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

#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