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
1417 lines
40 KiB
#define UNICODE
|
|
#define PUBLIC
|
|
#define PRIVATE
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <memory.h>
|
|
#include <string.h>
|
|
#include <windows.h>
|
|
#include <conio.h>
|
|
#include <share.h>
|
|
#include <dos.h>
|
|
#include <sddl.h>
|
|
#include "cscapi.h"
|
|
#include "csc_bmpc.h"
|
|
#pragma pack (1)
|
|
|
|
#include "struct.h"
|
|
|
|
|
|
#define MAX_PQ_PER_PAGE 10
|
|
#define MAX_SHARES_PER_PAGE 6
|
|
#define MAX_FILE_PER_PAGE 4
|
|
#define MAX_INODES_PER_PAGE 15
|
|
|
|
#define _wtoupper(x) ( ( ((x)>='a')&&((x)<='z') ) ? ((x)-'a'+'A'):(x))
|
|
|
|
typedef PVOID CSCHFILE;
|
|
|
|
#include "shdcom.h"
|
|
#include "cscsec.h"
|
|
|
|
#define ESC 0x1b
|
|
|
|
#include "record.h"
|
|
|
|
#define InodeFromRec(ulRec, fFile) ((ulRec+ULID_FIRST_USER_DIR-1) | ((fFile)?0x80000000:0))
|
|
#define RecFromInode(hShadow) ((hShadow & 0x7fffffff) - (ULID_FIRST_USER_DIR-1))
|
|
|
|
WCHAR rgwch[256];
|
|
WCHAR rgPrint[1024];
|
|
WCHAR rgwchPar[256];
|
|
|
|
WCHAR Shadow[] = L"\\WINDOWS\\CSC";
|
|
WCHAR Backslash[] = L"\\";
|
|
WCHAR DbDir[256]; // shadow database
|
|
WCHAR Name[MAX_PATH]; // working buffer
|
|
|
|
extern BOOLEAN fSwDebug;
|
|
|
|
// The _DB is used to distinguish this from the kernel mode CSC_BITMAP
|
|
// or the usermode _U
|
|
|
|
typedef struct _CSC_BITMAP_DB {
|
|
DWORD bitmapsize; // size in bits. How many bits effective in the bitmap
|
|
DWORD numDWORD; // how many DWORDs to accomodate the bitmap */
|
|
LPDWORD bitmap; // The bitmap itself
|
|
} CSC_BITMAP_DB, *LPCSC_BITMAP_DB, *PCSC_BITMAP_DB;
|
|
|
|
// append this to inode file name to get the stream name
|
|
PWCHAR CscBmpAltStrmName = L":cscbmp";
|
|
|
|
LONG DispFunc(PWSTR);
|
|
LONG EditFileFunc(PWSTR, FILEREC *);
|
|
LONG EditShareFunc(PWSTR, SHAREREC *);
|
|
VOID DisplayShares(PWSTR);
|
|
VOID DisplayInodes(VOID);
|
|
VOID DisplayPriorityQ(VOID);
|
|
VOID DisplaySids(VOID);
|
|
VOID DisplayFile(ULONG ulid, PWSTR, BOOL fForce);
|
|
VOID EditFile(ULONG ulid);
|
|
VOID EditShare(ULONG ulid);
|
|
LONG HexToA(ULONG, PWSTR, LONG);
|
|
|
|
// From recordse.c
|
|
#define CSC_NUMBER_OF_SIDS_OFFSET (0x0)
|
|
#define CSC_SID_SIZES_OFFSET (CSC_NUMBER_OF_SIDS_OFFSET + sizeof(ULONG))
|
|
|
|
VOID
|
|
FormNameStringDB(
|
|
PWSTR lpdbID,
|
|
ULONG ulidFile,
|
|
PWSTR lpName);
|
|
|
|
BOOL
|
|
FindAncestor(
|
|
ULONG ulid,
|
|
ULONG *lpulidDir);
|
|
|
|
LONG
|
|
RoughCompareWideStringWithAnsiString(
|
|
PWSTR lpSrcString,
|
|
USHORT *lpwDstString,
|
|
LONG cntMax);
|
|
|
|
PWSTR
|
|
ConvertGmtTimeToString(
|
|
FILETIME Time,
|
|
PWSTR OutputBuffer);
|
|
|
|
int
|
|
DBCSC_BitmapIsMarked(
|
|
LPCSC_BITMAP_DB lpbitmap,
|
|
DWORD bitoffset);
|
|
|
|
int
|
|
DBCSC_BitmapAppendStreamName(
|
|
PWCHAR fname,
|
|
DWORD bufsize);
|
|
|
|
int
|
|
DBCSC_BitmapRead(
|
|
LPCSC_BITMAP_DB *lplpbitmap,
|
|
LPCTSTR filename);
|
|
|
|
VOID
|
|
DBCSC_BitmapOutput(
|
|
FILE *outStrm,
|
|
LPCSC_BITMAP_DB lpbitmap);
|
|
|
|
#if defined(CSCUTIL_INTERNAL)
|
|
CmdDb(PWSTR DbArg)
|
|
{
|
|
BOOL fRet;
|
|
DWORD junk;
|
|
unsigned uAttr;
|
|
int iRet = -1;
|
|
if (DbArg == NULL) {
|
|
fRet = CSCGetSpaceUsageW(
|
|
DbDir,
|
|
sizeof(DbDir)/sizeof(WCHAR),
|
|
&junk,
|
|
&junk,
|
|
&junk,
|
|
&junk,
|
|
&junk,
|
|
&junk);
|
|
if (fRet == FALSE)
|
|
wcscpy(DbDir, Shadow);
|
|
} else {
|
|
wcscpy(DbDir, DbArg);
|
|
}
|
|
if((uAttr = GetFileAttributesW(DbDir)) == 0xffffffff) {
|
|
MyPrintf(L"Error accessing directory %ws \r\n", DbDir);
|
|
} else if (!(uAttr & _A_SUBDIR)) {
|
|
MyPrintf(L"%ws is not a directory\r\n", DbDir);
|
|
} else {
|
|
do {
|
|
memset(rgwch, 0, sizeof(rgwch));
|
|
MyPrintf(
|
|
L"\r\n"
|
|
L"(S)hares [name], "
|
|
L"Pri(Q), "
|
|
L"(O)wner, "
|
|
L"(F)ile inode# [name], "
|
|
L"(E)dit inode#, "
|
|
L"e(D)it share#, "
|
|
L"e(X)it "
|
|
L":");
|
|
if (!fgetws(rgwch, sizeof(rgwch)/sizeof(WCHAR), stdin))
|
|
break;
|
|
MyPrintf(L"\r\n");
|
|
if (DispFunc(rgwch) == 0)
|
|
break;
|
|
} while (1);
|
|
iRet = 0;
|
|
}
|
|
return (iRet);
|
|
}
|
|
|
|
LONG
|
|
DispFunc(PWSTR lpBuff)
|
|
{
|
|
WCHAR wch;
|
|
ULONG ulid;
|
|
LONG cnt;
|
|
|
|
// Chop leading blanks
|
|
if (lpBuff != NULL)
|
|
while (*lpBuff != L'\0' && *lpBuff == L' ')
|
|
lpBuff++;
|
|
|
|
cnt = swscanf(lpBuff, L"%c", &wch);
|
|
|
|
if (!cnt)
|
|
return 0;
|
|
|
|
switch (wch) {
|
|
// Display shares database
|
|
case L's':
|
|
case L'S':
|
|
cnt = swscanf(lpBuff, L"%c%ws", &wch, rgwchPar);
|
|
DisplayShares((cnt==2) ? rgwchPar : NULL);
|
|
break;
|
|
// display priority Q database
|
|
case L'q':
|
|
case L'Q':
|
|
DisplayPriorityQ();
|
|
break;
|
|
case L'o':
|
|
case L'O':
|
|
DisplaySids();
|
|
break;
|
|
case L'f':
|
|
case L'F':
|
|
cnt = swscanf(lpBuff, L"%c%x%ws", &wch, &ulid, rgwchPar);
|
|
if (cnt==2) {
|
|
// display Inode file
|
|
DisplayFile(ulid, NULL, (wch == 'F') ? TRUE : FALSE);
|
|
} else if (cnt==3) {
|
|
MyPrintf(L"Looking for %ws in 0x%x \r\n", rgwchPar, ulid);
|
|
// display Inode file
|
|
DisplayFile(ulid, rgwchPar, (wch == 'F') ? TRUE : FALSE);
|
|
}
|
|
break;
|
|
case L'e':
|
|
case L'E':
|
|
cnt = swscanf(lpBuff, L"%c%x%ws", &wch, &ulid, rgwchPar);
|
|
if (cnt==2) {
|
|
// display Inode file
|
|
EditFile(ulid);
|
|
}
|
|
break;
|
|
case L'd':
|
|
case L'D':
|
|
cnt = swscanf(lpBuff, L"%c%x%ws", &wch, &ulid, rgwchPar);
|
|
if (cnt==2) {
|
|
// display Inode file
|
|
EditShare(ulid);
|
|
}
|
|
break;
|
|
case L'x':
|
|
case L'X':
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
VOID
|
|
DisplaySecurityContext2(
|
|
PWSTR pSecurityDescriptor,
|
|
LPRECORDMANAGER_SECURITY_CONTEXT pSecurityContext)
|
|
{
|
|
PCACHED_SECURITY_INFORMATION pCachedSecurityInformation;
|
|
BOOL fGotOne = FALSE;
|
|
ULONG i;
|
|
|
|
pCachedSecurityInformation = (PCACHED_SECURITY_INFORMATION)pSecurityContext;
|
|
|
|
for (i = 0; i < MAXIMUM_NUMBER_OF_USERS; i++) {
|
|
CSC_SID_INDEX SidIndex;
|
|
|
|
SidIndex = pCachedSecurityInformation->AccessRights[i].SidIndex;
|
|
if (SidIndex != CSC_INVALID_SID_INDEX) {
|
|
fGotOne = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (fGotOne == FALSE)
|
|
return;
|
|
|
|
MyPrintf(L"%ws Security: ", pSecurityDescriptor);
|
|
for (i = 0; i < MAXIMUM_NUMBER_OF_USERS; i++) {
|
|
CSC_SID_INDEX SidIndex;
|
|
|
|
SidIndex = pCachedSecurityInformation->AccessRights[i].SidIndex;
|
|
if (SidIndex == CSC_INVALID_SID_INDEX) {
|
|
continue;
|
|
}else if (SidIndex == CSC_GUEST_SID_INDEX) {
|
|
MyPrintf(L"(G:0x%x)",
|
|
pCachedSecurityInformation->AccessRights[i].MaximalRights);
|
|
} else {
|
|
MyPrintf(L"(0x%x:0x%x)",
|
|
SidIndex,
|
|
pCachedSecurityInformation->AccessRights[i].MaximalRights);
|
|
}
|
|
}
|
|
MyPrintf(L"\r\n");
|
|
}
|
|
|
|
VOID
|
|
DisplayShares(PWSTR ShareName)
|
|
{
|
|
FILE *fp= NULL;
|
|
SHAREHEADER sSH;
|
|
SHAREREC sSR;
|
|
ULONG ulrec = 0;
|
|
LONG count = 0;
|
|
WCHAR TimeBuf1[30];
|
|
WCHAR TimeBuf2[30];
|
|
|
|
FormNameStringDB(DbDir, ULID_SHARE, Name);
|
|
if (fp = _wfopen(Name, L"rb")) {
|
|
if (fread(&sSH, sizeof(SHAREHEADER), 1, fp) != 1) {
|
|
MyPrintf(L"Error reading server header \r\n");
|
|
goto bailout;
|
|
}
|
|
|
|
MyPrintf(L"Header: Flags=%x Version=%lx Records=%ld Size=%d \r\n",
|
|
sSH.uFlags, sSH.ulVersion, sSH.ulRecords, sSH.uRecSize);
|
|
|
|
MyPrintf(L"Store(Max): Size=%d Dirs=%d Files=%d\r\n",
|
|
sSH.sMax.ulSize,
|
|
sSH.sMax.ucntDirs,
|
|
sSH.sMax.ucntFiles);
|
|
MyPrintf(L"Store(Cur): Size=%d Dirs=%d Files=%d\r\n",
|
|
sSH.sCur.ulSize,
|
|
sSH.sCur.ucntDirs,
|
|
sSH.sCur.ucntFiles);
|
|
MyPrintf(L"\r\n");
|
|
|
|
for (ulrec = 1; fread(&sSR, sizeof(SHAREREC), 1, fp) == 1; ulrec++) {
|
|
if (sSR.uchType == (UCHAR)REC_DATA) {
|
|
if (ShareName != NULL) {
|
|
if (RoughCompareWideStringWithAnsiString(
|
|
ShareName,
|
|
sSR.rgPath,
|
|
sizeof(sSR.rgPath)/sizeof(WCHAR)-1)
|
|
) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
MyPrintf(L"%ws (0x%x) Root=0x%x\r\n",
|
|
sSR.rgPath,
|
|
ulrec,
|
|
sSR.ulidShadow);
|
|
MyPrintf(L" Status=0x%x RootStatus=0x%x "
|
|
L"HntFlgs=0x%x HntPri=0x%x Attr=0x%x\r\n",
|
|
sSR.uStatus,
|
|
(unsigned)(sSR.usRootStatus),
|
|
(unsigned)(sSR.uchHintFlags),
|
|
(unsigned)(sSR.uchHintPri),
|
|
sSR.dwFileAttrib);
|
|
|
|
ConvertGmtTimeToString(sSR.ftLastWriteTime, TimeBuf1);
|
|
ConvertGmtTimeToString(sSR.ftOrgTime, TimeBuf2);
|
|
MyPrintf(L" LastWriteTime: %ws Orgtime: %ws\r\n", TimeBuf1, TimeBuf2);
|
|
|
|
DisplaySecurityContext2(L" ShareLevel",&sSR.sShareSecurity);
|
|
DisplaySecurityContext2(L" Root ",&sSR.sRootSecurity);
|
|
MyPrintf(L"\r\n");
|
|
}
|
|
}
|
|
}
|
|
bailout:
|
|
if (fp)
|
|
fclose(fp);
|
|
}
|
|
|
|
VOID
|
|
DisplayPriorityQ(VOID)
|
|
{
|
|
FILE *fp= NULL;
|
|
QHEADER sQH;
|
|
QREC sQR;
|
|
ULONG ulRec = 1;
|
|
LONG count = 0;
|
|
|
|
FormNameStringDB(DbDir, ULID_PQ, Name);
|
|
if (fp = _wfopen(Name, L"rb")) {
|
|
if (fread(&sQH, sizeof(QHEADER), 1, fp) != 1) {
|
|
MyPrintf(L"Error reading PQ header \r\n");
|
|
goto bailout;
|
|
}
|
|
MyPrintf(L"Header: Flags=%x Version=%lx Records=%ld Size=%d head=%ld tail=%ld\r\n",
|
|
sQH.uchFlags,
|
|
sQH.ulVersion,
|
|
sQH.ulRecords,
|
|
sQH.uRecSize,
|
|
sQH.ulrecHead,
|
|
sQH.ulrecTail);
|
|
MyPrintf(L"\r\n");
|
|
MyPrintf(
|
|
L" REC SHARE DIR SHADOW STATUS PRI HINTFLGS HINTPRI PREV NEXT DIRENT\r\n");
|
|
for (ulRec = sQH.ulrecHead; ulRec;) {
|
|
fseek(fp, ((ulRec-1) * sizeof(QREC))+sizeof(QHEADER), SEEK_SET);
|
|
if (fread(&sQR, sizeof(QREC), 1, fp)!=1)
|
|
break;
|
|
MyPrintf(L"%5d %5x %8x %8x %8x %4d %8x %7d %5d %5d %6d\r\n",
|
|
ulRec,
|
|
sQR.ulidShare,
|
|
sQR.ulidDir,
|
|
sQR.ulidShadow,
|
|
sQR.usStatus,
|
|
(unsigned)(sQR.uchRefPri),
|
|
(unsigned)(sQR.uchHintFlags),
|
|
(unsigned)(sQR.uchHintPri),
|
|
sQR.ulrecPrev,
|
|
sQR.ulrecNext,
|
|
sQR.ulrecDirEntry);
|
|
++count;
|
|
ulRec = sQR.ulrecNext;
|
|
}
|
|
}
|
|
bailout:
|
|
if (fp)
|
|
fclose(fp);
|
|
}
|
|
|
|
VOID
|
|
DisplaySids(VOID)
|
|
{
|
|
DWORD Status = ERROR_SUCCESS;
|
|
ULONG SidOffset = 0;
|
|
ULONG NumberOfSids;
|
|
ULONG BytesRead;
|
|
ULONG i;
|
|
PCSC_SIDS pCscSids = NULL;
|
|
FILE *fp = NULL;
|
|
LPWSTR StringSid = NULL;
|
|
SID_NAME_USE SidUse;
|
|
BOOL bRet = FALSE;
|
|
DWORD cbAcctName;
|
|
DWORD cbDomainName;
|
|
WCHAR AcctName[MAX_PATH];
|
|
WCHAR DomainName[MAX_PATH];
|
|
|
|
FormNameStringDB(DbDir, ULID_SID_MAPPINGS, Name);
|
|
fp = _wfopen(Name, L"rb");
|
|
if (fp == NULL) {
|
|
MyPrintf(L"Error opening SID file\r\n");
|
|
goto bailout;
|
|
}
|
|
fseek(fp, CSC_NUMBER_OF_SIDS_OFFSET, SEEK_SET);
|
|
if (fread(&NumberOfSids, sizeof(NumberOfSids), 1, fp) != 1) {
|
|
MyPrintf(L"Error reading # SIDS\r\n");
|
|
goto bailout;
|
|
}
|
|
|
|
pCscSids = (PCSC_SIDS)malloc(sizeof(CSC_SIDS) + sizeof(CSC_SID) * NumberOfSids);
|
|
|
|
if (pCscSids == NULL) {
|
|
MyPrintf(L"Error allocating memory of SID array\n");
|
|
goto bailout;
|
|
}
|
|
|
|
pCscSids->MaximumNumberOfSids = NumberOfSids;
|
|
pCscSids->NumberOfSids = NumberOfSids;
|
|
|
|
for (i = 0; i < NumberOfSids; i++)
|
|
pCscSids->Sids[i].pSid = NULL;
|
|
|
|
fseek(fp, CSC_SID_SIZES_OFFSET, SEEK_SET);
|
|
if (fread(&pCscSids->Sids, sizeof(CSC_SID) * NumberOfSids, 1, fp) != 1) {
|
|
MyPrintf(L"Error reading SIDS\r\n");
|
|
goto bailout;
|
|
}
|
|
|
|
// The array structure has been initialized correctly. Each of the
|
|
// individual sids needs to be initialized.
|
|
SidOffset = CSC_SID_SIZES_OFFSET + sizeof(CSC_SID) * NumberOfSids;
|
|
|
|
for (i = 0; i < NumberOfSids; i++) {
|
|
pCscSids->Sids[i].pSid = malloc(pCscSids->Sids[i].SidLength);
|
|
if (pCscSids->Sids[i].pSid == NULL) {
|
|
MyPrintf(L"Error allocating memory of SID array\n");
|
|
goto bailout;
|
|
}
|
|
fseek(fp, SidOffset, SEEK_SET);
|
|
if (fread(pCscSids->Sids[i].pSid, pCscSids->Sids[i].SidLength, 1, fp) != 1) {
|
|
MyPrintf(L"Error reading SIDS\r\n");
|
|
goto bailout;
|
|
}
|
|
SidOffset += pCscSids->Sids[i].SidLength;
|
|
}
|
|
|
|
MyPrintf(L"MaximumNumberOfSids: %d\r\n"
|
|
L"NumberOfSids: %d\r\n",
|
|
pCscSids->MaximumNumberOfSids,
|
|
pCscSids->NumberOfSids);
|
|
for (i = 0; i < NumberOfSids; i++) {
|
|
StringSid = NULL;
|
|
if (ConvertSidToStringSid(pCscSids->Sids[i].pSid, &StringSid)) {
|
|
MyPrintf(L"---0x%x (%d)---\r\n"
|
|
L" SidLength: %d\r\n"
|
|
L" Sid: %ws\r\n",
|
|
i+1, i+1,
|
|
pCscSids->Sids[i].SidLength,
|
|
StringSid);
|
|
LocalFree(StringSid);
|
|
StringSid = NULL;
|
|
DomainName[0] = L'0';
|
|
AcctName[0] = L'0';
|
|
cbAcctName = sizeof(AcctName) / sizeof(WCHAR);
|
|
cbDomainName = sizeof(DomainName) / sizeof(WCHAR);
|
|
bRet = LookupAccountSid(
|
|
NULL,
|
|
pCscSids->Sids[i].pSid,
|
|
AcctName,
|
|
&cbAcctName,
|
|
DomainName,
|
|
&cbDomainName,
|
|
&SidUse);
|
|
if (bRet) {
|
|
MyPrintf(L" Name: %ws%ws%ws\r\n",
|
|
DomainName,
|
|
DomainName[0] ? L"\\" : L"",
|
|
AcctName);
|
|
} else {
|
|
MyPrintf(L" Name: <unknown>\r\n");
|
|
}
|
|
} else {
|
|
MyPrintf(L"ConvertSidToStringSid returned %d\r\n", GetLastError());
|
|
}
|
|
}
|
|
bailout:
|
|
if (fp)
|
|
fclose(fp);
|
|
}
|
|
|
|
VOID
|
|
DisplayFile(
|
|
ULONG ulid,
|
|
PWSTR lpwszName,
|
|
BOOL fForce)
|
|
{
|
|
FILE *fp= NULL;
|
|
FILEHEADER sFH;
|
|
FILEREC sFR;
|
|
LONG fLfn=0;
|
|
ULONG ulidDir=ulid;
|
|
LONG fPrintOvf = 0, count=0;
|
|
WCHAR strmPath[MAX_PATH];
|
|
LPCSC_BITMAP_DB lpbitmap = NULL;
|
|
WCHAR TimeBuf1[30];
|
|
WCHAR TimeBuf2[30];
|
|
|
|
if (IsLeaf(ulid)) {
|
|
if (!FindAncestor(ulid, &ulidDir))
|
|
return;
|
|
}
|
|
|
|
FormNameStringDB(DbDir, ulidDir, Name);
|
|
|
|
if (fp = _wfopen(Name, L"rb")) {
|
|
if (fread(&sFH, sizeof(FILEHEADER), 1, fp) != 1) {
|
|
MyPrintf(L"Error reading file header \r\n");
|
|
goto bailout;
|
|
}
|
|
|
|
|
|
if (ulid == ulidDir) {
|
|
MyPrintf(L"Header: Flags=%x Version=%lx Records=%ld Size=%d\r\n",
|
|
sFH.uchFlags, sFH.ulVersion, sFH.ulRecords, sFH.uRecSize);
|
|
MyPrintf(L"Header: bytes=%ld entries=%d Share=%ld Dir=%lx\r\n",
|
|
sFH.ulsizeShadow, sFH.ucShadows, sFH.ulidShare, sFH.ulidDir);
|
|
printf ("\r\n");
|
|
fPrintOvf = 1;
|
|
}
|
|
|
|
while (fread(&sFR, sizeof(FILEREC), 1, fp)==1) {
|
|
if (sFR.uchType != (unsigned char)REC_OVERFLOW) {
|
|
if (fLfn) {
|
|
if (ulidDir != ulid)
|
|
break;
|
|
}
|
|
fLfn = 0;
|
|
}
|
|
if (sFR.uchType==(unsigned char)REC_DATA) {
|
|
if (ulidDir != ulid) {
|
|
if (ulid != sFR.ulidShadow)
|
|
continue;
|
|
}
|
|
if (lpwszName) {
|
|
if (RoughCompareWideStringWithAnsiString(
|
|
lpwszName,
|
|
sFR.rgwName,
|
|
sizeof(sFR.rgw83Name)/sizeof(WCHAR)-1)
|
|
) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
fPrintOvf = 1;
|
|
MyPrintf(L"%ws (0x%x)\r\n", sFR.rgw83Name, sFR.ulidShadow);
|
|
if (fForce == TRUE) {
|
|
MyPrintf(L" Type=%c Flags=0x%x status=0x%x size=%ld attrib=0x%lx\r\n",
|
|
sFR.uchType,
|
|
(unsigned)sFR.uchFlags,
|
|
sFR.uStatus,
|
|
sFR.ulFileSize,
|
|
sFR.dwFileAttrib);
|
|
MyPrintf(L" PinFlags=0x%x PinCount=%d RefPri=%d OriginalInode=0x%0x\r\n",
|
|
(unsigned)(sFR.uchHintFlags),
|
|
(int)(sFR.uchHintPri),
|
|
(int)(sFR.uchRefPri),
|
|
sFR.ulidShadowOrg);
|
|
ConvertGmtTimeToString(sFR.ftLastWriteTime, TimeBuf1);
|
|
ConvertGmtTimeToString(sFR.ftOrgTime, TimeBuf2);
|
|
MyPrintf(L" LastWriteTime: %ws Orgtime: %ws\r\n", TimeBuf1, TimeBuf2);
|
|
if (sFR.rgwName[0]) {
|
|
MyPrintf(L" LFN:%ws", sFR.rgwName);
|
|
fLfn = 1;
|
|
}
|
|
|
|
MyPrintf(L"\r\n");
|
|
DisplaySecurityContext2(L" ",&sFR.Security);
|
|
|
|
if (ulidDir != ulid) {
|
|
MyPrintf(L" DirInode = 0x%x\r\n", ulidDir);
|
|
FormNameStringDB(DbDir, sFR.ulidShadow, strmPath);
|
|
DBCSC_BitmapAppendStreamName(strmPath, MAX_PATH);
|
|
// read bitmap
|
|
switch(DBCSC_BitmapRead(&lpbitmap, strmPath)) {
|
|
case 1:
|
|
// Print the bitmap associated if any
|
|
MyPrintf(L"\r\n");
|
|
DBCSC_BitmapOutput(stdout, lpbitmap);
|
|
MyPrintf(L"\r\n");
|
|
// if bitmap opened delete bitmap
|
|
// DBCSC_BitmapDelete(&lpbitmap);
|
|
break;
|
|
case -1:
|
|
MyPrintf(L"Error reading bitmap file %ws or bitmap invalid\r\n",
|
|
strmPath);
|
|
break;
|
|
case -2:
|
|
MyPrintf(L"No CSCBitmap\n");
|
|
break;
|
|
case 0:
|
|
default:
|
|
MyPrintf(L"Something strange going on with bitmap printing...\r\n");
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
MyPrintf(L"\r\n");
|
|
} else if (fPrintOvf && (sFR.uchType == (unsigned char)REC_OVERFLOW)) {
|
|
MyPrintf(L"(overflow) ");
|
|
MyPrintf(L"%ws\r\n\r\n", sFR.rgwOvf);
|
|
}
|
|
}
|
|
|
|
// do counting only when we are scanning the whole directory
|
|
if (!lpwszName && (ulid == ulidDir)) {
|
|
++count;
|
|
}
|
|
}
|
|
MyPrintf(L"\r\n");
|
|
}
|
|
bailout:
|
|
if (fp)
|
|
fclose(fp);
|
|
}
|
|
|
|
VOID
|
|
EditFile(
|
|
ULONG ulid)
|
|
{
|
|
FILE *fp= NULL;
|
|
FILEHEADER sFH;
|
|
FILEREC sFR;
|
|
ULONG ulidDir=ulid;
|
|
WCHAR TimeBuf1[30];
|
|
WCHAR TimeBuf2[30];
|
|
LONG iRes;
|
|
|
|
if (!IsLeaf(ulid)) {
|
|
MyPrintf(L"0x%x is a directory.\r\n", ulid);
|
|
return;
|
|
}
|
|
|
|
if (!FindAncestor(ulid, &ulidDir))
|
|
return;
|
|
|
|
FormNameStringDB(DbDir, ulidDir, Name);
|
|
|
|
if (fp = _wfopen(Name, L"rb+")) {
|
|
if (fread(&sFH, sizeof(FILEHEADER), 1, fp) != 1) {
|
|
MyPrintf(L"Error reading file header \r\n");
|
|
goto bailout;
|
|
}
|
|
|
|
while (fread(&sFR, sizeof(FILEREC), 1, fp)==1) {
|
|
if (sFR.uchType == (unsigned char)REC_OVERFLOW) {
|
|
continue;
|
|
}
|
|
if (sFR.uchType==(unsigned char)REC_DATA) {
|
|
if (ulid != sFR.ulidShadow)
|
|
continue;
|
|
do {
|
|
MyPrintf(L"---------------------------------------------\r\n");
|
|
MyPrintf(L"%ws (0x%x)\r\n", sFR.rgw83Name, sFR.ulidShadow);
|
|
|
|
MyPrintf(L" Type=%c Flags=0x%x status=0x%x size=%ld attrib=0x%lx\r\n",
|
|
sFR.uchType,
|
|
(unsigned)sFR.uchFlags,
|
|
sFR.uStatus,
|
|
sFR.ulFileSize,
|
|
sFR.dwFileAttrib);
|
|
MyPrintf(L" PinFlags=0x%x PinCount=%d RefPri=%d OriginalInode=0x%0x\r\n",
|
|
(unsigned)(sFR.uchHintFlags),
|
|
(int)(sFR.uchHintPri),
|
|
(int)(sFR.uchRefPri),
|
|
sFR.ulidShadowOrg);
|
|
ConvertGmtTimeToString(sFR.ftLastWriteTime, TimeBuf1);
|
|
ConvertGmtTimeToString(sFR.ftOrgTime, TimeBuf2);
|
|
MyPrintf(L" LastWriteTime: %ws Orgtime: %ws\r\n", TimeBuf1, TimeBuf2);
|
|
MyPrintf(L" DirInode = 0x%x\r\n", ulidDir);
|
|
|
|
memset(rgwch, 0, sizeof(rgwch));
|
|
MyPrintf(
|
|
L"\r\n"
|
|
L"(F)lags, "
|
|
L"(S)tatus, "
|
|
L"si(Z)e , "
|
|
L"(A)ttrib, "
|
|
L"e(X)it "
|
|
L":");
|
|
if (!fgetws(rgwch, sizeof(rgwch)/sizeof(WCHAR), stdin))
|
|
break;
|
|
MyPrintf(L"\r\n");
|
|
iRes = EditFileFunc(rgwch, &sFR);
|
|
if (iRes == 0) {
|
|
break;
|
|
} else if (iRes == 1) {
|
|
fseek(fp, ftell(fp) - sizeof(FILEREC), SEEK_SET);
|
|
fwrite(&sFR, sizeof(FILEREC), 1, fp);
|
|
}
|
|
} while (1);
|
|
}
|
|
}
|
|
MyPrintf(L"\r\n");
|
|
}
|
|
bailout:
|
|
if (fp)
|
|
fclose(fp);
|
|
}
|
|
|
|
LONG
|
|
EditFileFunc(
|
|
PWSTR lpBuff,
|
|
FILEREC *sFR)
|
|
{
|
|
WCHAR wch;
|
|
ULONG NewFlags;
|
|
ULONG NewStatus;
|
|
ULONG NewSize;
|
|
ULONG NewAttrib;
|
|
LONG cnt;
|
|
|
|
// Tristate return:
|
|
// 0 -> exit
|
|
// 1 -> write updated sFR
|
|
// 2 -> don't write updated sFR
|
|
|
|
// Chop leading blanks
|
|
if (lpBuff != NULL)
|
|
while (*lpBuff != L'\0' && *lpBuff == L' ')
|
|
lpBuff++;
|
|
|
|
cnt = swscanf(lpBuff, L"%c", &wch);
|
|
|
|
if (!cnt)
|
|
return 0;
|
|
|
|
switch (wch) {
|
|
// Edit flags
|
|
case L'f':
|
|
case L'F':
|
|
cnt = swscanf(lpBuff, L"%c%x", &wch, &NewFlags);
|
|
if (cnt != 2)
|
|
return 2;
|
|
MyPrintf(L"Flags 0x%x -> 0x%x\r\n", (unsigned)sFR->uchFlags, NewFlags);
|
|
sFR->uchFlags = (char)NewFlags;
|
|
break;
|
|
// Edit status
|
|
case L's':
|
|
case L'S':
|
|
cnt = swscanf(lpBuff, L"%c%x", &wch, &NewStatus);
|
|
if (cnt != 2)
|
|
return 2;
|
|
MyPrintf(L"Status 0x%x -> 0x%x\r\n", sFR->uStatus, NewStatus);
|
|
sFR->uStatus = (USHORT)NewStatus;
|
|
break;
|
|
// Edit size
|
|
case L'z':
|
|
case L'Z':
|
|
cnt = swscanf(lpBuff, L"%c%x", &wch, &NewSize);
|
|
if (cnt != 2)
|
|
return 2;
|
|
MyPrintf(L"Size 0x%x -> 0x%x\r\n", sFR->ulFileSize, NewSize);
|
|
sFR->ulFileSize = NewSize;
|
|
break;
|
|
// Edit attrib
|
|
case L'a':
|
|
case L'A':
|
|
cnt = swscanf(lpBuff, L"%c%x", &wch, &NewAttrib);
|
|
if (cnt != 2)
|
|
return 2;
|
|
MyPrintf(L"Attrib 0x%x -> 0x%x\r\n", sFR->dwFileAttrib, NewAttrib);
|
|
sFR->dwFileAttrib = NewAttrib;
|
|
break;
|
|
// Exit
|
|
case L'x':
|
|
case L'X':
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
VOID
|
|
EditShare(
|
|
ULONG ulid)
|
|
{
|
|
FILE *fp= NULL;
|
|
SHAREHEADER sSH;
|
|
SHAREREC sSR;
|
|
WCHAR TimeBuf1[30];
|
|
WCHAR TimeBuf2[30];
|
|
LONG iRes;
|
|
ULONG ulrec = 0;
|
|
|
|
FormNameStringDB(DbDir, ULID_SHARE, Name);
|
|
|
|
if (fp = _wfopen(Name, L"rb+")) {
|
|
if (fread(&sSH, sizeof(SHAREHEADER), 1, fp) != 1) {
|
|
MyPrintf(L"Error reading server header \r\n");
|
|
goto bailout;
|
|
}
|
|
|
|
for (ulrec = 1; fread(&sSR, sizeof(SHAREREC), 1, fp) == 1; ulrec++) {
|
|
if (sSR.uchType == (UCHAR)REC_DATA) {
|
|
if (ulid != ulrec)
|
|
continue;
|
|
do {
|
|
MyPrintf(L"---------------------------------------------\r\n");
|
|
|
|
MyPrintf(L"%ws (0x%x) Root=0x%x\r\n",
|
|
sSR.rgPath,
|
|
ulrec,
|
|
sSR.ulidShadow);
|
|
MyPrintf(L" Status=0x%x RootStatus=0x%x "
|
|
L"HntFlgs=0x%x HntPri=0x%x Attr=0x%x\r\n",
|
|
sSR.uStatus,
|
|
(unsigned)(sSR.usRootStatus),
|
|
(unsigned)(sSR.uchHintFlags),
|
|
(unsigned)(sSR.uchHintPri),
|
|
sSR.dwFileAttrib);
|
|
|
|
memset(rgwch, 0, sizeof(rgwch));
|
|
MyPrintf(
|
|
L"\r\n"
|
|
L"(S)tatus, "
|
|
L"(R)ootStatus, "
|
|
L"Hnt(F)lgs , "
|
|
L"Hnt(P)ri, "
|
|
L"(A)ttr , "
|
|
L"e(X)it "
|
|
L":");
|
|
if (!fgetws(rgwch, sizeof(rgwch)/sizeof(WCHAR), stdin))
|
|
break;
|
|
MyPrintf(L"\r\n");
|
|
iRes = EditShareFunc(rgwch, &sSR);
|
|
if (iRes == 0) {
|
|
break;
|
|
} else if (iRes == 1) {
|
|
fseek(fp, ftell(fp) - sizeof(SHAREREC), SEEK_SET);
|
|
fwrite(&sSR, sizeof(SHAREREC), 1, fp);
|
|
}
|
|
} while (1);
|
|
}
|
|
}
|
|
MyPrintf(L"\r\n");
|
|
}
|
|
bailout:
|
|
if (fp)
|
|
fclose(fp);
|
|
}
|
|
|
|
LONG
|
|
EditShareFunc(
|
|
PWSTR lpBuff,
|
|
SHAREREC *sSR)
|
|
{
|
|
WCHAR wch;
|
|
ULONG NewStatus;
|
|
ULONG NewRootStatus;
|
|
ULONG NewHntFlgs;
|
|
ULONG NewHntPri;
|
|
ULONG NewAttr;
|
|
LONG cnt;
|
|
|
|
// Tristate return:
|
|
// 0 -> exit
|
|
// 1 -> write updated sSR
|
|
// 2 -> don't write updated sSR
|
|
|
|
// Chop leading blanks
|
|
if (lpBuff != NULL)
|
|
while (*lpBuff != L'\0' && *lpBuff == L' ')
|
|
lpBuff++;
|
|
|
|
cnt = swscanf(lpBuff, L"%c", &wch);
|
|
|
|
if (!cnt)
|
|
return 0;
|
|
|
|
switch (wch) {
|
|
// Edit status
|
|
case L's':
|
|
case L'S':
|
|
cnt = swscanf(lpBuff, L"%c%x", &wch, &NewStatus);
|
|
if (cnt != 2)
|
|
return 2;
|
|
MyPrintf(L"Status 0x%x -> 0x%x\r\n", (ULONG)sSR->uStatus, NewStatus);
|
|
sSR->uStatus = (USHORT)NewStatus;
|
|
break;
|
|
// Edit RootStatus
|
|
case L'r':
|
|
case L'R':
|
|
cnt = swscanf(lpBuff, L"%c%x", &wch, &NewRootStatus);
|
|
if (cnt != 2)
|
|
return 2;
|
|
MyPrintf(L"RootStatus 0x%x -> 0x%x\r\n", (ULONG)sSR->usRootStatus, NewRootStatus);
|
|
sSR->usRootStatus = (USHORT)NewRootStatus;
|
|
break;
|
|
// Edit HntFlgs
|
|
case L'f':
|
|
case L'F':
|
|
cnt = swscanf(lpBuff, L"%c%x", &wch, &NewHntFlgs);
|
|
if (cnt != 2)
|
|
return 2;
|
|
MyPrintf(L"HntFlgs 0x%x -> 0x%x\r\n", (ULONG)sSR->uchHintFlags, NewHntFlgs);
|
|
sSR->uchHintFlags = (char)NewHntFlgs;
|
|
break;
|
|
// Edit HntPri
|
|
case L'p':
|
|
case L'P':
|
|
cnt = swscanf(lpBuff, L"%c%x", &wch, &NewHntPri);
|
|
if (cnt != 2)
|
|
return 2;
|
|
MyPrintf(L"HntPri 0x%x -> 0x%x\r\n", (ULONG)sSR->uchHintPri, NewHntPri);
|
|
sSR->uchHintPri = (char)NewHntPri;
|
|
break;
|
|
// Edit attrib
|
|
case L'a':
|
|
case L'A':
|
|
cnt = swscanf(lpBuff, L"%c%x", &wch, &NewAttr);
|
|
if (cnt != 2)
|
|
return 2;
|
|
MyPrintf(L"Attrib 0x%x -> 0x%x\r\n", sSR->dwFileAttrib, NewAttr);
|
|
sSR->dwFileAttrib = NewAttr;
|
|
break;
|
|
// Exit
|
|
case L'x':
|
|
case L'X':
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
VOID
|
|
FormNameStringDB(
|
|
PWSTR lpdbID,
|
|
ULONG ulidFile,
|
|
PWSTR lpName)
|
|
{
|
|
PWSTR lp;
|
|
WCHAR wchSubdir;
|
|
|
|
// Prepend the local path
|
|
wcscpy(lpName, lpdbID);
|
|
wcscat(lpName, Backslash);
|
|
|
|
// Bump the pointer appropriately
|
|
lp = lpName + wcslen(lpName);
|
|
|
|
wchSubdir = CSCDbSubdirSecondChar(ulidFile);
|
|
|
|
// sprinkle the user files in one of the subdirectories
|
|
if (wchSubdir) {
|
|
// now append the subdirectory
|
|
*lp++ = CSCDbSubdirFirstChar();
|
|
*lp++ = wchSubdir;
|
|
*lp++ = L'\\';
|
|
}
|
|
|
|
|
|
HexToA(ulidFile, lp, 8);
|
|
|
|
lp += 8;
|
|
*lp = 0;
|
|
}
|
|
|
|
LONG
|
|
HexToA(
|
|
ULONG ulHex,
|
|
PWSTR lpName,
|
|
LONG count)
|
|
{
|
|
int i;
|
|
PWSTR lp = lpName + count - 1;
|
|
WCHAR wch;
|
|
|
|
for (i = 0; i < count; ++i) {
|
|
wch = (WCHAR)(ulHex & 0xf) + L'0';
|
|
if (wch > '9')
|
|
wch += 7; // A becomes '0' + A + 7 which is 'A'
|
|
*lp = wch;
|
|
--lp;
|
|
ulHex >>= 4;
|
|
}
|
|
*(lpName+count) = '\0';
|
|
return 0;
|
|
}
|
|
|
|
BOOL
|
|
FindAncestor(
|
|
ULONG ulid,
|
|
ULONG *lpulidDir)
|
|
{
|
|
ULONG ulRec = RecFromInode(ulid);
|
|
FILE *fp= (FILE *)NULL;
|
|
QHEADER sQH;
|
|
QREC sQR;
|
|
BOOL fRet = FALSE;
|
|
|
|
*lpulidDir = 0;
|
|
|
|
FormNameStringDB(DbDir, ULID_PQ, Name);
|
|
if (fp = _wfopen(Name, L"rb")) {
|
|
if (fread(&sQH, sizeof(QHEADER), 1, fp) != 1) {
|
|
MyPrintf(L"Error reading PQ header \r\n");
|
|
goto bailout;
|
|
}
|
|
|
|
fseek(fp, ((ulRec-1) * sizeof(QREC))+sizeof(QHEADER), SEEK_SET);
|
|
|
|
if (fread(&sQR, sizeof(QREC), 1, fp)!=1)
|
|
goto bailout;
|
|
*lpulidDir = sQR.ulidDir;
|
|
fRet = TRUE;
|
|
}
|
|
bailout:
|
|
if (fp)
|
|
fclose(fp);
|
|
return fRet;
|
|
}
|
|
|
|
LONG
|
|
RoughCompareWideStringWithAnsiString(
|
|
PWSTR lpSrcString,
|
|
USHORT *lpwDstString,
|
|
LONG cntMax)
|
|
{
|
|
WCHAR wch;
|
|
USHORT uch;
|
|
LONG i;
|
|
|
|
for (i = 0; i < cntMax; ++i) {
|
|
wch = *lpSrcString++;
|
|
uch = *lpwDstString++;
|
|
wch = _wtoupper(wch);
|
|
uch = _wtoupper(uch);
|
|
|
|
if (!wch) {
|
|
return 0;
|
|
}
|
|
|
|
if (wch != uch) {
|
|
return (uch - wch);
|
|
}
|
|
}
|
|
if (i == cntMax) {
|
|
return 0;
|
|
}
|
|
|
|
return 1; // this should never occur
|
|
}
|
|
|
|
/*++
|
|
|
|
DBCSC_BitmapIsMarked()
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Returns:
|
|
|
|
-1 if lpbitmap is NULL or bitoffset is larger than the bitmap
|
|
TRUE if the bit is marked
|
|
FALSE if the bit is unmarked
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
int
|
|
DBCSC_BitmapIsMarked(
|
|
LPCSC_BITMAP_DB lpbitmap,
|
|
DWORD bitoffset)
|
|
{
|
|
DWORD DWORDnum;
|
|
DWORD bitpos;
|
|
|
|
if (lpbitmap == NULL)
|
|
return -1;
|
|
if (bitoffset >= lpbitmap->bitmapsize)
|
|
return -1;
|
|
|
|
DWORDnum = bitoffset/(8*sizeof(DWORD));
|
|
bitpos = 1 << bitoffset%(8*sizeof(DWORD));
|
|
|
|
if (lpbitmap->bitmap[DWORDnum] & bitpos)
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/*++
|
|
|
|
DBCSC_BitmapAppendStreamName()
|
|
|
|
Routine Description:
|
|
|
|
Appends the CSC stream name to the existing path/file name fname.
|
|
|
|
Arguments:
|
|
|
|
fname is the sting buffer containing the path/file.
|
|
bufsize is the buffer size.
|
|
|
|
Returns:
|
|
|
|
TRUE if append successful.
|
|
FALSE if buffer is too small or other errors.
|
|
|
|
Notes:
|
|
|
|
Unicode strings only.
|
|
|
|
--*/
|
|
int
|
|
DBCSC_BitmapAppendStreamName(
|
|
PWCHAR fname,
|
|
DWORD bufsize)
|
|
{
|
|
if ((wcslen(fname) + wcslen(CscBmpAltStrmName) + 1) > bufsize)
|
|
return FALSE;
|
|
wcscat(fname, CscBmpAltStrmName);
|
|
return TRUE;
|
|
}
|
|
|
|
/*++
|
|
|
|
DBCSC_BitmapRead()
|
|
|
|
Routine Description:
|
|
|
|
Reads the on-disk bitmap file, and if it exists, is not in use and valid,
|
|
store it in *lplpbitmap. If *lplpbitmap is NULL allocate a new
|
|
bitmap data structure. Otherwise, if *lplpbitmap is not NULL, the
|
|
existing bitmap will be deleted and assigned the on-disk bitmap
|
|
file.
|
|
|
|
Arguments:
|
|
|
|
filename is the file that contains the bitmap. If read from a
|
|
stream, append the stream name before passing the filename in. The
|
|
filename is used as is and no checking of validity of the name is
|
|
performed. For default stream name, append the global LPSTR
|
|
CscBmpAltStrmName.
|
|
|
|
Returns:
|
|
|
|
1 if read successful
|
|
0 if lplpbitmap is NULL
|
|
-1 if error in disk operation (open/read), memory allocating error,
|
|
or invalid bitmap file format.
|
|
-2 if bitmap not exist
|
|
|
|
Notes:
|
|
|
|
CODE.IMPROVEMENT design a better error message propagation mechanism.
|
|
Bitmap open for exclusive access.
|
|
|
|
--*/
|
|
int
|
|
DBCSC_BitmapRead(
|
|
LPCSC_BITMAP_DB *lplpbitmap,
|
|
LPCTSTR filename)
|
|
{
|
|
CscBmpFileHdr hdr;
|
|
HANDLE bitmapFile;
|
|
DWORD bytesRead;
|
|
DWORD bitmapByteSize;
|
|
DWORD * bitmapBuf = NULL;
|
|
DWORD errCode;
|
|
int ret = 1;
|
|
|
|
if (fSwDebug)
|
|
MyPrintf(L"BitmapRead(%ws)\r\n", filename);
|
|
|
|
if (lplpbitmap == NULL)
|
|
return 0;
|
|
|
|
bitmapFile = CreateFile(
|
|
filename,
|
|
GENERIC_READ,
|
|
0, // No sharing; exclusive
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL);
|
|
if (bitmapFile == INVALID_HANDLE_VALUE) {
|
|
errCode = GetLastError();
|
|
if (fSwDebug)
|
|
MyPrintf(L"BitmapRead!Createfile error %d\r\n", errCode);
|
|
if (errCode == ERROR_FILE_NOT_FOUND) {
|
|
// File does not exist
|
|
return -2;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
if (!ReadFile(
|
|
bitmapFile,
|
|
&hdr,
|
|
sizeof(CscBmpFileHdr),
|
|
&bytesRead,
|
|
NULL)
|
|
) {
|
|
if (fSwDebug)
|
|
MyPrintf(L"BitmapRead!ReadFile of header error %d\r\n", GetLastError());
|
|
ret = -1;
|
|
goto CLOSEFILE;
|
|
}
|
|
|
|
MyPrintf(
|
|
L"---Header---\r\n"
|
|
L"MagicNum: 0x%x\r\n"
|
|
L"inuse: 0x%x\r\n"
|
|
L"valid: 0x%x\r\n"
|
|
L"sizeinbits:0x%x\r\n"
|
|
L"numDWORDS:0x%x\r\n",
|
|
hdr.magicnum,
|
|
hdr.inuse,
|
|
hdr.valid,
|
|
hdr.sizeinbits,
|
|
hdr.numDWORDs);
|
|
|
|
if (bytesRead != sizeof(CscBmpFileHdr)) {
|
|
if (fSwDebug)
|
|
MyPrintf(L"BitmapRead!ReadFile bytesRead != sizeof(CscBmpFileHdr).\r\n");
|
|
ret = -1;
|
|
goto CLOSEFILE;
|
|
}
|
|
if (hdr.magicnum != MAGICNUM) {
|
|
if (fSwDebug)
|
|
MyPrintf(L"BitmapRead!ReadFile hdr.magicnum != MAGICNUM.\r\n");
|
|
ret = -1;
|
|
goto CLOSEFILE;
|
|
}
|
|
if (!hdr.valid) {
|
|
if (fSwDebug)
|
|
MyPrintf(L"BitmapRead!ReadFile !hdr.valid.\r\n");
|
|
ret = -1;
|
|
goto CLOSEFILE;
|
|
}
|
|
if (hdr.inuse) {
|
|
if (fSwDebug)
|
|
MyPrintf(L"BitmapRead!ReadFile hdr.inuse.\r\n");
|
|
ret = -1;
|
|
goto CLOSEFILE;
|
|
}
|
|
|
|
if (hdr.sizeinbits > 0) {
|
|
bitmapByteSize = hdr.numDWORDs*sizeof(DWORD);
|
|
bitmapBuf = (DWORD *)malloc(bitmapByteSize);
|
|
if (!bitmapBuf) {
|
|
if (fSwDebug)
|
|
MyPrintf(L"BitmapRead!malloc failed\r\n");
|
|
ret = -1;
|
|
goto CLOSEFILE;
|
|
}
|
|
|
|
if (!ReadFile(
|
|
bitmapFile,
|
|
bitmapBuf,
|
|
bitmapByteSize,
|
|
&bytesRead,
|
|
NULL)
|
|
) {
|
|
if (fSwDebug)
|
|
MyPrintf(L"BitmapRead!ReadFile of bitmap error %d\r\n", GetLastError());
|
|
ret = -1;
|
|
goto CLOSEFILE;
|
|
}
|
|
|
|
if (bytesRead != bitmapByteSize) {
|
|
if (fSwDebug)
|
|
MyPrintf(
|
|
L"BitmapRead!ReadFile wrong size (%d vs %d).\r\n",
|
|
bytesRead,
|
|
bitmapByteSize);
|
|
ret = -1;
|
|
goto CLOSEFILE;
|
|
}
|
|
}
|
|
|
|
if (*lplpbitmap) {
|
|
// bitmap exist, dump old and create new
|
|
if ((*lplpbitmap)->bitmap)
|
|
free((*lplpbitmap)->bitmap);
|
|
(*lplpbitmap)->bitmap = bitmapBuf;
|
|
(*lplpbitmap)->numDWORD = hdr.numDWORDs;
|
|
(*lplpbitmap)->bitmapsize = hdr.sizeinbits;
|
|
} else {
|
|
// bitmap not exist, create brand new
|
|
*lplpbitmap = (LPCSC_BITMAP_DB)malloc(sizeof(CSC_BITMAP_DB));
|
|
if (!(*lplpbitmap)) {
|
|
// Error in memory allocation
|
|
ret = -1;
|
|
goto CLOSEFILE;
|
|
}
|
|
(*lplpbitmap)->bitmap = bitmapBuf;
|
|
(*lplpbitmap)->numDWORD = hdr.numDWORDs;
|
|
(*lplpbitmap)->bitmapsize = hdr.sizeinbits;
|
|
}
|
|
|
|
CLOSEFILE:
|
|
CloseHandle(bitmapFile);
|
|
if(ret = -1 && bitmapBuf != NULL){
|
|
free(bitmapBuf);
|
|
}
|
|
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*++
|
|
|
|
DBCSC_BitmapOutput()
|
|
|
|
Routine Description:
|
|
|
|
Outputs the passed in bitmap to the ouput file stream outStrm
|
|
|
|
Arguments:
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
Notes:
|
|
|
|
|
|
--*/
|
|
void
|
|
DBCSC_BitmapOutput(
|
|
FILE * outStrm,
|
|
LPCSC_BITMAP_DB lpbitmap)
|
|
{
|
|
DWORD i;
|
|
|
|
if (lpbitmap == NULL) {
|
|
MyPrintf(L"lpbitmap is NULL\r\n");
|
|
return;
|
|
}
|
|
|
|
MyPrintf(L"lpbitmap 0x%08x, bitmapsize 0x%x numDWORD 0x%x\r\n",
|
|
(ULONG_PTR)lpbitmap, lpbitmap->bitmapsize, lpbitmap->numDWORD);
|
|
|
|
MyPrintf(L"bitmap |0/5 |1/6 |2/7 |3/8 |4/9\r\n");
|
|
MyPrintf(L"number |01234|56789|01234|56789|01234|56789|01234|56789|01234|56789");
|
|
for (i = 0; i < lpbitmap->bitmapsize; i++) {
|
|
if ((i % 50) == 0)
|
|
MyPrintf(L"\r\n%08d", i);
|
|
if ((i % 5) == 0)
|
|
MyPrintf(L"|");
|
|
MyPrintf(L"%1d", DBCSC_BitmapIsMarked(lpbitmap, i));
|
|
}
|
|
MyPrintf(L"\r\n");
|
|
}
|
|
|
|
DWORD
|
|
DumpBitMap(
|
|
LPWSTR lpszTempName)
|
|
{
|
|
WCHAR lpszBitMapName[MAX_PATH];
|
|
LPCSC_BITMAP_DB lpbitmap = NULL;
|
|
DWORD dwError = ERROR_SUCCESS;
|
|
|
|
wcscpy(lpszBitMapName,lpszTempName);
|
|
DBCSC_BitmapAppendStreamName(lpszBitMapName, MAX_PATH);
|
|
// read bitmap
|
|
switch(DBCSC_BitmapRead(&lpbitmap, lpszBitMapName)) {
|
|
case 1:
|
|
// Print the bitmap associated if any
|
|
MyPrintf(L"\r\n");
|
|
DBCSC_BitmapOutput(stdout, lpbitmap);
|
|
MyPrintf(L"\r\n");
|
|
// if bitmap opened delete bitmap
|
|
// DBCSC_BitmapDelete(&lpbitmap);
|
|
break;
|
|
case -1:
|
|
MyPrintf(L"Error reading bitmap file %ws or bitmap invalid\r\n", lpszBitMapName);
|
|
dwError = ERROR_FILE_NOT_FOUND;
|
|
break;
|
|
case -2:
|
|
MyPrintf(L"No CSCBitmap\n");
|
|
dwError = ERROR_FILE_NOT_FOUND;
|
|
break;
|
|
case 0:
|
|
default:
|
|
MyPrintf(L"Something strange going on with bitmap printing...\r\n");
|
|
dwError = ERROR_FILE_NOT_FOUND;
|
|
break;
|
|
}
|
|
return dwError;
|
|
}
|
|
|
|
#endif // CSCUTIL_INTERNAL
|