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.

762 lines
21 KiB

  1. #define PUBLIC
  2. #define PRIVATE
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <memory.h>
  6. #include <string.h>
  7. #include <windows.h>
  8. #include <conio.h>
  9. #include <share.h>
  10. #include <dos.h>
  11. #include "cscapi.h"
  12. #pragma pack (1)
  13. #if defined(BITCOPY)
  14. #include "csc_bmpd.h"
  15. #endif // defined(BITCOPY)
  16. #define MAX_PQ_PER_PAGE 10
  17. #define MAX_SHARES_PER_PAGE 6
  18. #define MAX_FILE_PER_PAGE 4
  19. #define MAX_INODES_PER_PAGE 15
  20. #define _wtoupper(x) ( ( ((x)>='a')&&((x)<='z') ) ? ((x)-'a'+'A'):(x))
  21. #define _mytoupper(x) ( ( ((x)>='a')&&((x)<='z') ) ? ((x)-'a'+'A'):(x))
  22. #ifndef CSC_ON_NT
  23. typedef void *CSCHFILE;
  24. typedef void *CSC_ENUMCOOKIE;
  25. #define UCHAR unsigned char
  26. #define USHORT unsigned short
  27. #define ULONG unsigned long
  28. #define CHAR char
  29. #define wchar_t unsigned short
  30. #define LPTSTR LPSTR
  31. #define CONST const
  32. #define LPWIN32_FIND_DATAW LPVOID
  33. typedef struct tagSTOREDATA
  34. {
  35. ULONG ulSize; // Max shadow data size
  36. ULONG ucntDirs; // Current count of dirs
  37. ULONG ucntFiles; // Current count of files
  38. }
  39. STOREDATA, *LPSTOREDATA;
  40. typedef LPVOID LPFIND32;
  41. #else
  42. typedef PVOID CSCHFILE;
  43. #include "shdcom.h"
  44. #include "cscsec.h"
  45. #endif //CSC_ON_NT
  46. #define ESC 0x1b
  47. typedef unsigned long ulong;
  48. typedef unsigned short ushort;
  49. typedef LPSTR LPPATH;
  50. #include "record.h"
  51. #define InodeFromRec(ulRec, fFile) ((ulRec+ULID_FIRST_USER_DIR-1) | ((fFile)?0x80000000:0))
  52. #define RecFromInode(hShadow) ((hShadow & 0x7fffffff) - (ULID_FIRST_USER_DIR-1))
  53. char rgch[256], rgPrint[1024], rgchPar[256];
  54. char szShadow[] = "\\WINDOWS\\CSC";
  55. char szBackslash[] = "\\";
  56. char szDbDir[256]; // shadow database
  57. char szName[MAX_PATH]; // working buffer
  58. int DispFunc(char *);
  59. void DisplayShares(char *);
  60. void DisplayInodes(void);
  61. void DisplayPriorityQ(void);
  62. void DisplayFile(unsigned long ulid, char *);
  63. int PUBLIC HexToA(ulong, LPSTR, int);
  64. void PRIVATE FormNameStringDB(
  65. LPSTR lpdbID,
  66. ulong ulidFile,
  67. LPSTR lpName
  68. );
  69. BOOL
  70. FindAncestor(
  71. ulong ulid,
  72. ulong *lpulidDir
  73. );
  74. void
  75. printwidestring(
  76. USHORT *lpwString,
  77. unsigned long cntChars
  78. );
  79. int RoughCompareWideStringWithAnsiString(
  80. LPSTR lpSrcString,
  81. USHORT *lpwDstString,
  82. int cntMax
  83. );
  84. int _cdecl main(int argc, char *argv[], char *envp[])
  85. {
  86. BOOL fRet;
  87. DWORD junk;
  88. unsigned uAttr;
  89. int iRet = -1;
  90. if (argc==1)
  91. {
  92. fRet = CSCGetSpaceUsage(
  93. szDbDir,
  94. sizeof(szDbDir),
  95. &junk,
  96. &junk,
  97. &junk,
  98. &junk,
  99. &junk,
  100. &junk);
  101. if (fRet == FALSE)
  102. strcpy(szDbDir, szShadow);
  103. }
  104. else
  105. {
  106. memset(szDbDir, 0, sizeof(szDbDir));
  107. strncpy(szDbDir, argv[1], sizeof(szDbDir)-1);
  108. }
  109. #ifdef CSC_ON_NT
  110. if((uAttr = GetFileAttributes(szDbDir)) == 0xffffffff)
  111. #else
  112. if(_dos_getfileattr(szDbDir, &uAttr))
  113. #endif //CSC_ON_NT
  114. {
  115. printf("Error accessing directory %s \r\n", szDbDir);
  116. }
  117. else if (!(uAttr & _A_SUBDIR))
  118. {
  119. printf("%s is not a directory\r\n", szDbDir);
  120. }
  121. else
  122. {
  123. do
  124. {
  125. memset(rgch, 0, sizeof(rgch));
  126. printf("\r\n");
  127. printf("Shares [s [name]], ");
  128. printf("PriQ [q], ");
  129. printf("File [f inode# [name]], ");
  130. printf("Exit [x], ");
  131. printf("Enter:");
  132. if (!gets(rgch))
  133. break;
  134. printf("\r\n");
  135. if (!DispFunc(rgch))
  136. break;
  137. }
  138. while (1);
  139. iRet = 0;
  140. }
  141. return (iRet);
  142. }
  143. int DispFunc(
  144. char *lpBuff
  145. )
  146. {
  147. char ch;
  148. unsigned long ulid;
  149. int cnt;
  150. cnt = sscanf(lpBuff, "%c", &ch);
  151. if (!cnt)
  152. return 0;
  153. switch (ch)
  154. {
  155. // Display shares database
  156. case 's':
  157. case 'S':
  158. cnt = sscanf(lpBuff, "%c%s", &ch, rgchPar);
  159. DisplayShares((cnt==2)?rgchPar:NULL);
  160. break;
  161. // display priority Q database
  162. case 'q':
  163. case 'Q':
  164. DisplayPriorityQ();
  165. break;
  166. case 'f':
  167. case 'F':
  168. cnt = sscanf(lpBuff, "%c%lx%s", &ch, &ulid, rgchPar);
  169. if (cnt==2)
  170. {
  171. // display Inode file
  172. DisplayFile(ulid, NULL);
  173. }
  174. else if (cnt==3)
  175. {
  176. printf("Looking for %s in %x \r\n", rgchPar, ulid);
  177. // display Inode file
  178. DisplayFile(ulid, rgchPar);
  179. }
  180. break;
  181. case 'x':
  182. case 'X':
  183. return 0;
  184. }
  185. return 1;
  186. }
  187. void
  188. DisplaySecurityContext(
  189. char *pSecurityDescriptor,
  190. LPRECORDMANAGER_SECURITY_CONTEXT pSecurityContext)
  191. {
  192. #ifdef CSC_ON_NT
  193. PCACHED_SECURITY_INFORMATION pCachedSecurityInformation;
  194. ULONG i;
  195. pCachedSecurityInformation = (PCACHED_SECURITY_INFORMATION)pSecurityContext;
  196. if (pSecurityDescriptor != NULL) {
  197. printf("\n%s ",pSecurityDescriptor);
  198. }
  199. printf("SECURITY CONTEXT:\n");
  200. for (i = 0; i < MAXIMUM_NUMBER_OF_USERS; i++) {
  201. CSC_SID_INDEX SidIndex;
  202. SidIndex = pCachedSecurityInformation->AccessRights[i].SidIndex;
  203. switch (SidIndex) {
  204. case CSC_INVALID_SID_INDEX:
  205. break;
  206. default:
  207. {
  208. if (SidIndex == CSC_GUEST_SID_INDEX) {
  209. printf("\tGUEST: ");
  210. } else {
  211. printf("\t%lx: ",SidIndex);
  212. }
  213. printf(
  214. "Rights: %lx\t\n",
  215. pCachedSecurityInformation->AccessRights[i].MaximalRights);
  216. }
  217. }
  218. }
  219. #endif
  220. }
  221. void
  222. DisplaySecurityContext2(
  223. char *pSecurityDescriptor,
  224. LPRECORDMANAGER_SECURITY_CONTEXT pSecurityContext)
  225. {
  226. PCACHED_SECURITY_INFORMATION pCachedSecurityInformation;
  227. BOOL fGotOne = FALSE;
  228. ULONG i;
  229. pCachedSecurityInformation = (PCACHED_SECURITY_INFORMATION)pSecurityContext;
  230. for (i = 0; i < MAXIMUM_NUMBER_OF_USERS; i++) {
  231. CSC_SID_INDEX SidIndex;
  232. SidIndex = pCachedSecurityInformation->AccessRights[i].SidIndex;
  233. if (SidIndex != CSC_INVALID_SID_INDEX) {
  234. fGotOne = TRUE;
  235. break;
  236. }
  237. }
  238. if (fGotOne == FALSE)
  239. return;
  240. printf("%s Security: ",pSecurityDescriptor);
  241. for (i = 0; i < MAXIMUM_NUMBER_OF_USERS; i++) {
  242. CSC_SID_INDEX SidIndex;
  243. SidIndex = pCachedSecurityInformation->AccessRights[i].SidIndex;
  244. if (SidIndex == CSC_INVALID_SID_INDEX) {
  245. continue;
  246. }else if (SidIndex == CSC_GUEST_SID_INDEX) {
  247. printf("(G:0x%x)",
  248. pCachedSecurityInformation->AccessRights[i].MaximalRights);
  249. } else {
  250. printf("(0x%x:0x%x)",
  251. SidIndex,
  252. pCachedSecurityInformation->AccessRights[i].MaximalRights);
  253. }
  254. }
  255. printf("\r\n");
  256. }
  257. void DisplayShares(
  258. char *lpszShareName
  259. )
  260. {
  261. FILE *fp= (FILE *)NULL;
  262. SHAREHEADER sSH;
  263. SHAREREC sSR;
  264. unsigned long ulrec=1L;
  265. int count=0;
  266. FormNameStringDB(szDbDir, ULID_SHARE, szName);
  267. if (fp = _fsopen(szName, "rb", _SH_DENYNO))
  268. {
  269. if (fread(&sSH, sizeof(SHAREHEADER), 1, fp) != 1)
  270. {
  271. printf("Error reading server header \r\n");
  272. goto bailout;
  273. }
  274. printf("Header: Flags=%x Version=%lx Records=%ld Size=%d \r\n",
  275. sSH.uFlags, sSH.ulVersion, sSH.ulRecords, sSH.uRecSize);
  276. printf("Store: Max=%ld Current=%ld \r\n", sSH.sMax.ulSize, sSH.sCur.ulSize);
  277. printf("store: files=%ld directories=%ld \r\n\r\n", sSH.sCur.ucntFiles, sSH.sCur.ucntDirs);
  278. while (fread(&sSR, sizeof(SHAREREC), 1, fp)==1)
  279. {
  280. if (count == MAX_SHARES_PER_PAGE) {
  281. printf("\r\n--- Press any key to continue; ESC to cancel ---\r\n");
  282. if(_getch()==ESC) {
  283. break;
  284. }
  285. count = 0;
  286. }
  287. if (sSR.uchType == (unsigned char)REC_DATA) {
  288. if (lpszShareName) {
  289. if (RoughCompareWideStringWithAnsiString(
  290. lpszShareName,
  291. sSR.rgPath,
  292. sizeof(sSR.rgPath)/sizeof(USHORT)-1)
  293. ) {
  294. continue;
  295. }
  296. }
  297. printwidestring(sSR.rgPath, sizeof(sSR.rgPath)/sizeof(USHORT));
  298. printf("\r\n");
  299. printf( " Share=0x%x Root=0x%x Stat=0x%x RootStat=0x%x "
  300. "HntFlgs=0x%x HntPri=0x%x Attr=0x%x\r\n",
  301. ulrec++,
  302. sSR.ulidShadow,
  303. sSR.uStatus,
  304. (unsigned)(sSR.usRootStatus),
  305. (unsigned)(sSR.uchHintFlags),
  306. (unsigned)(sSR.uchHintPri),
  307. sSR.dwFileAttrib);
  308. DisplaySecurityContext2(" ShareLevel",&sSR.sShareSecurity);
  309. DisplaySecurityContext2(" Root ",&sSR.sRootSecurity);
  310. printf("\r\n");
  311. if (lpszShareName) {
  312. printf("\r\n--- Press any key to continue search; ESC to cancel ---\r\n");
  313. if(_getch()==ESC) {
  314. break;
  315. }
  316. } else {
  317. ++count;
  318. }
  319. }
  320. }
  321. }
  322. bailout:
  323. if (fp)
  324. fclose(fp);
  325. }
  326. void DisplayPriorityQ
  327. (
  328. void
  329. )
  330. {
  331. FILE *fp= (FILE *)NULL;
  332. QHEADER sQH;
  333. QREC sQR;
  334. unsigned long ulRec=1;
  335. int count = 0;
  336. FormNameStringDB(szDbDir, ULID_PQ, szName);
  337. if (fp = _fsopen(szName, "rb", _SH_DENYNO)) {
  338. if (fread(&sQH, sizeof(QHEADER), 1, fp) != 1) {
  339. printf("Error reading PQ header \r\n");
  340. goto bailout;
  341. }
  342. printf("Header: Flags=%x Version=%lx Records=%ld Size=%d head=%ld tail=%ld\r\n",
  343. sQH.uchFlags,
  344. sQH.ulVersion,
  345. sQH.ulRecords,
  346. sQH.uRecSize,
  347. sQH.ulrecHead,
  348. sQH.ulrecTail);
  349. printf("\r\n");
  350. printf(
  351. " REC SHARE DIR SHADOW STATUS PRI HINTFLGS HINTPRI PREV NEXT DIRENT\r\n");
  352. for (ulRec = sQH.ulrecHead; ulRec;) {
  353. if (count == MAX_PQ_PER_PAGE) {
  354. printf("\r\n--- Press any key to continue; ESC to cancel ---\r\n");
  355. if(_getch()==ESC) {
  356. break;
  357. }
  358. count = 0;
  359. printf(
  360. " REC SHARE DIR SHADOW STATUS PRI HINTFLGS HINTPRI PREV NEXT DIRENT\r\n");
  361. }
  362. fseek(fp, ((ulRec-1) * sizeof(QREC))+sizeof(QHEADER), SEEK_SET);
  363. if (fread(&sQR, sizeof(QREC), 1, fp)!=1)
  364. break;
  365. printf("%5d %5x %8x %8x %8x %4d %8x %7d %5d %5d %6d\r\n",
  366. ulRec,
  367. sQR.ulidShare,
  368. sQR.ulidDir,
  369. sQR.ulidShadow,
  370. sQR.usStatus,
  371. (unsigned)(sQR.uchRefPri),
  372. (unsigned)(sQR.uchHintFlags),
  373. (unsigned)(sQR.uchHintPri),
  374. sQR.ulrecPrev,
  375. sQR.ulrecNext,
  376. sQR.ulrecDirEntry);
  377. ++count;
  378. ulRec = sQR.ulrecNext;
  379. }
  380. }
  381. bailout:
  382. if (fp)
  383. fclose(fp);
  384. }
  385. void DisplayFile(
  386. unsigned long ulid,
  387. char *lpszName
  388. )
  389. {
  390. FILE *fp= (FILE *)NULL;
  391. FILEHEADER sFH;
  392. FILEREC sFR;
  393. int fLfn=0;
  394. unsigned long ulidDir=ulid;
  395. int fPrintOvf = 0, count=0;
  396. #if defined(BITCOPY)
  397. char strmPath[MAX_PATH];
  398. LPCSC_BITMAP_DB lpbitmap = NULL;
  399. #endif // defined(BITCOPY)
  400. if (IsLeaf(ulid)) {
  401. if (!FindAncestor(ulid, &ulidDir))
  402. return;
  403. }
  404. FormNameStringDB(szDbDir, ulidDir, szName);
  405. if (fp = _fsopen(szName, "rb", _SH_DENYNO)) {
  406. if (fread(&sFH, sizeof(FILEHEADER), 1, fp) != 1) {
  407. printf("Error reading file header \r\n");
  408. goto bailout;
  409. }
  410. if (ulid == ulidDir) {
  411. printf("Header: Flags=%x Version=%lx Records=%ld Size=%d\r\n",
  412. sFH.uchFlags, sFH.ulVersion, sFH.ulRecords, sFH.uRecSize);
  413. printf("Header: bytes=%ld entries=%d Share=%ld Dir=%lx\r\n",
  414. sFH.ulsizeShadow, sFH.ucShadows, sFH.ulidShare, sFH.ulidDir);
  415. printf ("\r\n");
  416. fPrintOvf = 1;
  417. }
  418. while (fread(&sFR, sizeof(FILEREC), 1, fp)==1) {
  419. if (count == MAX_FILE_PER_PAGE) {
  420. printf("--- Press any key to continue; ESC to cancel ---\r\n");
  421. if(_getch()==ESC) {
  422. break;
  423. }
  424. count = 0;
  425. }
  426. if (sFR.uchType != (unsigned char)REC_OVERFLOW) {
  427. if (fLfn) {
  428. if (ulidDir != ulid)
  429. break;
  430. }
  431. fLfn = 0;
  432. }
  433. if (sFR.uchType==(unsigned char)REC_DATA) {
  434. if (ulidDir != ulid) {
  435. if (ulid != sFR.ulidShadow)
  436. continue;
  437. }
  438. if (lpszName) {
  439. if (RoughCompareWideStringWithAnsiString(
  440. lpszName,
  441. sFR.rgwName,
  442. sizeof(sFR.rgw83Name)/sizeof(USHORT)-1)
  443. ) {
  444. continue;
  445. }
  446. }
  447. fPrintOvf = 1;
  448. printwidestring(sFR.rgw83Name, sizeof(sFR.rgw83Name)/sizeof(USHORT));
  449. printf(" (0x%x)\r\n", sFR.ulidShadow);
  450. printf(" Type=%c Flags=0x%x status=0x%x size=%ld attrib=0x%lx\r\n",
  451. sFR.uchType,
  452. (unsigned)sFR.uchFlags,
  453. sFR.uStatus,
  454. sFR.ulFileSize,
  455. sFR.dwFileAttrib);
  456. printf(" PinFlags=0x%x PinCount=%d RefPri=%d OriginalInode=0x%0x\r\n",
  457. (unsigned)(sFR.uchHintFlags),
  458. (int)(sFR.uchHintPri),
  459. (int)(sFR.uchRefPri),
  460. sFR.ulidShadowOrg);
  461. printf(" time: hi=%x lo=%x orgtime: hi=%x lo=%x\r\n",
  462. sFR.ftLastWriteTime.dwHighDateTime,
  463. sFR.ftLastWriteTime.dwLowDateTime,
  464. sFR.ftOrgTime.dwHighDateTime,
  465. sFR.ftOrgTime.dwLowDateTime);
  466. if (sFR.rgwName[0]) {
  467. printf(" LFN:");
  468. printwidestring(sFR.rgwName, sizeof(sFR.rgwName)/sizeof(USHORT));
  469. fLfn = 1;
  470. }
  471. printf("\r\n");
  472. DisplaySecurityContext2(" ",&sFR.Security);
  473. if (ulidDir != ulid)
  474. {
  475. printf("DirInode = %x\r\n", ulidDir);
  476. #if defined(BITCOPY)
  477. FormNameStringDB(szDbDir, sFR.ulidShadow, strmPath);
  478. DBCSC_BitmapAppendStreamName(strmPath, MAX_PATH);
  479. printf("Trying to read CSCBitmap file %s\n", strmPath);
  480. // read bitmap
  481. switch(DBCSC_BitmapRead(&lpbitmap, strmPath)) {
  482. case 1:
  483. // Print the bitmap associated if any
  484. printf("\n");
  485. DBCSC_BitmapOutput(stdout, lpbitmap);
  486. printf("\n");
  487. // if bitmap opened delete bitmap
  488. DBCSC_BitmapDelete(&lpbitmap);
  489. break;
  490. case -1:
  491. printf("Error reading bitmap file %s or bitmap invalid\n",
  492. strmPath);
  493. break;
  494. case -2:
  495. printf("No CSCBitmap\n");
  496. break;
  497. case 0:
  498. default:
  499. printf("Something strange going on w/ bitmap printing...\n");
  500. break;
  501. }
  502. #endif // defined(BITCOPY)
  503. break;
  504. }
  505. if (lpszName) {
  506. printf("--- Press any key to continue search; ESC to cancel ---\r\n");
  507. if(_getch()==ESC) {
  508. break;
  509. }
  510. }
  511. printf("\r\n");
  512. } else if (fPrintOvf && (sFR.uchType == (unsigned char)REC_OVERFLOW)) {
  513. printf("(overflow) ");
  514. printwidestring(sFR.rgwOvf,
  515. (sizeof(FILEREC)-sizeof(RECORDMANAGER_COMMON_RECORD))/sizeof(USHORT));
  516. printf("\r\n\r\n");
  517. }
  518. // do counting only when we are scanning the whole directory
  519. if (!lpszName && (ulid == ulidDir)) {
  520. ++count;
  521. }
  522. }
  523. printf("\r\n");
  524. }
  525. bailout:
  526. if (fp)
  527. fclose(fp);
  528. }
  529. void PRIVATE FormNameStringDB(
  530. LPSTR lpdbID,
  531. ulong ulidFile,
  532. LPSTR lpName
  533. )
  534. {
  535. LPSTR lp;
  536. char chSubdir;
  537. #ifdef CSC_ON_NT
  538. // Prepend the local path
  539. strcpy(lpName, lpdbID);
  540. strcat(lpName, szBackslash);
  541. #else
  542. // Prepend the local path
  543. _fstrcpy(lpName, lpdbID);
  544. _fstrcat(lpName, szBackslash);
  545. #endif //CSC_ON_NT
  546. // Bump the pointer appropriately
  547. #ifdef CSC_ON_NT
  548. lp = lpName + strlen(lpName);
  549. #else
  550. lp = lpName + _fstrlen(lpName);
  551. #endif //CSC_ON_NT
  552. chSubdir = CSCDbSubdirSecondChar(ulidFile);
  553. // sprinkle the user files in one of the subdirectories
  554. if (chSubdir)
  555. {
  556. // now append the subdirectory
  557. *lp++ = CSCDbSubdirFirstChar();
  558. *lp++ = chSubdir;
  559. *lp++ = '\\';
  560. }
  561. HexToA(ulidFile, lp, 8);
  562. lp += 8;
  563. *lp = 0;
  564. }
  565. int PUBLIC HexToA(
  566. ulong ulHex,
  567. LPSTR lpName,
  568. int count)
  569. {
  570. int i;
  571. LPSTR lp = lpName+count-1;
  572. unsigned char uch;
  573. for (i=0; i<count; ++i)
  574. {
  575. uch = (unsigned char)(ulHex & 0xf) + '0';
  576. if (uch > '9')
  577. uch += 7; // A becomes '0' + A + 7 which is 'A'
  578. *lp = uch;
  579. --lp;
  580. ulHex >>= 4;
  581. }
  582. *(lpName+count) = '\0';
  583. return 0;
  584. }
  585. BOOL
  586. FindAncestor(
  587. ulong ulid,
  588. ulong *lpulidDir
  589. )
  590. {
  591. ulong ulRec = RecFromInode(ulid);
  592. FILE *fp= (FILE *)NULL;
  593. QHEADER sQH;
  594. QREC sQR;
  595. BOOL fRet = FALSE;
  596. *lpulidDir = 0;
  597. FormNameStringDB(szDbDir, ULID_PQ, szName);
  598. if (fp = _fsopen(szName, "rb", _SH_DENYNO))
  599. {
  600. if (fread(&sQH, sizeof(QHEADER), 1, fp) != 1)
  601. {
  602. printf("Error reading PQ header \r\n");
  603. goto bailout;
  604. }
  605. fseek(fp, ((ulRec-1) * sizeof(QREC))+sizeof(QHEADER), SEEK_SET);
  606. if (fread(&sQR, sizeof(QREC), 1, fp)!=1){
  607. goto bailout;
  608. }
  609. *lpulidDir = sQR.ulidDir;
  610. fRet = TRUE;
  611. }
  612. bailout:
  613. if (fp)
  614. fclose(fp);
  615. return fRet;
  616. }
  617. #ifndef CSC_ON_NT
  618. void
  619. printwidestring(
  620. USHORT *lpwString,
  621. unsigned long cntChars
  622. )
  623. {
  624. unsigned long i;
  625. cntChars = min(cntChars, sizeof(rgPrint) -1);
  626. for(i=0; (i< cntChars) && lpwString[i]; ++i)
  627. {
  628. rgPrint[i] = (char)(lpwString[i]);
  629. }
  630. rgPrint[i] = 0;
  631. printf(rgPrint);
  632. }
  633. #else
  634. void
  635. printwidestring(
  636. USHORT *lpwString,
  637. unsigned long cntChars
  638. )
  639. {
  640. printf("%ls", lpwString);
  641. }
  642. #endif
  643. int RoughCompareWideStringWithAnsiString(
  644. LPSTR lpSrcString,
  645. USHORT *lpwDstString,
  646. int cntMax
  647. )
  648. {
  649. char ch;
  650. USHORT uch;
  651. int i;
  652. for (i=0;i<cntMax;++i)
  653. {
  654. ch = *lpSrcString++;
  655. uch = *lpwDstString++;
  656. uch = _wtoupper(uch);
  657. ch = _mytoupper(ch);
  658. if (!ch)
  659. {
  660. return 0;
  661. }
  662. if (ch != (char)uch)
  663. {
  664. return ((char)uch - ch);
  665. }
  666. }
  667. if (i==cntMax)
  668. {
  669. return 0;
  670. }
  671. return 1; // this should never occur
  672. }