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.

1417 lines
40 KiB

  1. #define UNICODE
  2. #define PUBLIC
  3. #define PRIVATE
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <memory.h>
  7. #include <string.h>
  8. #include <windows.h>
  9. #include <conio.h>
  10. #include <share.h>
  11. #include <dos.h>
  12. #include <sddl.h>
  13. #include "cscapi.h"
  14. #include "csc_bmpc.h"
  15. #pragma pack (1)
  16. #include "struct.h"
  17. #define MAX_PQ_PER_PAGE 10
  18. #define MAX_SHARES_PER_PAGE 6
  19. #define MAX_FILE_PER_PAGE 4
  20. #define MAX_INODES_PER_PAGE 15
  21. #define _wtoupper(x) ( ( ((x)>='a')&&((x)<='z') ) ? ((x)-'a'+'A'):(x))
  22. typedef PVOID CSCHFILE;
  23. #include "shdcom.h"
  24. #include "cscsec.h"
  25. #define ESC 0x1b
  26. #include "record.h"
  27. #define InodeFromRec(ulRec, fFile) ((ulRec+ULID_FIRST_USER_DIR-1) | ((fFile)?0x80000000:0))
  28. #define RecFromInode(hShadow) ((hShadow & 0x7fffffff) - (ULID_FIRST_USER_DIR-1))
  29. WCHAR rgwch[256];
  30. WCHAR rgPrint[1024];
  31. WCHAR rgwchPar[256];
  32. WCHAR Shadow[] = L"\\WINDOWS\\CSC";
  33. WCHAR Backslash[] = L"\\";
  34. WCHAR DbDir[256]; // shadow database
  35. WCHAR Name[MAX_PATH]; // working buffer
  36. extern BOOLEAN fSwDebug;
  37. // The _DB is used to distinguish this from the kernel mode CSC_BITMAP
  38. // or the usermode _U
  39. typedef struct _CSC_BITMAP_DB {
  40. DWORD bitmapsize; // size in bits. How many bits effective in the bitmap
  41. DWORD numDWORD; // how many DWORDs to accomodate the bitmap */
  42. LPDWORD bitmap; // The bitmap itself
  43. } CSC_BITMAP_DB, *LPCSC_BITMAP_DB, *PCSC_BITMAP_DB;
  44. // append this to inode file name to get the stream name
  45. PWCHAR CscBmpAltStrmName = L":cscbmp";
  46. LONG DispFunc(PWSTR);
  47. LONG EditFileFunc(PWSTR, FILEREC *);
  48. LONG EditShareFunc(PWSTR, SHAREREC *);
  49. VOID DisplayShares(PWSTR);
  50. VOID DisplayInodes(VOID);
  51. VOID DisplayPriorityQ(VOID);
  52. VOID DisplaySids(VOID);
  53. VOID DisplayFile(ULONG ulid, PWSTR, BOOL fForce);
  54. VOID EditFile(ULONG ulid);
  55. VOID EditShare(ULONG ulid);
  56. LONG HexToA(ULONG, PWSTR, LONG);
  57. // From recordse.c
  58. #define CSC_NUMBER_OF_SIDS_OFFSET (0x0)
  59. #define CSC_SID_SIZES_OFFSET (CSC_NUMBER_OF_SIDS_OFFSET + sizeof(ULONG))
  60. VOID
  61. FormNameStringDB(
  62. PWSTR lpdbID,
  63. ULONG ulidFile,
  64. PWSTR lpName);
  65. BOOL
  66. FindAncestor(
  67. ULONG ulid,
  68. ULONG *lpulidDir);
  69. LONG
  70. RoughCompareWideStringWithAnsiString(
  71. PWSTR lpSrcString,
  72. USHORT *lpwDstString,
  73. LONG cntMax);
  74. PWSTR
  75. ConvertGmtTimeToString(
  76. FILETIME Time,
  77. PWSTR OutputBuffer);
  78. int
  79. DBCSC_BitmapIsMarked(
  80. LPCSC_BITMAP_DB lpbitmap,
  81. DWORD bitoffset);
  82. int
  83. DBCSC_BitmapAppendStreamName(
  84. PWCHAR fname,
  85. DWORD bufsize);
  86. int
  87. DBCSC_BitmapRead(
  88. LPCSC_BITMAP_DB *lplpbitmap,
  89. LPCTSTR filename);
  90. VOID
  91. DBCSC_BitmapOutput(
  92. FILE *outStrm,
  93. LPCSC_BITMAP_DB lpbitmap);
  94. #if defined(CSCUTIL_INTERNAL)
  95. CmdDb(PWSTR DbArg)
  96. {
  97. BOOL fRet;
  98. DWORD junk;
  99. unsigned uAttr;
  100. int iRet = -1;
  101. if (DbArg == NULL) {
  102. fRet = CSCGetSpaceUsageW(
  103. DbDir,
  104. sizeof(DbDir)/sizeof(WCHAR),
  105. &junk,
  106. &junk,
  107. &junk,
  108. &junk,
  109. &junk,
  110. &junk);
  111. if (fRet == FALSE)
  112. wcscpy(DbDir, Shadow);
  113. } else {
  114. wcscpy(DbDir, DbArg);
  115. }
  116. if((uAttr = GetFileAttributesW(DbDir)) == 0xffffffff) {
  117. MyPrintf(L"Error accessing directory %ws \r\n", DbDir);
  118. } else if (!(uAttr & _A_SUBDIR)) {
  119. MyPrintf(L"%ws is not a directory\r\n", DbDir);
  120. } else {
  121. do {
  122. memset(rgwch, 0, sizeof(rgwch));
  123. MyPrintf(
  124. L"\r\n"
  125. L"(S)hares [name], "
  126. L"Pri(Q), "
  127. L"(O)wner, "
  128. L"(F)ile inode# [name], "
  129. L"(E)dit inode#, "
  130. L"e(D)it share#, "
  131. L"e(X)it "
  132. L":");
  133. if (!fgetws(rgwch, sizeof(rgwch)/sizeof(WCHAR), stdin))
  134. break;
  135. MyPrintf(L"\r\n");
  136. if (DispFunc(rgwch) == 0)
  137. break;
  138. } while (1);
  139. iRet = 0;
  140. }
  141. return (iRet);
  142. }
  143. LONG
  144. DispFunc(PWSTR lpBuff)
  145. {
  146. WCHAR wch;
  147. ULONG ulid;
  148. LONG cnt;
  149. // Chop leading blanks
  150. if (lpBuff != NULL)
  151. while (*lpBuff != L'\0' && *lpBuff == L' ')
  152. lpBuff++;
  153. cnt = swscanf(lpBuff, L"%c", &wch);
  154. if (!cnt)
  155. return 0;
  156. switch (wch) {
  157. // Display shares database
  158. case L's':
  159. case L'S':
  160. cnt = swscanf(lpBuff, L"%c%ws", &wch, rgwchPar);
  161. DisplayShares((cnt==2) ? rgwchPar : NULL);
  162. break;
  163. // display priority Q database
  164. case L'q':
  165. case L'Q':
  166. DisplayPriorityQ();
  167. break;
  168. case L'o':
  169. case L'O':
  170. DisplaySids();
  171. break;
  172. case L'f':
  173. case L'F':
  174. cnt = swscanf(lpBuff, L"%c%x%ws", &wch, &ulid, rgwchPar);
  175. if (cnt==2) {
  176. // display Inode file
  177. DisplayFile(ulid, NULL, (wch == 'F') ? TRUE : FALSE);
  178. } else if (cnt==3) {
  179. MyPrintf(L"Looking for %ws in 0x%x \r\n", rgwchPar, ulid);
  180. // display Inode file
  181. DisplayFile(ulid, rgwchPar, (wch == 'F') ? TRUE : FALSE);
  182. }
  183. break;
  184. case L'e':
  185. case L'E':
  186. cnt = swscanf(lpBuff, L"%c%x%ws", &wch, &ulid, rgwchPar);
  187. if (cnt==2) {
  188. // display Inode file
  189. EditFile(ulid);
  190. }
  191. break;
  192. case L'd':
  193. case L'D':
  194. cnt = swscanf(lpBuff, L"%c%x%ws", &wch, &ulid, rgwchPar);
  195. if (cnt==2) {
  196. // display Inode file
  197. EditShare(ulid);
  198. }
  199. break;
  200. case L'x':
  201. case L'X':
  202. return 0;
  203. }
  204. return 1;
  205. }
  206. VOID
  207. DisplaySecurityContext2(
  208. PWSTR pSecurityDescriptor,
  209. LPRECORDMANAGER_SECURITY_CONTEXT pSecurityContext)
  210. {
  211. PCACHED_SECURITY_INFORMATION pCachedSecurityInformation;
  212. BOOL fGotOne = FALSE;
  213. ULONG i;
  214. pCachedSecurityInformation = (PCACHED_SECURITY_INFORMATION)pSecurityContext;
  215. for (i = 0; i < MAXIMUM_NUMBER_OF_USERS; i++) {
  216. CSC_SID_INDEX SidIndex;
  217. SidIndex = pCachedSecurityInformation->AccessRights[i].SidIndex;
  218. if (SidIndex != CSC_INVALID_SID_INDEX) {
  219. fGotOne = TRUE;
  220. break;
  221. }
  222. }
  223. if (fGotOne == FALSE)
  224. return;
  225. MyPrintf(L"%ws Security: ", pSecurityDescriptor);
  226. for (i = 0; i < MAXIMUM_NUMBER_OF_USERS; i++) {
  227. CSC_SID_INDEX SidIndex;
  228. SidIndex = pCachedSecurityInformation->AccessRights[i].SidIndex;
  229. if (SidIndex == CSC_INVALID_SID_INDEX) {
  230. continue;
  231. }else if (SidIndex == CSC_GUEST_SID_INDEX) {
  232. MyPrintf(L"(G:0x%x)",
  233. pCachedSecurityInformation->AccessRights[i].MaximalRights);
  234. } else {
  235. MyPrintf(L"(0x%x:0x%x)",
  236. SidIndex,
  237. pCachedSecurityInformation->AccessRights[i].MaximalRights);
  238. }
  239. }
  240. MyPrintf(L"\r\n");
  241. }
  242. VOID
  243. DisplayShares(PWSTR ShareName)
  244. {
  245. FILE *fp= NULL;
  246. SHAREHEADER sSH;
  247. SHAREREC sSR;
  248. ULONG ulrec = 0;
  249. LONG count = 0;
  250. WCHAR TimeBuf1[30];
  251. WCHAR TimeBuf2[30];
  252. FormNameStringDB(DbDir, ULID_SHARE, Name);
  253. if (fp = _wfopen(Name, L"rb")) {
  254. if (fread(&sSH, sizeof(SHAREHEADER), 1, fp) != 1) {
  255. MyPrintf(L"Error reading server header \r\n");
  256. goto bailout;
  257. }
  258. MyPrintf(L"Header: Flags=%x Version=%lx Records=%ld Size=%d \r\n",
  259. sSH.uFlags, sSH.ulVersion, sSH.ulRecords, sSH.uRecSize);
  260. MyPrintf(L"Store(Max): Size=%d Dirs=%d Files=%d\r\n",
  261. sSH.sMax.ulSize,
  262. sSH.sMax.ucntDirs,
  263. sSH.sMax.ucntFiles);
  264. MyPrintf(L"Store(Cur): Size=%d Dirs=%d Files=%d\r\n",
  265. sSH.sCur.ulSize,
  266. sSH.sCur.ucntDirs,
  267. sSH.sCur.ucntFiles);
  268. MyPrintf(L"\r\n");
  269. for (ulrec = 1; fread(&sSR, sizeof(SHAREREC), 1, fp) == 1; ulrec++) {
  270. if (sSR.uchType == (UCHAR)REC_DATA) {
  271. if (ShareName != NULL) {
  272. if (RoughCompareWideStringWithAnsiString(
  273. ShareName,
  274. sSR.rgPath,
  275. sizeof(sSR.rgPath)/sizeof(WCHAR)-1)
  276. ) {
  277. continue;
  278. }
  279. }
  280. MyPrintf(L"%ws (0x%x) Root=0x%x\r\n",
  281. sSR.rgPath,
  282. ulrec,
  283. sSR.ulidShadow);
  284. MyPrintf(L" Status=0x%x RootStatus=0x%x "
  285. L"HntFlgs=0x%x HntPri=0x%x Attr=0x%x\r\n",
  286. sSR.uStatus,
  287. (unsigned)(sSR.usRootStatus),
  288. (unsigned)(sSR.uchHintFlags),
  289. (unsigned)(sSR.uchHintPri),
  290. sSR.dwFileAttrib);
  291. ConvertGmtTimeToString(sSR.ftLastWriteTime, TimeBuf1);
  292. ConvertGmtTimeToString(sSR.ftOrgTime, TimeBuf2);
  293. MyPrintf(L" LastWriteTime: %ws Orgtime: %ws\r\n", TimeBuf1, TimeBuf2);
  294. DisplaySecurityContext2(L" ShareLevel",&sSR.sShareSecurity);
  295. DisplaySecurityContext2(L" Root ",&sSR.sRootSecurity);
  296. MyPrintf(L"\r\n");
  297. }
  298. }
  299. }
  300. bailout:
  301. if (fp)
  302. fclose(fp);
  303. }
  304. VOID
  305. DisplayPriorityQ(VOID)
  306. {
  307. FILE *fp= NULL;
  308. QHEADER sQH;
  309. QREC sQR;
  310. ULONG ulRec = 1;
  311. LONG count = 0;
  312. FormNameStringDB(DbDir, ULID_PQ, Name);
  313. if (fp = _wfopen(Name, L"rb")) {
  314. if (fread(&sQH, sizeof(QHEADER), 1, fp) != 1) {
  315. MyPrintf(L"Error reading PQ header \r\n");
  316. goto bailout;
  317. }
  318. MyPrintf(L"Header: Flags=%x Version=%lx Records=%ld Size=%d head=%ld tail=%ld\r\n",
  319. sQH.uchFlags,
  320. sQH.ulVersion,
  321. sQH.ulRecords,
  322. sQH.uRecSize,
  323. sQH.ulrecHead,
  324. sQH.ulrecTail);
  325. MyPrintf(L"\r\n");
  326. MyPrintf(
  327. L" REC SHARE DIR SHADOW STATUS PRI HINTFLGS HINTPRI PREV NEXT DIRENT\r\n");
  328. for (ulRec = sQH.ulrecHead; ulRec;) {
  329. fseek(fp, ((ulRec-1) * sizeof(QREC))+sizeof(QHEADER), SEEK_SET);
  330. if (fread(&sQR, sizeof(QREC), 1, fp)!=1)
  331. break;
  332. MyPrintf(L"%5d %5x %8x %8x %8x %4d %8x %7d %5d %5d %6d\r\n",
  333. ulRec,
  334. sQR.ulidShare,
  335. sQR.ulidDir,
  336. sQR.ulidShadow,
  337. sQR.usStatus,
  338. (unsigned)(sQR.uchRefPri),
  339. (unsigned)(sQR.uchHintFlags),
  340. (unsigned)(sQR.uchHintPri),
  341. sQR.ulrecPrev,
  342. sQR.ulrecNext,
  343. sQR.ulrecDirEntry);
  344. ++count;
  345. ulRec = sQR.ulrecNext;
  346. }
  347. }
  348. bailout:
  349. if (fp)
  350. fclose(fp);
  351. }
  352. VOID
  353. DisplaySids(VOID)
  354. {
  355. DWORD Status = ERROR_SUCCESS;
  356. ULONG SidOffset = 0;
  357. ULONG NumberOfSids;
  358. ULONG BytesRead;
  359. ULONG i;
  360. PCSC_SIDS pCscSids = NULL;
  361. FILE *fp = NULL;
  362. LPWSTR StringSid = NULL;
  363. SID_NAME_USE SidUse;
  364. BOOL bRet = FALSE;
  365. DWORD cbAcctName;
  366. DWORD cbDomainName;
  367. WCHAR AcctName[MAX_PATH];
  368. WCHAR DomainName[MAX_PATH];
  369. FormNameStringDB(DbDir, ULID_SID_MAPPINGS, Name);
  370. fp = _wfopen(Name, L"rb");
  371. if (fp == NULL) {
  372. MyPrintf(L"Error opening SID file\r\n");
  373. goto bailout;
  374. }
  375. fseek(fp, CSC_NUMBER_OF_SIDS_OFFSET, SEEK_SET);
  376. if (fread(&NumberOfSids, sizeof(NumberOfSids), 1, fp) != 1) {
  377. MyPrintf(L"Error reading # SIDS\r\n");
  378. goto bailout;
  379. }
  380. pCscSids = (PCSC_SIDS)malloc(sizeof(CSC_SIDS) + sizeof(CSC_SID) * NumberOfSids);
  381. if (pCscSids == NULL) {
  382. MyPrintf(L"Error allocating memory of SID array\n");
  383. goto bailout;
  384. }
  385. pCscSids->MaximumNumberOfSids = NumberOfSids;
  386. pCscSids->NumberOfSids = NumberOfSids;
  387. for (i = 0; i < NumberOfSids; i++)
  388. pCscSids->Sids[i].pSid = NULL;
  389. fseek(fp, CSC_SID_SIZES_OFFSET, SEEK_SET);
  390. if (fread(&pCscSids->Sids, sizeof(CSC_SID) * NumberOfSids, 1, fp) != 1) {
  391. MyPrintf(L"Error reading SIDS\r\n");
  392. goto bailout;
  393. }
  394. // The array structure has been initialized correctly. Each of the
  395. // individual sids needs to be initialized.
  396. SidOffset = CSC_SID_SIZES_OFFSET + sizeof(CSC_SID) * NumberOfSids;
  397. for (i = 0; i < NumberOfSids; i++) {
  398. pCscSids->Sids[i].pSid = malloc(pCscSids->Sids[i].SidLength);
  399. if (pCscSids->Sids[i].pSid == NULL) {
  400. MyPrintf(L"Error allocating memory of SID array\n");
  401. goto bailout;
  402. }
  403. fseek(fp, SidOffset, SEEK_SET);
  404. if (fread(pCscSids->Sids[i].pSid, pCscSids->Sids[i].SidLength, 1, fp) != 1) {
  405. MyPrintf(L"Error reading SIDS\r\n");
  406. goto bailout;
  407. }
  408. SidOffset += pCscSids->Sids[i].SidLength;
  409. }
  410. MyPrintf(L"MaximumNumberOfSids: %d\r\n"
  411. L"NumberOfSids: %d\r\n",
  412. pCscSids->MaximumNumberOfSids,
  413. pCscSids->NumberOfSids);
  414. for (i = 0; i < NumberOfSids; i++) {
  415. StringSid = NULL;
  416. if (ConvertSidToStringSid(pCscSids->Sids[i].pSid, &StringSid)) {
  417. MyPrintf(L"---0x%x (%d)---\r\n"
  418. L" SidLength: %d\r\n"
  419. L" Sid: %ws\r\n",
  420. i+1, i+1,
  421. pCscSids->Sids[i].SidLength,
  422. StringSid);
  423. LocalFree(StringSid);
  424. StringSid = NULL;
  425. DomainName[0] = L'0';
  426. AcctName[0] = L'0';
  427. cbAcctName = sizeof(AcctName) / sizeof(WCHAR);
  428. cbDomainName = sizeof(DomainName) / sizeof(WCHAR);
  429. bRet = LookupAccountSid(
  430. NULL,
  431. pCscSids->Sids[i].pSid,
  432. AcctName,
  433. &cbAcctName,
  434. DomainName,
  435. &cbDomainName,
  436. &SidUse);
  437. if (bRet) {
  438. MyPrintf(L" Name: %ws%ws%ws\r\n",
  439. DomainName,
  440. DomainName[0] ? L"\\" : L"",
  441. AcctName);
  442. } else {
  443. MyPrintf(L" Name: <unknown>\r\n");
  444. }
  445. } else {
  446. MyPrintf(L"ConvertSidToStringSid returned %d\r\n", GetLastError());
  447. }
  448. }
  449. bailout:
  450. if (fp)
  451. fclose(fp);
  452. }
  453. VOID
  454. DisplayFile(
  455. ULONG ulid,
  456. PWSTR lpwszName,
  457. BOOL fForce)
  458. {
  459. FILE *fp= NULL;
  460. FILEHEADER sFH;
  461. FILEREC sFR;
  462. LONG fLfn=0;
  463. ULONG ulidDir=ulid;
  464. LONG fPrintOvf = 0, count=0;
  465. WCHAR strmPath[MAX_PATH];
  466. LPCSC_BITMAP_DB lpbitmap = NULL;
  467. WCHAR TimeBuf1[30];
  468. WCHAR TimeBuf2[30];
  469. if (IsLeaf(ulid)) {
  470. if (!FindAncestor(ulid, &ulidDir))
  471. return;
  472. }
  473. FormNameStringDB(DbDir, ulidDir, Name);
  474. if (fp = _wfopen(Name, L"rb")) {
  475. if (fread(&sFH, sizeof(FILEHEADER), 1, fp) != 1) {
  476. MyPrintf(L"Error reading file header \r\n");
  477. goto bailout;
  478. }
  479. if (ulid == ulidDir) {
  480. MyPrintf(L"Header: Flags=%x Version=%lx Records=%ld Size=%d\r\n",
  481. sFH.uchFlags, sFH.ulVersion, sFH.ulRecords, sFH.uRecSize);
  482. MyPrintf(L"Header: bytes=%ld entries=%d Share=%ld Dir=%lx\r\n",
  483. sFH.ulsizeShadow, sFH.ucShadows, sFH.ulidShare, sFH.ulidDir);
  484. printf ("\r\n");
  485. fPrintOvf = 1;
  486. }
  487. while (fread(&sFR, sizeof(FILEREC), 1, fp)==1) {
  488. if (sFR.uchType != (unsigned char)REC_OVERFLOW) {
  489. if (fLfn) {
  490. if (ulidDir != ulid)
  491. break;
  492. }
  493. fLfn = 0;
  494. }
  495. if (sFR.uchType==(unsigned char)REC_DATA) {
  496. if (ulidDir != ulid) {
  497. if (ulid != sFR.ulidShadow)
  498. continue;
  499. }
  500. if (lpwszName) {
  501. if (RoughCompareWideStringWithAnsiString(
  502. lpwszName,
  503. sFR.rgwName,
  504. sizeof(sFR.rgw83Name)/sizeof(WCHAR)-1)
  505. ) {
  506. continue;
  507. }
  508. }
  509. fPrintOvf = 1;
  510. MyPrintf(L"%ws (0x%x)\r\n", sFR.rgw83Name, sFR.ulidShadow);
  511. if (fForce == TRUE) {
  512. MyPrintf(L" Type=%c Flags=0x%x status=0x%x size=%ld attrib=0x%lx\r\n",
  513. sFR.uchType,
  514. (unsigned)sFR.uchFlags,
  515. sFR.uStatus,
  516. sFR.ulFileSize,
  517. sFR.dwFileAttrib);
  518. MyPrintf(L" PinFlags=0x%x PinCount=%d RefPri=%d OriginalInode=0x%0x\r\n",
  519. (unsigned)(sFR.uchHintFlags),
  520. (int)(sFR.uchHintPri),
  521. (int)(sFR.uchRefPri),
  522. sFR.ulidShadowOrg);
  523. ConvertGmtTimeToString(sFR.ftLastWriteTime, TimeBuf1);
  524. ConvertGmtTimeToString(sFR.ftOrgTime, TimeBuf2);
  525. MyPrintf(L" LastWriteTime: %ws Orgtime: %ws\r\n", TimeBuf1, TimeBuf2);
  526. if (sFR.rgwName[0]) {
  527. MyPrintf(L" LFN:%ws", sFR.rgwName);
  528. fLfn = 1;
  529. }
  530. MyPrintf(L"\r\n");
  531. DisplaySecurityContext2(L" ",&sFR.Security);
  532. if (ulidDir != ulid) {
  533. MyPrintf(L" DirInode = 0x%x\r\n", ulidDir);
  534. FormNameStringDB(DbDir, sFR.ulidShadow, strmPath);
  535. DBCSC_BitmapAppendStreamName(strmPath, MAX_PATH);
  536. // read bitmap
  537. switch(DBCSC_BitmapRead(&lpbitmap, strmPath)) {
  538. case 1:
  539. // Print the bitmap associated if any
  540. MyPrintf(L"\r\n");
  541. DBCSC_BitmapOutput(stdout, lpbitmap);
  542. MyPrintf(L"\r\n");
  543. // if bitmap opened delete bitmap
  544. // DBCSC_BitmapDelete(&lpbitmap);
  545. break;
  546. case -1:
  547. MyPrintf(L"Error reading bitmap file %ws or bitmap invalid\r\n",
  548. strmPath);
  549. break;
  550. case -2:
  551. MyPrintf(L"No CSCBitmap\n");
  552. break;
  553. case 0:
  554. default:
  555. MyPrintf(L"Something strange going on with bitmap printing...\r\n");
  556. break;
  557. }
  558. break;
  559. }
  560. MyPrintf(L"\r\n");
  561. } else if (fPrintOvf && (sFR.uchType == (unsigned char)REC_OVERFLOW)) {
  562. MyPrintf(L"(overflow) ");
  563. MyPrintf(L"%ws\r\n\r\n", sFR.rgwOvf);
  564. }
  565. }
  566. // do counting only when we are scanning the whole directory
  567. if (!lpwszName && (ulid == ulidDir)) {
  568. ++count;
  569. }
  570. }
  571. MyPrintf(L"\r\n");
  572. }
  573. bailout:
  574. if (fp)
  575. fclose(fp);
  576. }
  577. VOID
  578. EditFile(
  579. ULONG ulid)
  580. {
  581. FILE *fp= NULL;
  582. FILEHEADER sFH;
  583. FILEREC sFR;
  584. ULONG ulidDir=ulid;
  585. WCHAR TimeBuf1[30];
  586. WCHAR TimeBuf2[30];
  587. LONG iRes;
  588. if (!IsLeaf(ulid)) {
  589. MyPrintf(L"0x%x is a directory.\r\n", ulid);
  590. return;
  591. }
  592. if (!FindAncestor(ulid, &ulidDir))
  593. return;
  594. FormNameStringDB(DbDir, ulidDir, Name);
  595. if (fp = _wfopen(Name, L"rb+")) {
  596. if (fread(&sFH, sizeof(FILEHEADER), 1, fp) != 1) {
  597. MyPrintf(L"Error reading file header \r\n");
  598. goto bailout;
  599. }
  600. while (fread(&sFR, sizeof(FILEREC), 1, fp)==1) {
  601. if (sFR.uchType == (unsigned char)REC_OVERFLOW) {
  602. continue;
  603. }
  604. if (sFR.uchType==(unsigned char)REC_DATA) {
  605. if (ulid != sFR.ulidShadow)
  606. continue;
  607. do {
  608. MyPrintf(L"---------------------------------------------\r\n");
  609. MyPrintf(L"%ws (0x%x)\r\n", sFR.rgw83Name, sFR.ulidShadow);
  610. MyPrintf(L" Type=%c Flags=0x%x status=0x%x size=%ld attrib=0x%lx\r\n",
  611. sFR.uchType,
  612. (unsigned)sFR.uchFlags,
  613. sFR.uStatus,
  614. sFR.ulFileSize,
  615. sFR.dwFileAttrib);
  616. MyPrintf(L" PinFlags=0x%x PinCount=%d RefPri=%d OriginalInode=0x%0x\r\n",
  617. (unsigned)(sFR.uchHintFlags),
  618. (int)(sFR.uchHintPri),
  619. (int)(sFR.uchRefPri),
  620. sFR.ulidShadowOrg);
  621. ConvertGmtTimeToString(sFR.ftLastWriteTime, TimeBuf1);
  622. ConvertGmtTimeToString(sFR.ftOrgTime, TimeBuf2);
  623. MyPrintf(L" LastWriteTime: %ws Orgtime: %ws\r\n", TimeBuf1, TimeBuf2);
  624. MyPrintf(L" DirInode = 0x%x\r\n", ulidDir);
  625. memset(rgwch, 0, sizeof(rgwch));
  626. MyPrintf(
  627. L"\r\n"
  628. L"(F)lags, "
  629. L"(S)tatus, "
  630. L"si(Z)e , "
  631. L"(A)ttrib, "
  632. L"e(X)it "
  633. L":");
  634. if (!fgetws(rgwch, sizeof(rgwch)/sizeof(WCHAR), stdin))
  635. break;
  636. MyPrintf(L"\r\n");
  637. iRes = EditFileFunc(rgwch, &sFR);
  638. if (iRes == 0) {
  639. break;
  640. } else if (iRes == 1) {
  641. fseek(fp, ftell(fp) - sizeof(FILEREC), SEEK_SET);
  642. fwrite(&sFR, sizeof(FILEREC), 1, fp);
  643. }
  644. } while (1);
  645. }
  646. }
  647. MyPrintf(L"\r\n");
  648. }
  649. bailout:
  650. if (fp)
  651. fclose(fp);
  652. }
  653. LONG
  654. EditFileFunc(
  655. PWSTR lpBuff,
  656. FILEREC *sFR)
  657. {
  658. WCHAR wch;
  659. ULONG NewFlags;
  660. ULONG NewStatus;
  661. ULONG NewSize;
  662. ULONG NewAttrib;
  663. LONG cnt;
  664. // Tristate return:
  665. // 0 -> exit
  666. // 1 -> write updated sFR
  667. // 2 -> don't write updated sFR
  668. // Chop leading blanks
  669. if (lpBuff != NULL)
  670. while (*lpBuff != L'\0' && *lpBuff == L' ')
  671. lpBuff++;
  672. cnt = swscanf(lpBuff, L"%c", &wch);
  673. if (!cnt)
  674. return 0;
  675. switch (wch) {
  676. // Edit flags
  677. case L'f':
  678. case L'F':
  679. cnt = swscanf(lpBuff, L"%c%x", &wch, &NewFlags);
  680. if (cnt != 2)
  681. return 2;
  682. MyPrintf(L"Flags 0x%x -> 0x%x\r\n", (unsigned)sFR->uchFlags, NewFlags);
  683. sFR->uchFlags = (char)NewFlags;
  684. break;
  685. // Edit status
  686. case L's':
  687. case L'S':
  688. cnt = swscanf(lpBuff, L"%c%x", &wch, &NewStatus);
  689. if (cnt != 2)
  690. return 2;
  691. MyPrintf(L"Status 0x%x -> 0x%x\r\n", sFR->uStatus, NewStatus);
  692. sFR->uStatus = (USHORT)NewStatus;
  693. break;
  694. // Edit size
  695. case L'z':
  696. case L'Z':
  697. cnt = swscanf(lpBuff, L"%c%x", &wch, &NewSize);
  698. if (cnt != 2)
  699. return 2;
  700. MyPrintf(L"Size 0x%x -> 0x%x\r\n", sFR->ulFileSize, NewSize);
  701. sFR->ulFileSize = NewSize;
  702. break;
  703. // Edit attrib
  704. case L'a':
  705. case L'A':
  706. cnt = swscanf(lpBuff, L"%c%x", &wch, &NewAttrib);
  707. if (cnt != 2)
  708. return 2;
  709. MyPrintf(L"Attrib 0x%x -> 0x%x\r\n", sFR->dwFileAttrib, NewAttrib);
  710. sFR->dwFileAttrib = NewAttrib;
  711. break;
  712. // Exit
  713. case L'x':
  714. case L'X':
  715. return 0;
  716. }
  717. return 1;
  718. }
  719. VOID
  720. EditShare(
  721. ULONG ulid)
  722. {
  723. FILE *fp= NULL;
  724. SHAREHEADER sSH;
  725. SHAREREC sSR;
  726. WCHAR TimeBuf1[30];
  727. WCHAR TimeBuf2[30];
  728. LONG iRes;
  729. ULONG ulrec = 0;
  730. FormNameStringDB(DbDir, ULID_SHARE, Name);
  731. if (fp = _wfopen(Name, L"rb+")) {
  732. if (fread(&sSH, sizeof(SHAREHEADER), 1, fp) != 1) {
  733. MyPrintf(L"Error reading server header \r\n");
  734. goto bailout;
  735. }
  736. for (ulrec = 1; fread(&sSR, sizeof(SHAREREC), 1, fp) == 1; ulrec++) {
  737. if (sSR.uchType == (UCHAR)REC_DATA) {
  738. if (ulid != ulrec)
  739. continue;
  740. do {
  741. MyPrintf(L"---------------------------------------------\r\n");
  742. MyPrintf(L"%ws (0x%x) Root=0x%x\r\n",
  743. sSR.rgPath,
  744. ulrec,
  745. sSR.ulidShadow);
  746. MyPrintf(L" Status=0x%x RootStatus=0x%x "
  747. L"HntFlgs=0x%x HntPri=0x%x Attr=0x%x\r\n",
  748. sSR.uStatus,
  749. (unsigned)(sSR.usRootStatus),
  750. (unsigned)(sSR.uchHintFlags),
  751. (unsigned)(sSR.uchHintPri),
  752. sSR.dwFileAttrib);
  753. memset(rgwch, 0, sizeof(rgwch));
  754. MyPrintf(
  755. L"\r\n"
  756. L"(S)tatus, "
  757. L"(R)ootStatus, "
  758. L"Hnt(F)lgs , "
  759. L"Hnt(P)ri, "
  760. L"(A)ttr , "
  761. L"e(X)it "
  762. L":");
  763. if (!fgetws(rgwch, sizeof(rgwch)/sizeof(WCHAR), stdin))
  764. break;
  765. MyPrintf(L"\r\n");
  766. iRes = EditShareFunc(rgwch, &sSR);
  767. if (iRes == 0) {
  768. break;
  769. } else if (iRes == 1) {
  770. fseek(fp, ftell(fp) - sizeof(SHAREREC), SEEK_SET);
  771. fwrite(&sSR, sizeof(SHAREREC), 1, fp);
  772. }
  773. } while (1);
  774. }
  775. }
  776. MyPrintf(L"\r\n");
  777. }
  778. bailout:
  779. if (fp)
  780. fclose(fp);
  781. }
  782. LONG
  783. EditShareFunc(
  784. PWSTR lpBuff,
  785. SHAREREC *sSR)
  786. {
  787. WCHAR wch;
  788. ULONG NewStatus;
  789. ULONG NewRootStatus;
  790. ULONG NewHntFlgs;
  791. ULONG NewHntPri;
  792. ULONG NewAttr;
  793. LONG cnt;
  794. // Tristate return:
  795. // 0 -> exit
  796. // 1 -> write updated sSR
  797. // 2 -> don't write updated sSR
  798. // Chop leading blanks
  799. if (lpBuff != NULL)
  800. while (*lpBuff != L'\0' && *lpBuff == L' ')
  801. lpBuff++;
  802. cnt = swscanf(lpBuff, L"%c", &wch);
  803. if (!cnt)
  804. return 0;
  805. switch (wch) {
  806. // Edit status
  807. case L's':
  808. case L'S':
  809. cnt = swscanf(lpBuff, L"%c%x", &wch, &NewStatus);
  810. if (cnt != 2)
  811. return 2;
  812. MyPrintf(L"Status 0x%x -> 0x%x\r\n", (ULONG)sSR->uStatus, NewStatus);
  813. sSR->uStatus = (USHORT)NewStatus;
  814. break;
  815. // Edit RootStatus
  816. case L'r':
  817. case L'R':
  818. cnt = swscanf(lpBuff, L"%c%x", &wch, &NewRootStatus);
  819. if (cnt != 2)
  820. return 2;
  821. MyPrintf(L"RootStatus 0x%x -> 0x%x\r\n", (ULONG)sSR->usRootStatus, NewRootStatus);
  822. sSR->usRootStatus = (USHORT)NewRootStatus;
  823. break;
  824. // Edit HntFlgs
  825. case L'f':
  826. case L'F':
  827. cnt = swscanf(lpBuff, L"%c%x", &wch, &NewHntFlgs);
  828. if (cnt != 2)
  829. return 2;
  830. MyPrintf(L"HntFlgs 0x%x -> 0x%x\r\n", (ULONG)sSR->uchHintFlags, NewHntFlgs);
  831. sSR->uchHintFlags = (char)NewHntFlgs;
  832. break;
  833. // Edit HntPri
  834. case L'p':
  835. case L'P':
  836. cnt = swscanf(lpBuff, L"%c%x", &wch, &NewHntPri);
  837. if (cnt != 2)
  838. return 2;
  839. MyPrintf(L"HntPri 0x%x -> 0x%x\r\n", (ULONG)sSR->uchHintPri, NewHntPri);
  840. sSR->uchHintPri = (char)NewHntPri;
  841. break;
  842. // Edit attrib
  843. case L'a':
  844. case L'A':
  845. cnt = swscanf(lpBuff, L"%c%x", &wch, &NewAttr);
  846. if (cnt != 2)
  847. return 2;
  848. MyPrintf(L"Attrib 0x%x -> 0x%x\r\n", sSR->dwFileAttrib, NewAttr);
  849. sSR->dwFileAttrib = NewAttr;
  850. break;
  851. // Exit
  852. case L'x':
  853. case L'X':
  854. return 0;
  855. }
  856. return 1;
  857. }
  858. VOID
  859. FormNameStringDB(
  860. PWSTR lpdbID,
  861. ULONG ulidFile,
  862. PWSTR lpName)
  863. {
  864. PWSTR lp;
  865. WCHAR wchSubdir;
  866. // Prepend the local path
  867. wcscpy(lpName, lpdbID);
  868. wcscat(lpName, Backslash);
  869. // Bump the pointer appropriately
  870. lp = lpName + wcslen(lpName);
  871. wchSubdir = CSCDbSubdirSecondChar(ulidFile);
  872. // sprinkle the user files in one of the subdirectories
  873. if (wchSubdir) {
  874. // now append the subdirectory
  875. *lp++ = CSCDbSubdirFirstChar();
  876. *lp++ = wchSubdir;
  877. *lp++ = L'\\';
  878. }
  879. HexToA(ulidFile, lp, 8);
  880. lp += 8;
  881. *lp = 0;
  882. }
  883. LONG
  884. HexToA(
  885. ULONG ulHex,
  886. PWSTR lpName,
  887. LONG count)
  888. {
  889. int i;
  890. PWSTR lp = lpName + count - 1;
  891. WCHAR wch;
  892. for (i = 0; i < count; ++i) {
  893. wch = (WCHAR)(ulHex & 0xf) + L'0';
  894. if (wch > '9')
  895. wch += 7; // A becomes '0' + A + 7 which is 'A'
  896. *lp = wch;
  897. --lp;
  898. ulHex >>= 4;
  899. }
  900. *(lpName+count) = '\0';
  901. return 0;
  902. }
  903. BOOL
  904. FindAncestor(
  905. ULONG ulid,
  906. ULONG *lpulidDir)
  907. {
  908. ULONG ulRec = RecFromInode(ulid);
  909. FILE *fp= (FILE *)NULL;
  910. QHEADER sQH;
  911. QREC sQR;
  912. BOOL fRet = FALSE;
  913. *lpulidDir = 0;
  914. FormNameStringDB(DbDir, ULID_PQ, Name);
  915. if (fp = _wfopen(Name, L"rb")) {
  916. if (fread(&sQH, sizeof(QHEADER), 1, fp) != 1) {
  917. MyPrintf(L"Error reading PQ header \r\n");
  918. goto bailout;
  919. }
  920. fseek(fp, ((ulRec-1) * sizeof(QREC))+sizeof(QHEADER), SEEK_SET);
  921. if (fread(&sQR, sizeof(QREC), 1, fp)!=1)
  922. goto bailout;
  923. *lpulidDir = sQR.ulidDir;
  924. fRet = TRUE;
  925. }
  926. bailout:
  927. if (fp)
  928. fclose(fp);
  929. return fRet;
  930. }
  931. LONG
  932. RoughCompareWideStringWithAnsiString(
  933. PWSTR lpSrcString,
  934. USHORT *lpwDstString,
  935. LONG cntMax)
  936. {
  937. WCHAR wch;
  938. USHORT uch;
  939. LONG i;
  940. for (i = 0; i < cntMax; ++i) {
  941. wch = *lpSrcString++;
  942. uch = *lpwDstString++;
  943. wch = _wtoupper(wch);
  944. uch = _wtoupper(uch);
  945. if (!wch) {
  946. return 0;
  947. }
  948. if (wch != uch) {
  949. return (uch - wch);
  950. }
  951. }
  952. if (i == cntMax) {
  953. return 0;
  954. }
  955. return 1; // this should never occur
  956. }
  957. /*++
  958. DBCSC_BitmapIsMarked()
  959. Routine Description:
  960. Arguments:
  961. Returns:
  962. -1 if lpbitmap is NULL or bitoffset is larger than the bitmap
  963. TRUE if the bit is marked
  964. FALSE if the bit is unmarked
  965. Notes:
  966. --*/
  967. int
  968. DBCSC_BitmapIsMarked(
  969. LPCSC_BITMAP_DB lpbitmap,
  970. DWORD bitoffset)
  971. {
  972. DWORD DWORDnum;
  973. DWORD bitpos;
  974. if (lpbitmap == NULL)
  975. return -1;
  976. if (bitoffset >= lpbitmap->bitmapsize)
  977. return -1;
  978. DWORDnum = bitoffset/(8*sizeof(DWORD));
  979. bitpos = 1 << bitoffset%(8*sizeof(DWORD));
  980. if (lpbitmap->bitmap[DWORDnum] & bitpos)
  981. return TRUE;
  982. return FALSE;
  983. }
  984. /*++
  985. DBCSC_BitmapAppendStreamName()
  986. Routine Description:
  987. Appends the CSC stream name to the existing path/file name fname.
  988. Arguments:
  989. fname is the sting buffer containing the path/file.
  990. bufsize is the buffer size.
  991. Returns:
  992. TRUE if append successful.
  993. FALSE if buffer is too small or other errors.
  994. Notes:
  995. Unicode strings only.
  996. --*/
  997. int
  998. DBCSC_BitmapAppendStreamName(
  999. PWCHAR fname,
  1000. DWORD bufsize)
  1001. {
  1002. if ((wcslen(fname) + wcslen(CscBmpAltStrmName) + 1) > bufsize)
  1003. return FALSE;
  1004. wcscat(fname, CscBmpAltStrmName);
  1005. return TRUE;
  1006. }
  1007. /*++
  1008. DBCSC_BitmapRead()
  1009. Routine Description:
  1010. Reads the on-disk bitmap file, and if it exists, is not in use and valid,
  1011. store it in *lplpbitmap. If *lplpbitmap is NULL allocate a new
  1012. bitmap data structure. Otherwise, if *lplpbitmap is not NULL, the
  1013. existing bitmap will be deleted and assigned the on-disk bitmap
  1014. file.
  1015. Arguments:
  1016. filename is the file that contains the bitmap. If read from a
  1017. stream, append the stream name before passing the filename in. The
  1018. filename is used as is and no checking of validity of the name is
  1019. performed. For default stream name, append the global LPSTR
  1020. CscBmpAltStrmName.
  1021. Returns:
  1022. 1 if read successful
  1023. 0 if lplpbitmap is NULL
  1024. -1 if error in disk operation (open/read), memory allocating error,
  1025. or invalid bitmap file format.
  1026. -2 if bitmap not exist
  1027. Notes:
  1028. CODE.IMPROVEMENT design a better error message propagation mechanism.
  1029. Bitmap open for exclusive access.
  1030. --*/
  1031. int
  1032. DBCSC_BitmapRead(
  1033. LPCSC_BITMAP_DB *lplpbitmap,
  1034. LPCTSTR filename)
  1035. {
  1036. CscBmpFileHdr hdr;
  1037. HANDLE bitmapFile;
  1038. DWORD bytesRead;
  1039. DWORD bitmapByteSize;
  1040. DWORD * bitmapBuf = NULL;
  1041. DWORD errCode;
  1042. int ret = 1;
  1043. if (fSwDebug)
  1044. MyPrintf(L"BitmapRead(%ws)\r\n", filename);
  1045. if (lplpbitmap == NULL)
  1046. return 0;
  1047. bitmapFile = CreateFile(
  1048. filename,
  1049. GENERIC_READ,
  1050. 0, // No sharing; exclusive
  1051. NULL,
  1052. OPEN_EXISTING,
  1053. FILE_ATTRIBUTE_NORMAL,
  1054. NULL);
  1055. if (bitmapFile == INVALID_HANDLE_VALUE) {
  1056. errCode = GetLastError();
  1057. if (fSwDebug)
  1058. MyPrintf(L"BitmapRead!Createfile error %d\r\n", errCode);
  1059. if (errCode == ERROR_FILE_NOT_FOUND) {
  1060. // File does not exist
  1061. return -2;
  1062. }
  1063. return -1;
  1064. }
  1065. if (!ReadFile(
  1066. bitmapFile,
  1067. &hdr,
  1068. sizeof(CscBmpFileHdr),
  1069. &bytesRead,
  1070. NULL)
  1071. ) {
  1072. if (fSwDebug)
  1073. MyPrintf(L"BitmapRead!ReadFile of header error %d\r\n", GetLastError());
  1074. ret = -1;
  1075. goto CLOSEFILE;
  1076. }
  1077. MyPrintf(
  1078. L"---Header---\r\n"
  1079. L"MagicNum: 0x%x\r\n"
  1080. L"inuse: 0x%x\r\n"
  1081. L"valid: 0x%x\r\n"
  1082. L"sizeinbits:0x%x\r\n"
  1083. L"numDWORDS:0x%x\r\n",
  1084. hdr.magicnum,
  1085. hdr.inuse,
  1086. hdr.valid,
  1087. hdr.sizeinbits,
  1088. hdr.numDWORDs);
  1089. if (bytesRead != sizeof(CscBmpFileHdr)) {
  1090. if (fSwDebug)
  1091. MyPrintf(L"BitmapRead!ReadFile bytesRead != sizeof(CscBmpFileHdr).\r\n");
  1092. ret = -1;
  1093. goto CLOSEFILE;
  1094. }
  1095. if (hdr.magicnum != MAGICNUM) {
  1096. if (fSwDebug)
  1097. MyPrintf(L"BitmapRead!ReadFile hdr.magicnum != MAGICNUM.\r\n");
  1098. ret = -1;
  1099. goto CLOSEFILE;
  1100. }
  1101. if (!hdr.valid) {
  1102. if (fSwDebug)
  1103. MyPrintf(L"BitmapRead!ReadFile !hdr.valid.\r\n");
  1104. ret = -1;
  1105. goto CLOSEFILE;
  1106. }
  1107. if (hdr.inuse) {
  1108. if (fSwDebug)
  1109. MyPrintf(L"BitmapRead!ReadFile hdr.inuse.\r\n");
  1110. ret = -1;
  1111. goto CLOSEFILE;
  1112. }
  1113. if (hdr.sizeinbits > 0) {
  1114. bitmapByteSize = hdr.numDWORDs*sizeof(DWORD);
  1115. bitmapBuf = (DWORD *)malloc(bitmapByteSize);
  1116. if (!bitmapBuf) {
  1117. if (fSwDebug)
  1118. MyPrintf(L"BitmapRead!malloc failed\r\n");
  1119. ret = -1;
  1120. goto CLOSEFILE;
  1121. }
  1122. if (!ReadFile(
  1123. bitmapFile,
  1124. bitmapBuf,
  1125. bitmapByteSize,
  1126. &bytesRead,
  1127. NULL)
  1128. ) {
  1129. if (fSwDebug)
  1130. MyPrintf(L"BitmapRead!ReadFile of bitmap error %d\r\n", GetLastError());
  1131. ret = -1;
  1132. goto CLOSEFILE;
  1133. }
  1134. if (bytesRead != bitmapByteSize) {
  1135. if (fSwDebug)
  1136. MyPrintf(
  1137. L"BitmapRead!ReadFile wrong size (%d vs %d).\r\n",
  1138. bytesRead,
  1139. bitmapByteSize);
  1140. ret = -1;
  1141. goto CLOSEFILE;
  1142. }
  1143. }
  1144. if (*lplpbitmap) {
  1145. // bitmap exist, dump old and create new
  1146. if ((*lplpbitmap)->bitmap)
  1147. free((*lplpbitmap)->bitmap);
  1148. (*lplpbitmap)->bitmap = bitmapBuf;
  1149. (*lplpbitmap)->numDWORD = hdr.numDWORDs;
  1150. (*lplpbitmap)->bitmapsize = hdr.sizeinbits;
  1151. } else {
  1152. // bitmap not exist, create brand new
  1153. *lplpbitmap = (LPCSC_BITMAP_DB)malloc(sizeof(CSC_BITMAP_DB));
  1154. if (!(*lplpbitmap)) {
  1155. // Error in memory allocation
  1156. ret = -1;
  1157. goto CLOSEFILE;
  1158. }
  1159. (*lplpbitmap)->bitmap = bitmapBuf;
  1160. (*lplpbitmap)->numDWORD = hdr.numDWORDs;
  1161. (*lplpbitmap)->bitmapsize = hdr.sizeinbits;
  1162. }
  1163. CLOSEFILE:
  1164. CloseHandle(bitmapFile);
  1165. if(ret = -1 && bitmapBuf != NULL){
  1166. free(bitmapBuf);
  1167. }
  1168. return ret;
  1169. }
  1170. /*++
  1171. DBCSC_BitmapOutput()
  1172. Routine Description:
  1173. Outputs the passed in bitmap to the ouput file stream outStrm
  1174. Arguments:
  1175. Returns:
  1176. Notes:
  1177. --*/
  1178. void
  1179. DBCSC_BitmapOutput(
  1180. FILE * outStrm,
  1181. LPCSC_BITMAP_DB lpbitmap)
  1182. {
  1183. DWORD i;
  1184. if (lpbitmap == NULL) {
  1185. MyPrintf(L"lpbitmap is NULL\r\n");
  1186. return;
  1187. }
  1188. MyPrintf(L"lpbitmap 0x%08x, bitmapsize 0x%x numDWORD 0x%x\r\n",
  1189. (ULONG_PTR)lpbitmap, lpbitmap->bitmapsize, lpbitmap->numDWORD);
  1190. MyPrintf(L"bitmap |0/5 |1/6 |2/7 |3/8 |4/9\r\n");
  1191. MyPrintf(L"number |01234|56789|01234|56789|01234|56789|01234|56789|01234|56789");
  1192. for (i = 0; i < lpbitmap->bitmapsize; i++) {
  1193. if ((i % 50) == 0)
  1194. MyPrintf(L"\r\n%08d", i);
  1195. if ((i % 5) == 0)
  1196. MyPrintf(L"|");
  1197. MyPrintf(L"%1d", DBCSC_BitmapIsMarked(lpbitmap, i));
  1198. }
  1199. MyPrintf(L"\r\n");
  1200. }
  1201. DWORD
  1202. DumpBitMap(
  1203. LPWSTR lpszTempName)
  1204. {
  1205. WCHAR lpszBitMapName[MAX_PATH];
  1206. LPCSC_BITMAP_DB lpbitmap = NULL;
  1207. DWORD dwError = ERROR_SUCCESS;
  1208. wcscpy(lpszBitMapName,lpszTempName);
  1209. DBCSC_BitmapAppendStreamName(lpszBitMapName, MAX_PATH);
  1210. // read bitmap
  1211. switch(DBCSC_BitmapRead(&lpbitmap, lpszBitMapName)) {
  1212. case 1:
  1213. // Print the bitmap associated if any
  1214. MyPrintf(L"\r\n");
  1215. DBCSC_BitmapOutput(stdout, lpbitmap);
  1216. MyPrintf(L"\r\n");
  1217. // if bitmap opened delete bitmap
  1218. // DBCSC_BitmapDelete(&lpbitmap);
  1219. break;
  1220. case -1:
  1221. MyPrintf(L"Error reading bitmap file %ws or bitmap invalid\r\n", lpszBitMapName);
  1222. dwError = ERROR_FILE_NOT_FOUND;
  1223. break;
  1224. case -2:
  1225. MyPrintf(L"No CSCBitmap\n");
  1226. dwError = ERROR_FILE_NOT_FOUND;
  1227. break;
  1228. case 0:
  1229. default:
  1230. MyPrintf(L"Something strange going on with bitmap printing...\r\n");
  1231. dwError = ERROR_FILE_NOT_FOUND;
  1232. break;
  1233. }
  1234. return dwError;
  1235. }
  1236. #endif // CSCUTIL_INTERNAL