`
phinecos
  • 浏览: 342077 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

《Windows系统编程》读后感(一)

 
阅读更多

读了前5章,感触最深的是作者在例子程序中对UNICODE的考虑,另外就是将windowsAPIUNIX进行对比,结合前段时间在看的《UNIX网络编程 2》,感觉对比性很强。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

印象最深刻的就是第5章的3个排序示例,将外部文件排序用内存来实现,堆,内存映射文件以及基准指针的使用让人大开眼见,不过比之《windows核心编程》还是有差距
#include"EvryThng.h"

#defineKEY_SIZE8

/**//*Structuredefinitionforatreenode.*/

typedef
struct_TreeNode{
struct_TreeNode*Left,*Right;
TCHARKey[KEY_SIZE];
LPTSTRpData;
}
TREENODE,*LPTNODE,**LPPTNODE;

#defineNODE_SIZEsizeof(TREENODE)
#defineNODE_HEAP_ISIZE0x8000
#defineDATA_HEAP_ISIZE0x8000
#defineMAX_DATA_LEN0x1000
#defineTKEY_SIZEKEY_SIZE*sizeof(TCHAR)

LPTNODEFillTree(HANDLE,HANDLE,HANDLE);
BOOLScan(LPTNODE);
intKeyCompare(LPCTSTR,LPCTSTR);iFile;/**//*foraccessinexceptionhandler*/
BOOLInsertTree(LPPTNODE,LPTNODE);

int_tmain(intargc,LPTSTRargv[])
{
HANDLEhIn,hNode
=NULL,hData=NULL;
LPTNODEpRoot;
BOOLNoPrint;
CHARErrorMessage[
256];
intiFirstFile=Options(argc,argv,_T("n"),&NoPrint,NULL);

if(argc<=iFirstFile)
ReportError(_T(
"Usage:sortBT[options]files"),1,FALSE);
/**//*Processallfilesonthecommandline.*/
for(iFile=iFirstFile;iFile<argc;iFile++)__try{
/**//*Opentheinputfile.*/
hIn
=CreateFile(argv[iFile],GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL);
if(hIn==INVALID_HANDLE_VALUE)
RaiseException(
0,0,0,NULL);
/**//*Allocatethetwoheaps.*/
__try
{
hNode
=HeapCreate(
HEAP_GENERATE_EXCEPTIONS
|HEAP_NO_SERIALIZE,NODE_HEAP_ISIZE,0);
hData
=HeapCreate(
HEAP_GENERATE_EXCEPTIONS
|HEAP_NO_SERIALIZE,DATA_HEAP_ISIZE,0);
/**//*Processtheinputfile,creatingthetree.*/
pRoot
=FillTree(hIn,hNode,hData);
/**//*DisplaythetreeinKeyorder.*/
if(!NoPrint){
_tprintf(_T(
"Sortedfile:%s/n"),argv[iFile]);
Scan(pRoot);
}

}
__finally{/**//*Heapsandfilehandlearealwaysclosed*/
/**//*Destroythetwoheapsanddatastructures.*/
if(hNode!=NULL)HeapDestroy(hNode);
if(hNode!=NULL)HeapDestroy(hData);
hNode
=NULL;hData=NULL;
if(hIn!=INVALID_HANDLE_VALUE)CloseHandle(hIn);
}

}
/**//*Endofmainfileprocessingloopandtryblock.*/

__except(EXCEPTION_EXECUTE_HANDLER)
{
_stprintf(ErrorMessage,_T(
"/n%s%s"),_T("sortBTerroronfile:"),argv[iFile]);
ReportError(ErrorMessage,
0,TRUE);
}

return0;
}


LPTNODEFillTree(HANDLEhIn,HANDLEhNode,HANDLEhData)

/**//*Scantheinputfile,creatingabinarysearchtreeinthe
hNodeheapwithdatapointerstothehDataheap.
*/

/**//*Usethecallingprogram'sexceptionhandler.*/
{
LPTNODEpRoot
=NULL,pNode;
DWORDnRead,i;
BOOLAtCR;
TCHARDataHold[MAX_DATA_LEN];
LPTSTRpString;
/**//*Opentheinputfile.*/
while(TRUE){
pNode
=HeapAlloc(hNode,HEAP_ZERO_MEMORY,NODE_SIZE);
pNode
->pData=NULL;
(pNode
->Left)=pNode->Right=NULL;
/**//*Readthekey.Returnifdone.*/
if(!ReadFile(hIn,pNode->Key,TKEY_SIZE,
&nRead,NULL)||nRead!=TKEY_SIZE)
/**//*Assumeendoffileonerror.*/
returnpRoot;/**//*Readthedatauntiltheendofline.*/
AtCR
=FALSE;/**//*LastcharacterwasnotaCR.*/

for(i=0;i<MAX_DATA_LEN;i++){
ReadFile(hIn,
&DataHold[i],TSIZE,&nRead,NULL);
if(AtCR&&DataHold[i]==LF)break;
AtCR
=(DataHold[i]==CR);
}

DataHold[i
-1]='/0';

/**//*DataHoldcontainsthedatawithoutthekey.
CombinetheKeyandtheData.
*/


pString
=HeapAlloc(hData,HEAP_ZERO_MEMORY,
(SIZE_T)(KEY_SIZE
+_tcslen(DataHold)+1)*TSIZE);
memcpy(pString,pNode
->Key,TKEY_SIZE);
pString[KEY_SIZE]
='/0';
_tcscat(pString,DataHold);
pNode
->pData=pString;
/**//*Insertthenewnodeintothesearchtree.*/
InsertTree(
&pRoot,pNode);

}
/**//*Endofwhile(TRUE)loop*/
returnNULL;/**//*Failure*/
}


BOOLInsertTree(LPPTNODEppRoot,LPTNODEpNode)

/**//*Insertthenewnode,pNode,intothebinarysearchtree,pRoot.*/
{
if(*ppRoot==NULL){
*ppRoot=pNode;
returnTRUE;
}

if(KeyCompare(pNode->Key,(*ppRoot)->Key)<0)
InsertTree(
&((*ppRoot)->Left),pNode);
else
InsertTree(
&((*ppRoot)->Right),pNode);
returnTRUE;
}


intKeyCompare(LPCTSTRpKey1,LPCTSTRpKey2)

/**//*Comparetworecordsofgenericcharacters.
Thekeypositionandlengthareglobalvariables.
*/

{
return_tcsncmp(pKey1,pKey2,KEY_SIZE);
}


staticBOOLScan(LPTNODEpNode)

/**//*Scanandprintthecontentsofabinarytree.*/
{
if(pNode==NULL)
returnTRUE;
Scan(pNode
->Left);
_tprintf(_T(
"%s/n"),pNode->pData);
Scan(pNode
->Right);
returnTRUE;
}


#include"EvryThng.h"

/**//*Definitionsoftherecordstructureinthesortfile.*/

#defineDATALEN56
#defineKEY_SIZE8

typedef
struct_RECORD{
TCHARKey[KEY_SIZE];
TCHARData[DATALEN];
}
RECORD;

#defineRECSIZEsizeof(RECORD)
typedefRECORD
*LPRECORD;
intKeyCompare(LPCTSTR,LPCTSTR);

int_tmain(intargc,LPTSTRargv[])
{
/**//*Thefileisthefirstargument.Sortingisdoneinplace.*/
/**//*Sortingisdonebyfilememorymapping.*/

HANDLEhFile
=INVALID_HANDLE_VALUE,hMap=NULL;
HANDLEhStdOut
=GetStdHandle(STD_OUTPUT_HANDLE);
LPVOIDpFile
=NULL;
DWORDFsLow,Result
=2;
TCHARTempFile[MAX_PATH];
LPTSTRpTFile;

BOOLNoPrint;
intiFirstFile;

iFirstFile
=Options(argc,argv,_T("n"),&NoPrint,NULL);

if(argc<=iFirstFile)
ReportError(_T(
"Usage:sortFL[options]files"),1,FALSE);

_try
{/**//*try-except*/
/**//*Copytheinputfiletoatempoutputfilethatwillbesorted.
Donotaltertheinputfile.
*/


_stprintf(TempFile,_T(
"%s%s"),argv[iFirstFile],_T(".tmp"));

CopyFile(argv[iFirstFile],TempFile,TRUE);

Result
=1;/**//*tmpfileisnewandshouldbedeleted.*/

/**//*Openthefile(usethetemporarycopy).*/

hFile
=CreateFile(TempFile,GENERIC_READ
|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);

if(hFile==INVALID_HANDLE_VALUE)
ReportException(_T(
"Fileopenfailed."),2);

/**//*Getfilesize.
Ifthefileistoolarge,catchthatwhenitismapped.
*/


FsLow
=GetFileSize(hFile,NULL);

if(FsLow==0){/**//*Thereisnothingtosort*/
CloseHandle(hFile);
return0;/**//*Youmightwanttoputoutaninformationalmessage*/
}

/**//*Createafilemappingobject.
Usethefilesizebutaddspaceforthenullcharacter.
*/


hMap
=CreateFileMapping(hFile,NULL,PAGE_READWRITE,0,FsLow+TSIZE,NULL);
if(hMap==NULL)
ReportException(_T(
"CreateFilemapfailed."),3);

pFile
=MapViewOfFile(hMap,FILE_MAP_ALL_ACCESS,0,0/**//*FsLow+TSIZE*/,0);
if(pFile==NULL)
ReportException(_T(
"MapViewfailed"),4);

/**//*Nowsortthefile.
PerformthesortwiththeClibrary-inmappedmemory.
*/


qsort(pFile,FsLow
/RECSIZE,RECSIZE,KeyCompare);

/**//*Printouttheentiresortedfile.Treatitasonesinglestring.*/

pTFile
=(LPTSTR)pFile;
pTFile[FsLow
/TSIZE]='/0';
if(!NoPrint)
PrintMsg(hStdOut,pFile);

/**//*Indicatesuccessfulcompletion.*/

Result
=0;
ReportException(EMPTY,
5);/**//*Forceanexceptiontocleanup.*/
return0;
}
/**//*Endofinnertry-except.*/

_except(EXCEPTION_EXECUTE_HANDLER)
{

/**//*Catchanyexceptionhere.Indicateanyerror.
Thisisthenormaltermination.Deletethetemporary
fileandFreealltheresources.
*/


if(pFile!=NULL)
UnmapViewOfFile(pFile);
if(hMap!=NULL)
CloseHandle(hMap);
if(hFile!=INVALID_HANDLE_VALUE)
CloseHandle(hFile);
if(Result!=2)
DeleteFile(TempFile);
returnResult;
}

}
/**//*Endof_tmain*/

/**//*CODEFROMHERETOENDISNOTINCLUDEDINTEXT.*/

intKeyCompare(LPCTSTRpKey1,LPCTSTRpKey2)

/**//*Comparetworecordsofgenericcharacters.
Thekeypositionandlengthareglobalvariables.
*/

{
return_tcsncmp(pKey1,pKey2,KEY_SIZE);
}



#include"EvryThng.h"

intKeyCompare(LPCTSTR,LPCTSTR);
DWORDCreateIndexFile(DWORD,LPCTSTR,LPTSTR);
DWORD_PTRKStart,KSize;
/**//*Keystartposition&size(TCHAR).*/
BOOLRevrs;

int_tmain(intargc,LPTSTRargv[])
{
/**//*Thefileisthefirstargument.Sortingisdoneinplace.*/
/**//*Sortingisdonebyfilememorymapping.*/

HANDLEhInFile,hInMap;
/**//*Inputfilehandles.*/
HANDLEhXFile,hXMap;
/**//*Indexfilehandles.*/
HANDLEhStdOut
=GetStdHandle(STD_OUTPUT_HANDLE);
BOOLIdxExists,NoPrint;
DWORDFsIn,FsX,RSize,iKey,nWrite,
*pSizes;
LPTSTRpInFile
=NULL;
LPBYTEpXFile
=NULL,pX;
TCHAR_based(pInFile)
*pIn;
TCHARIdxFlNam[MAX_PATH],ChNewLine
='/n';
intFlIdx;

/**//*Determinetheoptions.*/

FlIdx
=Options(argc,argv,_T("rIn"),&Revrs,&IdxExists,&NoPrint,NULL);
if(FlIdx>=argc)
ReportError(_T(
"Nofilenameoncommandline."),1,FALSE);

/**//*Step1:OpenandMaptheInputFile.*/

hInFile
=CreateFile(argv[FlIdx],GENERIC_READ|GENERIC_WRITE,
0,NULL,OPEN_EXISTING,0,NULL);
if(hInFile==INVALID_HANDLE_VALUE)
ReportError(_T(
"Failedtoopeninputfile."),2,TRUE);

/**//*Createafilemappingobject.Usethefilesize.*/

hInMap
=CreateFileMapping(hInFile,NULL,PAGE_READWRITE,0,0,NULL);
if(hInMap==NULL)
ReportError(_T(
"Failedtocreateinputfilemapping."),3,TRUE);
pInFile
=MapViewOfFile(hInMap,FILE_MAP_ALL_ACCESS,0,0,0);
if(pInFile==NULL)
ReportError(_T(
"Failedtomapinputfile."),4,TRUE);

/**//*Getthefilesize.
Asthemappingsucceeded,thefilesizeislessthan2GB.
*/


FsIn
=GetFileSize(hInFile,NULL);

/**//*Createtheindexfilename.*/

_stprintf(IdxFlNam,_T(
"%s%s"),argv[FlIdx],_T(".idx"));

/**//*Steps2and3,ifnecessary.*/

if(!IdxExists)
RSize
=CreateIndexFile(FsIn,IdxFlNam,pInFile);

/**//*Step4.Maptheindexfile.*/

hXFile
=CreateFile(IdxFlNam,GENERIC_READ|GENERIC_WRITE,
0,NULL,OPEN_EXISTING,0,NULL);
if(hXFile==INVALID_HANDLE_VALUE)
ReportError(_T(
"Failedtoopenexistingindexfile."),5,TRUE);

/**//*Createafilemappingobject.Usethefilesize.*/

hXMap
=CreateFileMapping(hXFile,NULL,PAGE_READWRITE,0,0,NULL);
if(hXMap==NULL)
ReportError(_T(
"Failedtocreateindexfilemapping."),6,TRUE);
pXFile
=MapViewOfFile(hXMap,FILE_MAP_ALL_ACCESS,0,0,0);
if(pXFile==NULL)
ReportError(_T(
"Failedtomapindexfile."),7,TRUE);
FsX
=GetFileSize(hXFile,NULL);

/**//*Getthekeysize/keystartandadjustthefilesizeforthe
KeySize/KeyStartfields.Computetherecordsizefromthekeysize.
*/


pSizes
=(LPDWORD)pXFile;KSize=*pSizes;
KStart
=*(pSizes+1);
FsX
-=2*sizeof(DWORD);

/**//*Step5.Sorttheindexfileusingqsort.*/

if(!IdxExists)
qsort(pXFile
+2*sizeof(DWORD),FsX/RSize,RSize,KeyCompare);

/**//*Step6.Outputtheinputfileinsortedorder.*/

/**//*Pointtotheaddressoftheinputfilestring.
StartintheInputfile.
*/


pX
=pXFile+2*sizeof(DWORD)+RSize-sizeof(LPTSTR);

if(!NoPrint)
for(iKey=0;iKey<FsX/RSize;iKey++){
WriteFile(hStdOut,
&ChNewLine,TSIZE,&nWrite,NULL);

/**//*ThecastonpXisimportant,asitisapointertoa
byteandweneedthefourbytesofabasedpointer.
*/

pIn
=(TCHAR_based(pInFile)*)*(DWORD_PTR*)pX;

while((*pIn!=CR||*(pIn+1)!=LF)&&(SIZE_T)pIn<(SIZE_T)FsIn){
WriteFile(hStdOut,pIn,TSIZE,
&nWrite,NULL);
pIn
++;
}

pX
+=RSize;
}


/**//*Done.Freeallthehandlesandmaps.*/

UnmapViewOfFile(pInFile);
CloseHandle(hInMap);
CloseHandle(hInFile);
UnmapViewOfFile(pXFile);
CloseHandle(hXMap);
CloseHandle(hXFile);
return0;
}


DWORDCreateIndexFile(DWORDFsIn,LPCTSTRIdxFlNam,LPTSTRpInFile)

/**//*PerformSteps2-3asdefinedinprogramdescription.*/
/**//*Thisstepwillbeskippediftheoptionsspecifyuseofanexistingindexfile.*/
{
HANDLEhXFile;
TCHAR_based(pInFile)
*pInScan=0;
DWORDnWrite;

/**//*Step2a:Createanindexfile.
Donotmapityetasitslengthisnotknown.
*/


hXFile
=CreateFile(IdxFlNam,GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ,NULL,CREATE_ALWAYS,
0,NULL);
if(hXFile==INVALID_HANDLE_VALUE)
ReportError(_T(
"Failuretocreateindexfile."),8,TRUE);

/**//*Step2b:Getthefirstkeyanddeterminekeysizeandstart.*/

KStart
=(DWORD_PTR)pInScan;
/**//*Computedstartofkeyfield.*/
while(*pInScan!=''&&*pInScan!='/t')pInScan++;
/**//*Computedendofkeyfield*/

KSize
=((DWORD_PTR)pInScan-KStart)/TSIZE;

/**//*Computedkeyfieldsizeincharacters.*/

/**//*Step2c.Step3.Scanthecompletefile,writingkeys
andrecordpointerstothekeyfile.
*/

/**//*TheeightbytescontaintheKeySize/KeyStart.
Thisisnecessarysothatwecanre-usetheindexfile.
*/


WriteFile(hXFile,
&KSize,sizeof(DWORD),&nWrite,NULL);
WriteFile(hXFile,
&KStart,sizeof(DWORD),&nWrite,NULL);
pInScan
=/**//*(TCHAR_based(pInFile)*)*/0;
while((DWORD_PTR)pInScan<FsIn){
WriteFile(hXFile,pInScan
+KStart,KSize*TSIZE,&nWrite,NULL);
WriteFile(hXFile,
&pInScan,sizeof(LPTSTR),&nWrite,NULL);
while((DWORD)(DWORD_PTR)pInScan<FsIn&&((*pInScan!=CR)
||(*(pInScan+1)!=LF))){
pInScan
++;/**//*Skiptoendofline.*/
}

pInScan
+=2;/**//*SkippastCR,LF.*/
}

CloseHandle(hXFile);
/**//*Sizeofanindividualrecord.*/
returnKSize*TSIZE+sizeof(LPTSTR);
}


intKeyCompare(LPCTSTRpKey1,LPCTSTRpKey2)

/**//*Comparetworecordsofgenericcharacters.
Thekeypositionandlengthareglobalvariables.
*/

{
DWORDi;
TCHARt1,t2;
intResult=0;
for(i=0;i<KSize&&Result==0;i++){
t1
=*pKey1;
t2
=*pKey2;
if(t1<t2)
Result
=-1;
if(t1>t2)
Result
=+1;
pKey1
++;
pKey2
++;
}

returnRevrs?-Result:Result;
}

分享到:
评论

相关推荐

    寒江独钓《Windows内核安全编程》

    当一个经验并不丰富的小程序员面对庞大复杂的并且不开源的Windows框架时,那是一种怎样的无助感啊!谭文是我比较钦佩的程序员之一,他对技术非常执着,并且精力充沛。内核程序的知识涉及面非常广,不同类别的内核...

    VC++6.0核心编程源码.rar

    从系统内部来讲,当一个Windows函数检测到一个错误时,它会使用一个称为线程本地存储器的机制,将相应的错误代码号码与调用的线程关联起来。(“线程本地存储器”将在第21章中介绍)。这将使线程能够互相独立地运行...

    XML高级编程

    Web站点的开发者能够学到把自己的站点提高一个层次的技术,而编程者和软件系统程序员能够学到XML如何和他们的系统相配合,以及如何使用它来解决应用程序集成中的问题。 XML应用程序天生就具备分布性而且通常是面向...

    自己动手写操作系统(含源代码).part2

    上篇基本上是第一版的修订,只是做了一个调整,那便是在兼顾 Windows和Linux两方面用户的基础上,默认在Linux下建立开发环境来编写我们的操作系统。至于这样做的原因,在本书第 2章有比较详细的说明。当然,开发环境...

    自己动手写操作系统(含源代码).part1

    上篇基本上是第一版的修订,只是做了一个调整,那便是在兼顾 Windows和Linux两方面用户的基础上,默认在Linux下建立开发环境来编写我们的操作系统。至于这样做的原因,在本书第 2章有比较详细的说明。当然,开发环境...

    Oracle SQL高级编程(资深Oracle专家力作,OakTable团队推荐)--随书源代码

    从1996年开始使用Oracle,在应用开发、大型系统实现以及性能评估方面具有丰富的经验。她是OakTable的成员,同时是Expert Oracle Practices (2010年 Apress出版)一书的合著者。  RIYAJ SHAMSUDEEN 专注于性能/...

    PERL语言编程

    从另外一个角度来看,Perl 还可以从另外一个方向运转:在 Windows 上工作的 web 设计者通常会非常开心地发现他们的 Perl 程序可以不加修改地在 Unix 服务器上跑。 &lt;br/&gt;尽管 Perl 在系统程序员和 web 设计师...

    新版Android开发教程.rar

    Android 是一个专门针对移动设备的软件集,它包括一个操作系统,中间件和一些重要的应用程序。 Beta 版 的 Android SDK 提供了在 Android 平台上使用 JaVa 语言进行 Android 应用开发必须的工具和 API 接口。 特性 ...

    IEEE_电气工程师_数字信号处理_FORTRAN程序库-3

    f2c是一个开源的fortran到c的转换软件,如果不想混合编程的话,可以用它。 ============================================= 这是1976年IEEE组织编辑出版的《IEEE电气工程师 数字信号处理 FORTRAN程序库》的FORTRAN...

    IEEE_电气工程师_数字信号处理_FORTRAN程序库-2

    f2c是一个开源的fortran到c的转换软件,如果不想混合编程的话,可以用它。 ============================================= 这是1976年IEEE组织编辑出版的《IEEE电气工程师 数字信号处理 FORTRAN程序库》的FORTRAN...

    asp.net知识库

    应用系统的多语言支持 (一) 应用系统的多语言支持 (二) 自动返回上次请求页面(小技巧) ASP.NET 2.0 控件 ASP.NET 2.0 验证控件新的功能 DataGridView中如何在textbox列中限制输入。 ASP.NET 2.0构建动态导航的...

    IIS6.0 IIS,互联网信息服务

     一、IIS的添加 请进入“控制面板”,依次选“添加/删除程序→添加/删除Windows组件”,将“Internet信息服务(IIS)”前的小钩去掉(如有),重新勾选中后按提示操作即可完成IIS组件的添加。用这种方法添加的IIS...

    C++MFC教程

    Windows系统是一个消息驱动的OS,什么是消息呢?我很难说得清楚,也很难下一个定义(谁在嘘我),我下面从不同的几个方面讲解一下,希望大家看了后有一点了解。 1、消息的组成:一个消息由一个消息名称(UINT),和...

    基于AT89S52 单片的频率计

    程通俗的讲就是编MCU 从系统目标系统中移出在结合系统中一系列内部的硬 件资源可实的远程编程。 ISP 功能的优点: ①在系统中编程不需要移出微控制器。 ②不需并行编程器仅需用P15,P16 和P17,这三个IO 仅仅是下载...

    -Q版缓冲区溢出教程

    没有复杂的、Windows系统结构的定义,阅读起来不会有混混欲睡的乏味感! 书里面,有的是活波生动的语言;有的是的美好纯真的校园生活;有的是可遇不可求的经验;有的是直截了当、图文并茂的手把手操作;有的是...

    Reversing:逆向工程揭密

    第一类是从已知软件系统的完整代码出发,生成对应系统的结构以及相关设计原理和算法思想的文档。实际上,学习和研究别人的源代码就属于此类。Chikofsky在本书的序中特别指出:阅读别人写的代码或者自己以前写的代码...

Global site tag (gtag.js) - Google Analytics