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

762 lines
21 KiB

#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 "cscapi.h"
#pragma pack (1)
#if defined(BITCOPY)
#include "csc_bmpd.h"
#endif // defined(BITCOPY)
#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))
#define _mytoupper(x) ( ( ((x)>='a')&&((x)<='z') ) ? ((x)-'a'+'A'):(x))
#ifndef CSC_ON_NT
typedef void *CSCHFILE;
typedef void *CSC_ENUMCOOKIE;
#define UCHAR unsigned char
#define USHORT unsigned short
#define ULONG unsigned long
#define CHAR char
#define wchar_t unsigned short
#define LPTSTR LPSTR
#define CONST const
#define LPWIN32_FIND_DATAW LPVOID
typedef struct tagSTOREDATA
{
ULONG ulSize; // Max shadow data size
ULONG ucntDirs; // Current count of dirs
ULONG ucntFiles; // Current count of files
}
STOREDATA, *LPSTOREDATA;
typedef LPVOID LPFIND32;
#else
typedef PVOID CSCHFILE;
#include "shdcom.h"
#include "cscsec.h"
#endif //CSC_ON_NT
#define ESC 0x1b
typedef unsigned long ulong;
typedef unsigned short ushort;
typedef LPSTR LPPATH;
#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))
char rgch[256], rgPrint[1024], rgchPar[256];
char szShadow[] = "\\WINDOWS\\CSC";
char szBackslash[] = "\\";
char szDbDir[256]; // shadow database
char szName[MAX_PATH]; // working buffer
int DispFunc(char *);
void DisplayShares(char *);
void DisplayInodes(void);
void DisplayPriorityQ(void);
void DisplayFile(unsigned long ulid, char *);
int PUBLIC HexToA(ulong, LPSTR, int);
void PRIVATE FormNameStringDB(
LPSTR lpdbID,
ulong ulidFile,
LPSTR lpName
);
BOOL
FindAncestor(
ulong ulid,
ulong *lpulidDir
);
void
printwidestring(
USHORT *lpwString,
unsigned long cntChars
);
int RoughCompareWideStringWithAnsiString(
LPSTR lpSrcString,
USHORT *lpwDstString,
int cntMax
);
int _cdecl main(int argc, char *argv[], char *envp[])
{
BOOL fRet;
DWORD junk;
unsigned uAttr;
int iRet = -1;
if (argc==1)
{
fRet = CSCGetSpaceUsage(
szDbDir,
sizeof(szDbDir),
&junk,
&junk,
&junk,
&junk,
&junk,
&junk);
if (fRet == FALSE)
strcpy(szDbDir, szShadow);
}
else
{
memset(szDbDir, 0, sizeof(szDbDir));
strncpy(szDbDir, argv[1], sizeof(szDbDir)-1);
}
#ifdef CSC_ON_NT
if((uAttr = GetFileAttributes(szDbDir)) == 0xffffffff)
#else
if(_dos_getfileattr(szDbDir, &uAttr))
#endif //CSC_ON_NT
{
printf("Error accessing directory %s \r\n", szDbDir);
}
else if (!(uAttr & _A_SUBDIR))
{
printf("%s is not a directory\r\n", szDbDir);
}
else
{
do
{
memset(rgch, 0, sizeof(rgch));
printf("\r\n");
printf("Shares [s [name]], ");
printf("PriQ [q], ");
printf("File [f inode# [name]], ");
printf("Exit [x], ");
printf("Enter:");
if (!gets(rgch))
break;
printf("\r\n");
if (!DispFunc(rgch))
break;
}
while (1);
iRet = 0;
}
return (iRet);
}
int DispFunc(
char *lpBuff
)
{
char ch;
unsigned long ulid;
int cnt;
cnt = sscanf(lpBuff, "%c", &ch);
if (!cnt)
return 0;
switch (ch)
{
// Display shares database
case 's':
case 'S':
cnt = sscanf(lpBuff, "%c%s", &ch, rgchPar);
DisplayShares((cnt==2)?rgchPar:NULL);
break;
// display priority Q database
case 'q':
case 'Q':
DisplayPriorityQ();
break;
case 'f':
case 'F':
cnt = sscanf(lpBuff, "%c%lx%s", &ch, &ulid, rgchPar);
if (cnt==2)
{
// display Inode file
DisplayFile(ulid, NULL);
}
else if (cnt==3)
{
printf("Looking for %s in %x \r\n", rgchPar, ulid);
// display Inode file
DisplayFile(ulid, rgchPar);
}
break;
case 'x':
case 'X':
return 0;
}
return 1;
}
void
DisplaySecurityContext(
char *pSecurityDescriptor,
LPRECORDMANAGER_SECURITY_CONTEXT pSecurityContext)
{
#ifdef CSC_ON_NT
PCACHED_SECURITY_INFORMATION pCachedSecurityInformation;
ULONG i;
pCachedSecurityInformation = (PCACHED_SECURITY_INFORMATION)pSecurityContext;
if (pSecurityDescriptor != NULL) {
printf("\n%s ",pSecurityDescriptor);
}
printf("SECURITY CONTEXT:\n");
for (i = 0; i < MAXIMUM_NUMBER_OF_USERS; i++) {
CSC_SID_INDEX SidIndex;
SidIndex = pCachedSecurityInformation->AccessRights[i].SidIndex;
switch (SidIndex) {
case CSC_INVALID_SID_INDEX:
break;
default:
{
if (SidIndex == CSC_GUEST_SID_INDEX) {
printf("\tGUEST: ");
} else {
printf("\t%lx: ",SidIndex);
}
printf(
"Rights: %lx\t\n",
pCachedSecurityInformation->AccessRights[i].MaximalRights);
}
}
}
#endif
}
void
DisplaySecurityContext2(
char *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;
printf("%s 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) {
printf("(G:0x%x)",
pCachedSecurityInformation->AccessRights[i].MaximalRights);
} else {
printf("(0x%x:0x%x)",
SidIndex,
pCachedSecurityInformation->AccessRights[i].MaximalRights);
}
}
printf("\r\n");
}
void DisplayShares(
char *lpszShareName
)
{
FILE *fp= (FILE *)NULL;
SHAREHEADER sSH;
SHAREREC sSR;
unsigned long ulrec=1L;
int count=0;
FormNameStringDB(szDbDir, ULID_SHARE, szName);
if (fp = _fsopen(szName, "rb", _SH_DENYNO))
{
if (fread(&sSH, sizeof(SHAREHEADER), 1, fp) != 1)
{
printf("Error reading server header \r\n");
goto bailout;
}
printf("Header: Flags=%x Version=%lx Records=%ld Size=%d \r\n",
sSH.uFlags, sSH.ulVersion, sSH.ulRecords, sSH.uRecSize);
printf("Store: Max=%ld Current=%ld \r\n", sSH.sMax.ulSize, sSH.sCur.ulSize);
printf("store: files=%ld directories=%ld \r\n\r\n", sSH.sCur.ucntFiles, sSH.sCur.ucntDirs);
while (fread(&sSR, sizeof(SHAREREC), 1, fp)==1)
{
if (count == MAX_SHARES_PER_PAGE) {
printf("\r\n--- Press any key to continue; ESC to cancel ---\r\n");
if(_getch()==ESC) {
break;
}
count = 0;
}
if (sSR.uchType == (unsigned char)REC_DATA) {
if (lpszShareName) {
if (RoughCompareWideStringWithAnsiString(
lpszShareName,
sSR.rgPath,
sizeof(sSR.rgPath)/sizeof(USHORT)-1)
) {
continue;
}
}
printwidestring(sSR.rgPath, sizeof(sSR.rgPath)/sizeof(USHORT));
printf("\r\n");
printf( " Share=0x%x Root=0x%x Stat=0x%x RootStat=0x%x "
"HntFlgs=0x%x HntPri=0x%x Attr=0x%x\r\n",
ulrec++,
sSR.ulidShadow,
sSR.uStatus,
(unsigned)(sSR.usRootStatus),
(unsigned)(sSR.uchHintFlags),
(unsigned)(sSR.uchHintPri),
sSR.dwFileAttrib);
DisplaySecurityContext2(" ShareLevel",&sSR.sShareSecurity);
DisplaySecurityContext2(" Root ",&sSR.sRootSecurity);
printf("\r\n");
if (lpszShareName) {
printf("\r\n--- Press any key to continue search; ESC to cancel ---\r\n");
if(_getch()==ESC) {
break;
}
} else {
++count;
}
}
}
}
bailout:
if (fp)
fclose(fp);
}
void DisplayPriorityQ
(
void
)
{
FILE *fp= (FILE *)NULL;
QHEADER sQH;
QREC sQR;
unsigned long ulRec=1;
int count = 0;
FormNameStringDB(szDbDir, ULID_PQ, szName);
if (fp = _fsopen(szName, "rb", _SH_DENYNO)) {
if (fread(&sQH, sizeof(QHEADER), 1, fp) != 1) {
printf("Error reading PQ header \r\n");
goto bailout;
}
printf("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);
printf("\r\n");
printf(
" REC SHARE DIR SHADOW STATUS PRI HINTFLGS HINTPRI PREV NEXT DIRENT\r\n");
for (ulRec = sQH.ulrecHead; ulRec;) {
if (count == MAX_PQ_PER_PAGE) {
printf("\r\n--- Press any key to continue; ESC to cancel ---\r\n");
if(_getch()==ESC) {
break;
}
count = 0;
printf(
" REC SHARE DIR SHADOW STATUS PRI HINTFLGS HINTPRI PREV NEXT DIRENT\r\n");
}
fseek(fp, ((ulRec-1) * sizeof(QREC))+sizeof(QHEADER), SEEK_SET);
if (fread(&sQR, sizeof(QREC), 1, fp)!=1)
break;
printf("%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 DisplayFile(
unsigned long ulid,
char *lpszName
)
{
FILE *fp= (FILE *)NULL;
FILEHEADER sFH;
FILEREC sFR;
int fLfn=0;
unsigned long ulidDir=ulid;
int fPrintOvf = 0, count=0;
#if defined(BITCOPY)
char strmPath[MAX_PATH];
LPCSC_BITMAP_DB lpbitmap = NULL;
#endif // defined(BITCOPY)
if (IsLeaf(ulid)) {
if (!FindAncestor(ulid, &ulidDir))
return;
}
FormNameStringDB(szDbDir, ulidDir, szName);
if (fp = _fsopen(szName, "rb", _SH_DENYNO)) {
if (fread(&sFH, sizeof(FILEHEADER), 1, fp) != 1) {
printf("Error reading file header \r\n");
goto bailout;
}
if (ulid == ulidDir) {
printf("Header: Flags=%x Version=%lx Records=%ld Size=%d\r\n",
sFH.uchFlags, sFH.ulVersion, sFH.ulRecords, sFH.uRecSize);
printf("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 (count == MAX_FILE_PER_PAGE) {
printf("--- Press any key to continue; ESC to cancel ---\r\n");
if(_getch()==ESC) {
break;
}
count = 0;
}
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 (lpszName) {
if (RoughCompareWideStringWithAnsiString(
lpszName,
sFR.rgwName,
sizeof(sFR.rgw83Name)/sizeof(USHORT)-1)
) {
continue;
}
}
fPrintOvf = 1;
printwidestring(sFR.rgw83Name, sizeof(sFR.rgw83Name)/sizeof(USHORT));
printf(" (0x%x)\r\n", sFR.ulidShadow);
printf(" 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);
printf(" PinFlags=0x%x PinCount=%d RefPri=%d OriginalInode=0x%0x\r\n",
(unsigned)(sFR.uchHintFlags),
(int)(sFR.uchHintPri),
(int)(sFR.uchRefPri),
sFR.ulidShadowOrg);
printf(" time: hi=%x lo=%x orgtime: hi=%x lo=%x\r\n",
sFR.ftLastWriteTime.dwHighDateTime,
sFR.ftLastWriteTime.dwLowDateTime,
sFR.ftOrgTime.dwHighDateTime,
sFR.ftOrgTime.dwLowDateTime);
if (sFR.rgwName[0]) {
printf(" LFN:");
printwidestring(sFR.rgwName, sizeof(sFR.rgwName)/sizeof(USHORT));
fLfn = 1;
}
printf("\r\n");
DisplaySecurityContext2(" ",&sFR.Security);
if (ulidDir != ulid)
{
printf("DirInode = %x\r\n", ulidDir);
#if defined(BITCOPY)
FormNameStringDB(szDbDir, sFR.ulidShadow, strmPath);
DBCSC_BitmapAppendStreamName(strmPath, MAX_PATH);
printf("Trying to read CSCBitmap file %s\n", strmPath);
// read bitmap
switch(DBCSC_BitmapRead(&lpbitmap, strmPath)) {
case 1:
// Print the bitmap associated if any
printf("\n");
DBCSC_BitmapOutput(stdout, lpbitmap);
printf("\n");
// if bitmap opened delete bitmap
DBCSC_BitmapDelete(&lpbitmap);
break;
case -1:
printf("Error reading bitmap file %s or bitmap invalid\n",
strmPath);
break;
case -2:
printf("No CSCBitmap\n");
break;
case 0:
default:
printf("Something strange going on w/ bitmap printing...\n");
break;
}
#endif // defined(BITCOPY)
break;
}
if (lpszName) {
printf("--- Press any key to continue search; ESC to cancel ---\r\n");
if(_getch()==ESC) {
break;
}
}
printf("\r\n");
} else if (fPrintOvf && (sFR.uchType == (unsigned char)REC_OVERFLOW)) {
printf("(overflow) ");
printwidestring(sFR.rgwOvf,
(sizeof(FILEREC)-sizeof(RECORDMANAGER_COMMON_RECORD))/sizeof(USHORT));
printf("\r\n\r\n");
}
// do counting only when we are scanning the whole directory
if (!lpszName && (ulid == ulidDir)) {
++count;
}
}
printf("\r\n");
}
bailout:
if (fp)
fclose(fp);
}
void PRIVATE FormNameStringDB(
LPSTR lpdbID,
ulong ulidFile,
LPSTR lpName
)
{
LPSTR lp;
char chSubdir;
#ifdef CSC_ON_NT
// Prepend the local path
strcpy(lpName, lpdbID);
strcat(lpName, szBackslash);
#else
// Prepend the local path
_fstrcpy(lpName, lpdbID);
_fstrcat(lpName, szBackslash);
#endif //CSC_ON_NT
// Bump the pointer appropriately
#ifdef CSC_ON_NT
lp = lpName + strlen(lpName);
#else
lp = lpName + _fstrlen(lpName);
#endif //CSC_ON_NT
chSubdir = CSCDbSubdirSecondChar(ulidFile);
// sprinkle the user files in one of the subdirectories
if (chSubdir)
{
// now append the subdirectory
*lp++ = CSCDbSubdirFirstChar();
*lp++ = chSubdir;
*lp++ = '\\';
}
HexToA(ulidFile, lp, 8);
lp += 8;
*lp = 0;
}
int PUBLIC HexToA(
ulong ulHex,
LPSTR lpName,
int count)
{
int i;
LPSTR lp = lpName+count-1;
unsigned char uch;
for (i=0; i<count; ++i)
{
uch = (unsigned char)(ulHex & 0xf) + '0';
if (uch > '9')
uch += 7; // A becomes '0' + A + 7 which is 'A'
*lp = uch;
--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(szDbDir, ULID_PQ, szName);
if (fp = _fsopen(szName, "rb", _SH_DENYNO))
{
if (fread(&sQH, sizeof(QHEADER), 1, fp) != 1)
{
printf("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;
}
#ifndef CSC_ON_NT
void
printwidestring(
USHORT *lpwString,
unsigned long cntChars
)
{
unsigned long i;
cntChars = min(cntChars, sizeof(rgPrint) -1);
for(i=0; (i< cntChars) && lpwString[i]; ++i)
{
rgPrint[i] = (char)(lpwString[i]);
}
rgPrint[i] = 0;
printf(rgPrint);
}
#else
void
printwidestring(
USHORT *lpwString,
unsigned long cntChars
)
{
printf("%ls", lpwString);
}
#endif
int RoughCompareWideStringWithAnsiString(
LPSTR lpSrcString,
USHORT *lpwDstString,
int cntMax
)
{
char ch;
USHORT uch;
int i;
for (i=0;i<cntMax;++i)
{
ch = *lpSrcString++;
uch = *lpwDstString++;
uch = _wtoupper(uch);
ch = _mytoupper(ch);
if (!ch)
{
return 0;
}
if (ch != (char)uch)
{
return ((char)uch - ch);
}
}
if (i==cntMax)
{
return 0;
}
return 1; // this should never occur
}