Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

885 lines
21 KiB

  1. #ifndef COMPILED_FORDOS
  2. #include <nt.h>
  3. #include <ntrtl.h>
  4. #include <nturtl.h>
  5. #endif
  6. #include <windows.h>
  7. #include <dos.h>
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <stdio.h>
  11. #include <stddef.h>
  12. #include <stdlib.h>
  13. #include <stdarg.h>
  14. #include <limits.h>
  15. #include <malloc.h>
  16. #include <errno.h>
  17. #include <ctype.h>
  18. #include <signal.h>
  19. #include <string.h>
  20. #include <time.h>
  21. #include <io.h>
  22. #include <conio.h>
  23. #include <sys\types.h>
  24. #include <sys\stat.h>
  25. #ifdef COMPILED_FORDOS
  26. #define MAX_PATH 256
  27. #endif
  28. #define READ_BUFFER_SIZE (8192*sizeof(DWORD))
  29. #define CHECK_NAME "\\chkfile.chk"
  30. extern BOOL fUsage;
  31. extern BOOL fGenerateCheck;
  32. extern LPSTR RootOfTree;
  33. char RootBuffer[MAX_PATH];
  34. extern BOOL fVerbose;
  35. LPSTR CheckFileName;
  36. char OutputLine[512];
  37. DWORD ReadBuffer[READ_BUFFER_SIZE/sizeof(DWORD)];
  38. WORD
  39. CheckSum(
  40. DWORD ParitialSum,
  41. LPWORD Source,
  42. DWORD Length
  43. );
  44. typedef struct _FINDBUF {
  45. char reserved[21];
  46. char attrib;
  47. unsigned short wr_time;
  48. unsigned short wr_data;
  49. long size;
  50. char name[13];
  51. } FINDBUF, *PFINDBUF;
  52. DWORD
  53. PortFindFirstFile(
  54. LPSTR FindPattern,
  55. LPSTR FindName,
  56. LPBOOL IsDir,
  57. LPDWORD FindSize
  58. );
  59. BOOL
  60. PortFindNextFile(
  61. DWORD FindHandle,
  62. LPSTR FindName,
  63. LPBOOL IsDir,
  64. LPDWORD FindSize
  65. );
  66. VOID
  67. PortFindClose(
  68. DWORD FindHandle
  69. );
  70. VOID
  71. GenerateCheckFile( VOID );
  72. VOID
  73. ValidateCheckFile( VOID );
  74. BOOL
  75. ProcessParameters(
  76. int argc,
  77. LPSTR argv[]
  78. );
  79. FILE *GlobalCheckFile;
  80. FILE *
  81. OpenCheckFile( VOID );
  82. BOOL
  83. ComputeEntry(
  84. FILE *CheckFile,
  85. LPSTR FileName,
  86. DWORD FileLength
  87. );
  88. DWORD
  89. CheckSumFile(
  90. FILE *InputHandle,
  91. LPSTR PathName,
  92. DWORD FileLength,
  93. LPSTR FileName
  94. );
  95. BOOL fGenerateCheck = FALSE;
  96. LPSTR RootOfTree = "C:\\NT";
  97. BOOL fVerbose = FALSE;
  98. BOOL fUsage = FALSE;
  99. #ifndef COMPILED_FORDOS
  100. int ThreadCount;
  101. HANDLE ThreadListMutex;
  102. HANDLE ThreadListSemaphore;
  103. LIST_ENTRY WorkList;
  104. #define ITEM_TYPE_EXIT 1
  105. #define ITEM_TYPE_VALIDATE 2
  106. #define ITEM_TYPE_GENERATE 3
  107. typedef struct _WORK_ITEM {
  108. LIST_ENTRY ItemLinks;
  109. DWORD ItemType;
  110. PVOID Base;
  111. DWORD FileLength;
  112. DWORD ActualSum;
  113. char FileName[MAX_PATH];
  114. } WORK_ITEM, *PWORK_ITEM;
  115. PHANDLE ThreadHandles;
  116. CRITICAL_SECTION GenerateCrit;
  117. VOID
  118. WriteCheckSumEntry(
  119. FileName,
  120. Sum,
  121. FileLength
  122. )
  123. {
  124. char lOutputLine[512];
  125. int LineLength;
  126. LineLength = sprintf(lOutputLine,"%s %x %x\n",FileName,Sum,FileLength);
  127. if ( fVerbose ) {
  128. fprintf(stdout,"Id %d %s",GetCurrentThreadId(),lOutputLine);
  129. }
  130. EnterCriticalSection(&GenerateCrit);
  131. fwrite(lOutputLine,1,LineLength,GlobalCheckFile);
  132. LeaveCriticalSection(&GenerateCrit);
  133. }
  134. DWORD
  135. WorkerThread(
  136. LPVOID WhoCares
  137. )
  138. {
  139. HANDLE Objects[2];
  140. PWORK_ITEM Item;
  141. PLIST_ENTRY Entry;
  142. int FilesProcessed = 0;
  143. Objects[0] = ThreadListMutex;
  144. Objects[1] = ThreadListSemaphore;
  145. SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_ABOVE_NORMAL);
  146. //
  147. // Wait for and entry on the list, and exclusive ownership of the listhead
  148. //
  149. while(TRUE) {
  150. WaitForMultipleObjects(2,Objects,TRUE,INFINITE);
  151. Entry = RemoveHeadList(&WorkList);
  152. Item = (PWORK_ITEM)(CONTAINING_RECORD(Entry,WORK_ITEM,ItemLinks));
  153. ReleaseMutex(ThreadListMutex);
  154. switch ( Item->ItemType ) {
  155. case ITEM_TYPE_VALIDATE :
  156. FilesProcessed++;
  157. break;
  158. case ITEM_TYPE_GENERATE :
  159. FilesProcessed++;
  160. {
  161. DWORD Sum;
  162. Sum = (DWORD)CheckSum(0,Item->Base,(Item->FileLength+1) >> 1);
  163. UnmapViewOfFile(Item->Base);
  164. WriteCheckSumEntry(Item->FileName,Sum,Item->FileLength);
  165. break;
  166. }
  167. break;
  168. case ITEM_TYPE_EXIT :
  169. default:
  170. fprintf(stdout,"Id %d Processed %d Files\n",GetCurrentThreadId(),FilesProcessed);
  171. ExitThread(1);
  172. }
  173. LocalFree(Item);
  174. }
  175. return 0;
  176. }
  177. #endif
  178. INT __cdecl
  179. main( argc, argv )
  180. int argc;
  181. LPSTR argv[];
  182. {
  183. if (!ProcessParameters( argc, argv )) {
  184. fUsage = TRUE;
  185. }
  186. if (fUsage) {
  187. fprintf( stderr, "usage: checkrel [-?] display this message\n" );
  188. fprintf( stderr, " [-r pathname] supply release root\n" );
  189. fprintf( stderr, " [-v] verbose output\n" );
  190. fprintf( stderr, " [-g] generate check file\n" );
  191. fprintf( stderr, " [-t n] use n threads to process the data\n" );
  192. }
  193. else {
  194. //
  195. // if we are generating a check file, then generate it,
  196. // otherwise just check the release
  197. //
  198. if ( fGenerateCheck ) {
  199. GenerateCheckFile();
  200. #ifndef COMPILED_FORDOS
  201. if ( ThreadCount ) {
  202. int i;
  203. PWORK_ITEM Item;
  204. for(i=0;i<ThreadCount;i++){
  205. Item = LocalAlloc(LMEM_ZEROINIT,sizeof(*Item));
  206. Item->ItemType = ITEM_TYPE_EXIT;
  207. WaitForSingleObject(ThreadListMutex,INFINITE);
  208. InsertTailList(&WorkList,&Item->ItemLinks);
  209. ReleaseSemaphore(ThreadListSemaphore,1,NULL);
  210. ReleaseMutex(ThreadListMutex);
  211. }
  212. WaitForMultipleObjects(ThreadCount,ThreadHandles,TRUE,INFINITE);
  213. }
  214. #endif
  215. }
  216. else {
  217. ValidateCheckFile();
  218. }
  219. }
  220. return( 0 );
  221. }
  222. BOOL
  223. ProcessParameters(
  224. int argc,
  225. LPSTR argv[]
  226. )
  227. {
  228. char c, *p;
  229. BOOL Result;
  230. char *WhoCares;
  231. int i;
  232. Result = TRUE;
  233. while (--argc) {
  234. p = *++argv;
  235. if (*p == '/' || *p == '-') {
  236. while (c = *++p)
  237. switch (toupper( c )) {
  238. case '?':
  239. fUsage = TRUE;
  240. break;
  241. case 'R': {
  242. argc--;
  243. argv++;
  244. RootOfTree = *argv;
  245. GetFullPathName(RootOfTree,sizeof(RootBuffer),RootBuffer,&WhoCares);
  246. RootOfTree = RootBuffer;
  247. break;
  248. }
  249. case 'G':
  250. fGenerateCheck = TRUE;
  251. break;
  252. case 'V':
  253. fVerbose = TRUE;
  254. break;
  255. #ifndef COMPILED_FORDOS
  256. case 'T': {
  257. DWORD ThreadId;
  258. argc--;
  259. argv++;
  260. ThreadCount = atoi(*argv);
  261. InitializeListHead(&WorkList);
  262. ThreadListMutex = CreateMutex(NULL,FALSE,NULL);
  263. ThreadListSemaphore = CreateSemaphore(NULL,0,0x70000000,NULL);
  264. InitializeCriticalSection(&GenerateCrit);
  265. if ( ThreadListMutex && ThreadListSemaphore ) {
  266. ThreadHandles = LocalAlloc(LMEM_ZEROINIT,sizeof(HANDLE)*ThreadCount);
  267. if ( ThreadHandles ) {
  268. for(i=0;i<ThreadCount;i++) {
  269. ThreadHandles[i] = CreateThread(
  270. NULL,
  271. 0,
  272. WorkerThread,
  273. NULL,
  274. 0,
  275. &ThreadId
  276. );
  277. if ( !ThreadHandles[i] ) {
  278. ThreadCount = 0;
  279. break;
  280. }
  281. }
  282. }
  283. else {
  284. ThreadCount = 0;
  285. }
  286. }
  287. else {
  288. ThreadCount = 0;
  289. }
  290. break;
  291. }
  292. #endif
  293. default:
  294. fprintf( stderr, "checkrel: Invalid switch - /%c\n", c );
  295. Result = FALSE;
  296. break;
  297. }
  298. }
  299. }
  300. return( Result );
  301. }
  302. VOID
  303. WalkTree(
  304. FILE *CheckFile,
  305. LPSTR SubDir
  306. )
  307. {
  308. char NextSubDir[MAX_PATH];
  309. DWORD FindHandle;
  310. char FindPattern[MAX_PATH];
  311. char FindName[MAX_PATH];
  312. DWORD FindSize;
  313. BOOL b;
  314. BOOL IsDir;
  315. //
  316. // recursively walk the system searching all files
  317. //
  318. //
  319. // build the find pattern
  320. //
  321. strcpy(FindPattern,RootOfTree);
  322. if ( SubDir ) {
  323. strcat(FindPattern,"\\");
  324. strcat(FindPattern,SubDir);
  325. }
  326. strcat(FindPattern,"\\*.*");
  327. if ( fVerbose ) {
  328. fprintf(stdout,"WalkTree %s \n",FindPattern);
  329. }
  330. FindHandle = PortFindFirstFile(FindPattern,FindName,&IsDir,&FindSize);
  331. if ( FindHandle == -1 ) {
  332. fprintf(stderr,"checkrel: FindFirst(%s) failed %d\n",FindPattern,errno);
  333. return;
  334. }
  335. b = TRUE;
  336. while(b) {
  337. _strlwr(FindName);
  338. //
  339. // recurse if we are at a directory
  340. //
  341. if ( IsDir ) {
  342. //
  343. // if name is . or .., skip to findnext
  344. //
  345. if ( !strcmp(FindName,".") || !strcmp(FindName,"..") ) {
  346. goto findnext;
  347. }
  348. //
  349. // if name is w32x86 or w32mips, skip to findnext
  350. //
  351. if ( !strcmp(FindName,"w32mips") || !strcmp(FindName,"w32x86") ) {
  352. goto findnext;
  353. }
  354. NextSubDir[0] = '\0';
  355. if ( SubDir ) {
  356. strcat(NextSubDir,SubDir);
  357. strcat(NextSubDir,"\\");
  358. }
  359. strcat(NextSubDir,FindName);
  360. WalkTree(CheckFile,NextSubDir);
  361. }
  362. else {
  363. NextSubDir[0] = '\0';
  364. if ( SubDir ) {
  365. strcat(NextSubDir,SubDir);
  366. strcat(NextSubDir,"\\");
  367. }
  368. strcat(NextSubDir,FindName);
  369. b = ComputeEntry(CheckFile,NextSubDir,FindSize);
  370. }
  371. if ( !b ) {
  372. fprintf(stderr,"checkrel: ComputeEntry faild\n");
  373. return;
  374. }
  375. findnext:
  376. b = PortFindNextFile(FindHandle,FindName,&IsDir,&FindSize);
  377. }
  378. PortFindClose(FindHandle);
  379. }
  380. VOID
  381. GenerateCheckFile( VOID )
  382. {
  383. FILE *CheckFile;
  384. CheckFile = OpenCheckFile();
  385. if ( !CheckFile ) {
  386. return;
  387. }
  388. WalkTree(CheckFile,NULL);
  389. }
  390. VOID
  391. ValidateCheckFile( VOID )
  392. {
  393. FILE *CheckFile;
  394. DWORD CheckSize, CheckSum;
  395. char CheckName[MAX_PATH];
  396. DWORD n;
  397. LPSTR PathName;
  398. FILE *FileHandle;
  399. DWORD ActualSize;
  400. DWORD ActualSum;
  401. CheckFile = OpenCheckFile();
  402. if ( !CheckFile ) {
  403. return;
  404. }
  405. PathName = malloc(strlen(RootOfTree)+MAX_PATH+1);
  406. if ( !PathName ) {
  407. fprintf(stderr,"checkrel: memory allocation for %d bytes failed\n",strlen(RootOfTree)+MAX_PATH+1);
  408. return;
  409. }
  410. n = fscanf(CheckFile,"%s %x %x",CheckName,&CheckSum,&CheckSize);
  411. while ( n != EOF ) {
  412. if ( n != 3 ) {
  413. fprintf(stderr,"checkrel: error in format\n");
  414. return;
  415. }
  416. //
  417. // Now form the file and do the checksum compare
  418. //
  419. strcpy(PathName,RootOfTree);
  420. strcat(PathName,"\\");
  421. strcat(PathName,CheckName);
  422. FileHandle = fopen(PathName,"rb");
  423. if ( !FileHandle ) {
  424. fprintf(stderr,"checkrel: failed to open file %s %d\n",PathName,errno);
  425. }
  426. else {
  427. ActualSize = _filelength(_fileno(FileHandle));
  428. if ( ActualSize == 0xffffffff ) {
  429. fprintf(stderr,"checkrel: unable to get file size for file %s %d\n",PathName,errno);
  430. fclose(FileHandle);
  431. }
  432. else {
  433. if ( ActualSize != CheckSize ) {
  434. fprintf(stderr,"checkrel: FileSizes Differ for %s Actual %x vs. %x\n",PathName,ActualSize,CheckSize);
  435. }
  436. ActualSum = CheckSumFile(FileHandle,PathName,ActualSize,NULL);
  437. if ( ActualSum ) {
  438. if ( ActualSum != CheckSum ) {
  439. fprintf(stderr,"checkrel: CheckSums Differ for %s Actual %x vs. %x\n",PathName,ActualSum,CheckSum);
  440. }
  441. }
  442. if ( fVerbose ) {
  443. fprintf(stdout,"%s Sum(%x vs %x) Size(%x vs %x)\n",PathName,ActualSum,CheckSum,ActualSize,CheckSize);
  444. }
  445. }
  446. }
  447. n = fscanf(CheckFile,"%s %x %x",CheckName,&CheckSum,&CheckSize);
  448. }
  449. }
  450. FILE *
  451. OpenCheckFile()
  452. {
  453. FILE *CheckFile;
  454. GlobalCheckFile = (FILE *)-1;
  455. CheckFileName = malloc(strlen(RootOfTree)+strlen(CHECK_NAME)+1);
  456. if ( !CheckFileName ) {
  457. return (FILE *)-1;
  458. }
  459. strcpy(CheckFileName,RootOfTree);
  460. strcat(CheckFileName,CHECK_NAME);
  461. if ( fVerbose ) {
  462. fprintf(stdout,"checkrel: check name %s\n",CheckFileName);
  463. }
  464. CheckFile = fopen(CheckFileName,fGenerateCheck ? "wt" : "rt");
  465. if ( !CheckFile ) {
  466. fprintf(stderr,"checkrel: open %s failed %d\n",CheckFileName,errno);
  467. }
  468. GlobalCheckFile = CheckFile;
  469. return CheckFile;
  470. }
  471. BOOL
  472. ComputeEntry(
  473. FILE *CheckFile,
  474. LPSTR FileName,
  475. DWORD FileLength
  476. )
  477. {
  478. char PathName[MAX_PATH];
  479. DWORD CheckSum;
  480. DWORD LineLength;
  481. strcpy(PathName,RootOfTree);
  482. strcat(PathName,"\\");
  483. strcat(PathName,FileName);
  484. CheckSum = CheckSumFile(NULL,PathName,FileLength,FileName);
  485. if ( CheckSum ) {
  486. LineLength = sprintf(OutputLine,"%s %x %x\n",FileName,CheckSum,FileLength);
  487. if ( fVerbose ) {
  488. fprintf(stdout,"%s",OutputLine);
  489. }
  490. fwrite(OutputLine,1,LineLength,CheckFile);
  491. }
  492. return TRUE;
  493. }
  494. DWORD
  495. CheckSumFile(
  496. FILE *InputHandle,
  497. LPSTR PathName,
  498. DWORD FileLength,
  499. LPSTR FileName
  500. )
  501. {
  502. FILE *FileHandle;
  503. DWORD Sum;
  504. signed char *pb;
  505. LPDWORD pul;
  506. PVOID Base;
  507. DWORD cbread, cbreadtotal;
  508. if ( InputHandle ){
  509. FileHandle = InputHandle;
  510. }
  511. else {
  512. FileHandle = fopen(PathName,"rb");
  513. if ( !FileHandle ) {
  514. fprintf(stderr,"checkrel: failed to open file %s %d\n",PathName,errno);
  515. return 0;
  516. }
  517. #ifndef COMPILED_FORDOS
  518. if ( ThreadCount ) {
  519. PWORK_ITEM Item;
  520. HANDLE Win32FileHandle;
  521. HANDLE MappingHandle;
  522. //
  523. // Queue the generate request to a worker thread
  524. //
  525. Item = LocalAlloc(LMEM_ZEROINIT,sizeof(*Item));
  526. if (!Item) {
  527. goto bail;
  528. }
  529. Win32FileHandle = (HANDLE)_get_osfhandle(_fileno(FileHandle));
  530. MappingHandle = CreateFileMapping(
  531. Win32FileHandle,
  532. NULL,
  533. PAGE_READONLY,
  534. 0,
  535. 0,
  536. NULL
  537. );
  538. if ( !MappingHandle ) {
  539. fprintf(stderr,"checkrel: failed to map file %s %d\n",PathName,GetLastError());
  540. fclose(FileHandle);
  541. return 0;
  542. }
  543. Base = MapViewOfFile(
  544. MappingHandle,
  545. FILE_MAP_READ,
  546. 0,
  547. 0,
  548. 0
  549. );
  550. CloseHandle(MappingHandle);
  551. if ( !Base ) {
  552. fprintf(stderr,"checkrel: failed to map view of file %s %d\n",PathName,GetLastError());
  553. fclose(FileHandle);
  554. return 0;
  555. }
  556. fclose(FileHandle);
  557. Item->ItemType = ITEM_TYPE_GENERATE;
  558. Item->Base = Base;
  559. Item->FileLength = FileLength;
  560. strcpy(&Item->FileName[0],FileName);
  561. WaitForSingleObject(ThreadListMutex,INFINITE);
  562. InsertTailList(&WorkList,&Item->ItemLinks);
  563. ReleaseSemaphore(ThreadListSemaphore,1,NULL);
  564. ReleaseMutex(ThreadListMutex);
  565. return 0;
  566. }
  567. bail:;
  568. #endif
  569. }
  570. #ifdef COMPILED_FORDOS
  571. Base = ReadBuffer;
  572. //
  573. // Read the file in large blocks and compute the checksum.
  574. //
  575. Sum = 0;
  576. cbreadtotal = 0;
  577. while (cbread = fread(ReadBuffer, 1, READ_BUFFER_SIZE, FileHandle)) {
  578. cbreadtotal += cbread;
  579. pb = Base;
  580. //
  581. // Make sure the last byte of the buffer is zero in case a
  582. // partial buffer was read with an odd number of bytes in the
  583. // buffer.
  584. //
  585. ((PBYTE)ReadBuffer)[cbread] = 0;
  586. //
  587. // Compute the checksum using the same algorithm used for
  588. // tcp/ip network packets. This is a word checksum with all
  589. // carries folded back into the sum.
  590. //
  591. Sum = (DWORD)CheckSum(Sum, (LPWORD)ReadBuffer, (cbread + 1) >> 1);
  592. }
  593. #else
  594. {
  595. HANDLE Win32FileHandle;
  596. HANDLE MappingHandle;
  597. Win32FileHandle = (HANDLE)_get_osfhandle(_fileno(FileHandle));
  598. MappingHandle = CreateFileMapping(
  599. Win32FileHandle,
  600. NULL,
  601. PAGE_READONLY,
  602. 0,
  603. 0,
  604. NULL
  605. );
  606. if ( !MappingHandle ) {
  607. fprintf(stderr,"checkrel: failed to map file %s %d\n",PathName,GetLastError());
  608. fclose(FileHandle);
  609. return 0;
  610. }
  611. Base = MapViewOfFile(
  612. MappingHandle,
  613. FILE_MAP_READ,
  614. 0,
  615. 0,
  616. 0
  617. );
  618. CloseHandle(MappingHandle);
  619. if ( !Base ) {
  620. fprintf(stderr,"checkrel: failed to map view of file %s %d\n",PathName,GetLastError());
  621. fclose(FileHandle);
  622. return 0;
  623. }
  624. Sum = (DWORD)CheckSum(0,Base,(FileLength+1) >> 1);
  625. UnmapViewOfFile(Base);
  626. }
  627. #endif
  628. fclose(FileHandle);
  629. if (Sum == 0) {
  630. Sum = FileLength;
  631. }
  632. return(Sum);
  633. }
  634. #ifndef COMPILED_FORDOS
  635. DWORD
  636. PortFindFirstFile(
  637. LPSTR FindPattern,
  638. LPSTR FindName,
  639. LPBOOL IsDir,
  640. LPDWORD FindSize
  641. )
  642. {
  643. HANDLE FindHandle;
  644. WIN32_FIND_DATA FindFileData;
  645. FindHandle = FindFirstFile(FindPattern,&FindFileData);
  646. if ( FindHandle != INVALID_HANDLE_VALUE ) {
  647. strcpy(FindName,FindFileData.cFileName);
  648. *FindSize = FindFileData.nFileSizeLow;
  649. *IsDir = FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
  650. }
  651. return (DWORD)FindHandle;
  652. }
  653. BOOL
  654. PortFindNextFile(
  655. DWORD FindHandle,
  656. LPSTR FindName,
  657. LPBOOL IsDir,
  658. LPDWORD FindSize
  659. )
  660. {
  661. BOOL b;
  662. WIN32_FIND_DATA FindFileData;
  663. b = FindNextFile((HANDLE)FindHandle,&FindFileData);
  664. if ( b ) {
  665. strcpy(FindName,FindFileData.cFileName);
  666. *FindSize = FindFileData.nFileSizeLow;
  667. *IsDir = FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
  668. }
  669. return b;
  670. }
  671. VOID
  672. PortFindClose(
  673. DWORD FindHandle
  674. )
  675. {
  676. FindClose((HANDLE)FindHandle);
  677. }
  678. #else
  679. DWORD
  680. PortFindFirstFile(
  681. LPSTR FindPattern,
  682. LPSTR FindName,
  683. LPBOOL IsDir,
  684. LPDWORD FindSize
  685. )
  686. {
  687. struct find_t *FindHandle;
  688. int error;
  689. FindHandle = malloc(sizeof(*FindHandle));
  690. error = _dos_findfirst(FindPattern,_A_RDONLY | _A_NORMAL | _A_DIR, FindHandle);
  691. if ( error ) {
  692. free(FindHandle);
  693. return -1;
  694. }
  695. strcpy(FindName,FindHandle->name);
  696. *FindSize = FindHandle->size;
  697. *IsDir = FindHandle->attrib & 0x10;
  698. return (DWORD)FindHandle;
  699. }
  700. BOOL
  701. PortFindNextFile(
  702. DWORD FindHandle,
  703. LPSTR FindName,
  704. LPBOOL IsDir,
  705. LPDWORD FindSize
  706. )
  707. {
  708. BOOL b;
  709. int error;
  710. struct find_t *xxFindHandle;
  711. xxFindHandle = (struct find_t *)FindHandle;
  712. error = _dos_findnext( xxFindHandle );
  713. if ( error ) {
  714. return FALSE;
  715. }
  716. strcpy(FindName,xxFindHandle->name);
  717. *FindSize = xxFindHandle->size;
  718. *IsDir = FindHandle->attrib & 0x10;
  719. return TRUE;
  720. }
  721. VOID
  722. PortFindClose(
  723. DWORD FindHandle
  724. )
  725. {
  726. free((int *)FindHandle);
  727. }
  728. WORD
  729. CheckSum(
  730. DWORD PartialSum,
  731. LPWORD Source,
  732. DWORD Length
  733. )
  734. {
  735. register unsigned long t = PartialSum;
  736. register unsigned long r;
  737. while(Length--) {
  738. t += *Source++;
  739. }
  740. while (r = (t & 0xFFFF0000) {
  741. t &= 0x0000FFFF;
  742. t += (r >> 16);
  743. }
  744. return t;
  745. }
  746. #endif