|
|
/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
OsLayer.c
Abstract: (win95)
none.
Abstract: (NT)
We go thru these wrapper functions but the main implementation is in ntcsclow.c
Author:
Shishir Pardikar [Shishirp] 01-jan-1995
Revision History:
Joe Linn [joelinn] 01-jan-1997 ported to NT Joe Linn [joelinn] 22-aug-1997 moved NT stuff to ntcsclow.c
--*/
#include "precomp.h"
#pragma hdrstop
#pragma code_seg("PAGE")
#ifndef CSC_RECORDMANAGER_WINNT
#define WIN32_APIS
#include "cshadow.h"
#endif //ifndef CSC_RECORDMANAGER_WINNT
//already included by shdcom.h #include "ifs.h"
#ifdef CSC_RECORDMANAGER_WINNT
#define Dbg (DEBUG_TRACE_MRXSMBCSC_OSLAYER)
RXDT_DefineCategory(MRXSMBCSC_OSLAYER); #endif //ifdef CSC_RECORDMANAGER_WINNT
//#define RXJOECSC_WHACKTRACE_FOR_OSLAYER
#ifdef RXJOECSC_WHACKTRACE_FOR_OSLAYER
#undef RxDbgTrace
#define RxDbgTrace(a,b,__d__) {DbgPrint __d__;}
#endif
#ifdef CSC_BUILD_W_PROGRESS_CATCHERS
VOID CscProgressInit ( PCSC_PROGRESS_BLOCK ProgressBlock, ULONG Counter, PVOID NearArgs ) { ProgressBlock->Counter = Counter; ProgressBlock->NearTop = &NearArgs; ProgressBlock->NearArgs = NearArgs; ProgressBlock->Progress = 0x80000000; ProgressBlock->LastBit = 0; ProgressBlock->Loops = 0; ProgressBlock->StackRemaining = IoGetRemainingStackSize(); ProgressBlock->RetAddrP = ((PULONG)NearArgs)-1; //that's one ulong, boys....
ProgressBlock->RetAddr = *(ProgressBlock->RetAddrP); ProgressBlock->SignatureOfEnd = '!dne'; } VOID CscProgress ( PCSC_PROGRESS_BLOCK ProgressBlock, ULONG Bit ) { if( (*(ProgressBlock->RetAddrP)) != ProgressBlock->RetAddr ) { DbgPrint("Returnaddr has been trashed %08lx %08lx %08lx %08lx\n", ProgressBlock,Bit, (*(ProgressBlock->RetAddrP)), ProgressBlock->RetAddr); DbgBreakPoint(); } ProgressBlock->Progress |= (1<<Bit); if (Bit <= ProgressBlock->LastBit) { ProgressBlock->Loops++; } ProgressBlock->LastBit = Bit; } #endif //ifdef CSC_RECORDMANAGER_WINNT
/*
*/ /********************** typedefs and defines ********************************/ #ifdef HISTORY
#define R0_OPENCREATE 0xD500
#define R0_READ 0xD600
#define R0_WRITE 0xD601
#define R0_CLOSE 0xD700
#define R0_GETFILESIZE 0xD800
#define R0_RENAMEFILE 0x5600
#define R0_FILELOCK 0x5C00
#define R0_GETATTRIBUTE 0x4300
#define R0_SETATTRIBUTE 0x4301
#define R0_DELETEFILE 0x4100
#endif //HISTORY
#define R0_UNLOCKFILE 0x5C01
#define R0_SETATTRIBUTE 0x4301
#pragma intrinsic (memcmp, memcpy, memset, strcat, strcmp, strcpy, strlen)
/********************** static data *****************************************/ /********************** global data *****************************************/
AssertData; AssertError; /********************** function prototypes *********************************/
int Ring0Api();
/****************************************************************************/
/************************ File I/O ******************************************/
#ifndef CSC_RECORDMANAGER_WINNT
#pragma VxD_LOCKED_CODE_SEG
#endif //ifndef CSC_RECORDMANAGER_WINNT
long R0ReadWriteFile (ULONG uOper, CSCHFILE handle, ULONG pos, PVOID, long lCount); #ifndef R0ReadWriteFileEx
long R0ReadWriteFileEx (ULONG uOper, CSCHFILE handle, ULONG pos, PVOID, long lCount, BOOL fInstrument); #endif //ifndef R0ReadWriteFile
#ifndef R0ReadWriteFileEx2
long R0ReadWriteFileEx2 (ULONG uOper, CSCHFILE handle, ULONG pos, PVOID, long lCount, ULONG uFlags); #endif //ifndef R0ReadWriteFileEx2
CSCHFILE CreateFileLocal(LPSTR lpPath) { return (R0OpenFile(ACCESS_READWRITE, ACTION_OPENALWAYS, lpPath)); }
CSCHFILE OpenFileLocal(LPSTR lpPath) { return (OpenFileLocalEx(lpPath, FALSE)); } CSCHFILE OpenFileLocalEx(LPSTR lpPath, BOOL fInstrument) { CSCHFILE hf; // unsigned uSize;
hf = R0OpenFileEx(ACCESS_READWRITE, ACTION_OPENEXISTING, 0, lpPath, fInstrument);
#ifdef DEBUG
if (!hf) KdPrint(("OpenFileLocal: error opening %s \r\n", lpPath)); #endif //DEBUG
#ifdef OBSOLETE
// BUGBUG-win9xonly temporary kludge till fixed in IFS
hf = R0OpenFile(ACCESS_READWRITE, ACTION_OPENALWAYS, lpPath); if (hf) { if ((GetFileSizeLocal(hf, &uSize) < 0 ) || !uSize) { CloseFileLocal(hf); hf = CSCHFILE_NULL; } } #endif //OBSOLETE
return (hf); }
int FileExists ( LPSTR lpPath ) { CSCHFILE hf; if (hf = R0OpenFile(ACCESS_READWRITE, ACTION_OPENEXISTING, lpPath)) { CloseFileLocal(hf); } return (hf != CSCHFILE_NULL); }
long ReadFileLocal ( CSCHFILE handle, ULONG pos, LPVOID pBuff, long lCount ) { return(R0ReadWriteFile(R0_READFILE, handle, pos, pBuff,lCount)); }
long ReadFileLocalEx ( CSCHFILE handle, ULONG pos, LPVOID pBuff, long lCount, BOOL fInstrument ) { return(R0ReadWriteFileEx(R0_READFILE, handle, pos, pBuff,lCount, fInstrument)); }
long ReadFileLocalEx2 ( CSCHFILE handle, ULONG pos, LPVOID pBuff, long lCount, ULONG flags ) { return(R0ReadWriteFileEx2(R0_READFILE, handle, pos, pBuff, lCount, flags)); }
long WriteFileLocal ( CSCHFILE handle, ULONG pos, LPVOID pBuff, long lCount ) { return(R0ReadWriteFile(R0_WRITEFILE, handle, pos, pBuff, lCount)); }
long WriteFileLocalEx ( CSCHFILE handle, ULONG pos, LPVOID pBuff, long lCount, BOOL fInstrument ) { return(R0ReadWriteFileEx(R0_WRITEFILE, handle, pos, pBuff, lCount, FALSE)); }
long WriteFileLocalEx2( CSCHFILE hf, unsigned long lSeek, LPVOID lpBuff, long cLength, ULONG flags ) { return (R0ReadWriteFileEx2(R0_WRITEFILE, hf, lSeek, lpBuff, cLength, flags)); }
long ReadFileInContextLocal ( CSCHFILE handle, ULONG pos, LPVOID pBuff, long lCount ) { return(R0ReadWriteFile(R0_READFILE_IN_CONTEXT, handle, pos, pBuff,lCount)); }
long WriteFileInContextLocal ( CSCHFILE handle, ULONG pos, LPVOID pBuff, long lCount ) { return(R0ReadWriteFile(R0_WRITEFILE_IN_CONTEXT, handle, pos, pBuff, lCount)); }
#ifndef CSC_RECORDMANAGER_WINNT
ULONG CloseFileLocal ( CSCHFILE handle ) { ULONG uOp = R0_CLOSEFILE; _asm { mov eax, uOp mov ebx, handle call Ring0Api jc error xor eax,eax error: } } #endif //ifndef CSC_RECORDMANAGER_WINNT
CSCHFILE R0OpenFile ( USHORT usOpenFlags, UCHAR bAction, LPSTR lpPath ) { return (R0OpenFileEx(usOpenFlags, bAction, FILE_ATTRIBUTE_NORMAL, lpPath, FALSE)); }
#ifndef CSC_RECORDMANAGER_WINNT
CSCHFILE R0OpenFileEx ( USHORT usOpenFlags, UCHAR bAction, ULONG ulAttr, LPSTR lpPath, BOOL fInstrument ) { ULONG uOper = R0_OPENCREATFILE; UCHAR bR0Opt = R0_SWAPPER_CALL; ulAttr; // ignore ulAttr on win9x
_asm { mov eax, uOper mov bx, usOpenFlags mov cx, 0 mov dl, bAction mov dh, bR0Opt mov esi, lpPath call Ring0Api jnc ok xor eax,eax ok: } } #endif //ifndef CSC_RECORDMANAGER_WINNT
long R0ReadWriteFile ( ULONG uOper, CSCHFILE handle, ULONG pos, PVOID pBuff, long lCount ) { return (R0ReadWriteFileEx(uOper, handle, pos, pBuff, lCount, FALSE)); }
#ifndef CSC_RECORDMANAGER_WINNT
long R0ReadWriteFileEx (// YUK
ULONG uOper, CSCHFILE handle, ULONG pos, PVOID pBuff, long lCount, BOOL fInstrument // don't care
) { return (R0ReadWriteFileEx2(uOper, handle, pos, pBuff, lCount, 0));
}
long R0ReadWriteFileEx2 ( ULONG uOper, CSCHFILE handle, ULONG pos, PVOID pBuff, long lCount, ULONG ulFlags ) { int retValue; if (lCount < 0 ) return -1; _asm { mov eax, uOper mov ebx, handle mov ecx, lCount mov edx, pos mov esi, pBuff call Ring0Api jnc done mov eax,0xffffffff
; neg eax ; return negative error codes done: } } #endif //ifndef CSC_RECORDMANAGER_WINNT
#ifndef CSC_RECORDMANAGER_WINNT
int GetFileSizeLocal ( CSCHFILE handle, PULONG lpuSize ) { ULONG uSize; int iRes=0; _asm { mov eax, R0_GETFILESIZE mov ebx, handle call Ring0Api jnc ok mov iRes,0xffffffff ok: mov uSize, eax } *lpuSize = uSize; return (iRes); } #endif //ifndef CSC_RECORDMANAGER_WINNT
#ifndef CSC_RECORDMANAGER_WINNT
int GetAttributesLocal ( LPSTR lpPath, ULONG *lpuAttributes ) { int iRes=0; USHORT usAttrib=0;
_asm { mov eax, R0_FILEATTRIBUTES mov esi, lpPath call Ring0Api jnc ok mov iRes,0xffffffff ok: mov usAttrib, cx } *lpuAttributes = (ULONG)usAttrib; return (iRes); } #endif //ifndef CSC_RECORDMANAGER_WINNT
#ifndef CSC_RECORDMANAGER_WINNT
int SetAttributesLocal ( LPSTR lpPath, ULONG uAttributes ) { int iRes=0; USHORT usAttrib=(USHORT)uAttributes; _asm { mov eax, R0_SETATTRIBUTE mov esi, lpPath mov cx, usAttrib call Ring0Api jnc ok mov iRes,0xffffffff ok: } return (iRes); } #endif //ifndef CSC_RECORDMANAGER_WINNT
#ifndef CSC_RECORDMANAGER_WINNT
int RenameFileLocal ( LPSTR lpFrom, LPSTR lpTo ) { int iRes=0; #ifdef DEBUG
int iErr; #endif //DEBUG
_asm { mov eax, R0_RENAMEFILE mov esi, lpFrom mov edx, lpTo call Ring0Api jnc ok mov iRes,0xffffffff #ifdef DEBUG
mov iErr,eax #endif
ok: } #ifdef DEBUG
if (iRes == 0xffffffff) { KdPrint(("RenameFileLocal: error %d renaming %s to %s\r\n", iErr, lpFrom, lpTo)); } #endif //DEBUG
return (iRes); } #endif //ifndef CSC_RECORDMANAGER_WINNT
#ifndef CSC_RECORDMANAGER_WINNT
int DeleteFileLocal ( LPSTR lpName, USHORT usAttrib ) { int iRes=0; #ifdef DEBUG
int iErr; #endif //DEBUG
_asm { mov eax, R0_DELETEFILE mov esi, lpName mov cx, usAttrib call Ring0Api jnc ok mov iRes,0xffffffff #ifdef DEBUG
mov iErr,eax #endif
ok: } #ifdef DEBUG
if (iRes == 0xffffffff) { KdPrint(("DeleteFileLocal: error %d deleting %s \r\n", iErr, lpName)); } #endif //DEBUG
return (iRes); } #endif //ifndef CSC_RECORDMANAGER_WINNT
int GetDiskFreeSpaceLocal( int indx, ULONG *lpuSectorsPerCluster, ULONG *lpuBytesPerSector, ULONG *lpuFreeClusters, ULONG *lpuTotalClusters ) { #ifndef CSC_RECORDMANAGER_WINNT
int iRes = 0; BYTE bIndx = (BYTE)indx; USHORT usSPC, usBPS, usFC, usTC; _asm { mov eax, R0_GETDISKFREESPACE mov dl, bIndx call Ring0Api jnc ok mov iRes, 0xffffffff jmp done ok: mov usSPC, ax mov usBPS, cx mov usFC, bx mov usTC, dx done: } if (!iRes) { *lpuSectorsPerCluster = (ULONG)usSPC; *lpuBytesPerSector = (ULONG)usBPS; *lpuFreeClusters = (ULONG)usFC; *lpuTotalClusters = (ULONG)usTC; } return (iRes); #else
ASSERT(FALSE); return(-1); #endif //ifndef CSC_RECORDMANAGER_WINNT
}
int FileLockLocal( CSCHFILE hf, ULONG offsetLock, ULONG lengthLock, ULONG idProcess, BOOL fLock ) { #ifndef CSC_RECORDMANAGER_WINNT
int iRes = 0; ULONG uOp = (fLock)?R0_LOCKFILE:R0_UNLOCKFILE; _asm { mov eax, uOp mov ebx, hf mov edx, offsetLock mov esi, lengthLock mov ecx, idProcess call Ring0Api jnc ok mov iRes,0xffffffff ok: } return (iRes); #else
ASSERT(FALSE); return(-1); #endif //ifndef CSC_RECORDMANAGER_WINNT
}
int FindOpenRemote ( PIOREQ pir, LPHFREMOTE lphFind ) { int iRet; PRESOURCE pResource = pir->ir_rh; PFINDINFO pFindInfo; hndlfunc hfnSav; hfunc_t pSav;
if(!(pFindInfo = (PFINDINFO)PAllocElem(SizeofFindRemote))) { #if VERBOSE > 1
KdPrint(("FindOpenRemote: Error creating FindOpen structure \r\n")); #endif //VERBOSE > 1
return -1; // BUGBUG-win9xonly return proper error code
}
mSetBits(pFindInfo->usLocalFlags, FLAG_FINDINFO_INTERNAL_HANDLE); // HACK save the ioreq structure
pFindInfo->pnextFindInfo = (PFINDINFO)pir; // Save it
memcpy(LpIoreqFromFindInfo(pFindInfo), pir, sizeof(ioreq));
pir->ir_data = LpFind32FromFindInfo(pFindInfo); pir->ir_attr = FILE_ATTRIBUTE_ALL; pir->ir_error = 0; pir->ir_flags = RESTYPE_DISK; pSav = pir->ir_hfunc; pir->ir_hfunc = (hfunc_t)&hfnSav; pir->ir_rh = pResource->rhPro;
(*(pResource->pVolTab->vfn_func[VFN_FINDOPEN]))(pir); iRet = pir->ir_error; pir->ir_hfunc = pSav; pir->ir_rh = (rh_t)pResource; pir->ir_error = 0;
if (!iRet) { // succeeded
// Save his file handle
pFindInfo->fhProFind = pir->ir_fh;
// Save his function table
pFindInfo->hfFindHandle = hfnSav;
// point back to our parent
pFindInfo->pResource = pResource;
#if VERBOSE > 1
{
KdPrint(("FindOpenRemote: lpFind32=%x Lowdate=%x Highdate=%x \r\n" , LpFind32FromFindInfo(pFindInfo) , LpFind32FromFindInfo(pFindInfo)->ftLastWriteTime.dwLowDateTime , LpFind32FromFindInfo(pFindInfo)->ftLastWriteTime.dwHighDateTime)); } #endif //VERBOSE > 1
} else { memcpy(pir, LpIoreqFromFindInfo(pFindInfo), sizeof(ioreq)); FreeMem(pFindInfo); #if VERBOSE < 2
if (iRet != ERROR_NO_MORE_FILES) #endif //VERBOSE < 2
#if VERBOSE > 1
KdPrint(("FindOpenRemote: Error %x \r\n", iRet)); #endif //VERBOSE > 1
pFindInfo = NULL; }
*lphFind = (HFREMOTE)pFindInfo; return (iRet); }
int FindNextRemote ( PFINDINFO pFindInfo, PIOREQ pir ) { PRESOURCE pResource = pir->ir_rh; int iRet;
if (mQueryBits(pFindInfo->usLocalFlags, FLAG_FINDINFO_INTERNAL_HANDLE)) { pir = (PIOREQ)(pFindInfo->pnextFindInfo); } else { Assert(pir); } pir->ir_data = LpFind32FromFindInfo(pFindInfo); pir->ir_error = 0;
pir->ir_rh = pFindInfo->pResource->rhPro; pir->ir_fh = pFindInfo->fhProFind; (*(pFindInfo->hfFindHandle.hf_read))(pir); iRet = pir->ir_error; pir->ir_rh = (rh_t)(pFindInfo->pResource); pir->ir_error = 0; return (iRet); }
int FindCloseRemote ( PFINDINFO pFindInfo, PIOREQ pir ) { PRESOURCE pResource = pir->ir_rh; int iRet;
if (mQueryBits(pFindInfo->usLocalFlags, FLAG_FINDINFO_INTERNAL_HANDLE)) { pir = (PIOREQ)(pFindInfo->pnextFindInfo); }
#if VERBOSE > 1
KdPrint(("FindCloseRemote: hfind= %x fh=%x\r\n", pFindInfo, pFindInfo->fhProFind)); #endif //VERBOSE > 1
pir->ir_error = 0; pir->ir_rh = pFindInfo->pResource->rhPro; pir->ir_fh = pFindInfo->fhProFind; (*(pFindInfo->hfFindHandle.hf_misc->hm_func[HM_CLOSE]))(pir); iRet = pir->ir_error; pir->ir_rh = (rh_t)(pFindInfo->pResource); pir->ir_error = 0; if (iRet) { #if VERBOSE > 1
KdPrint(("FindCloseRemote: error hf= %x #=%x \r\n", pFindInfo, iRet)); #endif //VERBOSE > 1
} if (mQueryBits(pFindInfo->usLocalFlags, FLAG_FINDINFO_INTERNAL_HANDLE)) { Assert(pir == (PIOREQ)(pFindInfo->pnextFindInfo)); memcpy(pir, LpIoreqFromFindInfo(pFindInfo), sizeof(ioreq)); FreeMem(pFindInfo); } return (iRet); }
int OpenFileRemote ( PIOREQ pir, LPHFREMOTE lphFile ) { return (OpenFileRemoteEx(pir, ACCESS_READWRITE, ACTION_OPENEXISTING, 0, lphFile)); }
int OpenFileRemoteEx ( PIOREQ pir, UCHAR uchAccess, USHORT usOptions, ULONG ulAttr, LPHFREMOTE lphFile ) { PRESOURCE pResource = (PRESOURCE)(pir->ir_rh); PFILEINFO pFileInfo; hndlfunc hfnSav; hfunc_t pSav;
int iRet;
if(!(pFileInfo = (PFILEINFO)PAllocElem(SizeofFileRemote))) { KdPrint(("OpenFileRemoteEx: Error creating File structure \r\n")); return -1; // BUGBUG-win9xonly return proper error code
}
mSetBits(pFileInfo->usLocalFlags, FLAG_FILEINFO_INTERNAL_HANDLE);
// HACK save the ioreq structure pointer
pFileInfo->pnextFileInfo = (PFILEINFO)pir;
// Save it
memcpy(LpIoreqFromFileInfo(pFileInfo), pir, sizeof(ioreq));
pir->ir_flags = uchAccess; pir->ir_options = usOptions; pir->ir_attr = ulAttr;
// Plug his resource handle back
pir->ir_rh = pResource->rhPro;
// Plug this in so servers understanding case can use it
pir->ir_uFName = IFSLastElement(pir->ir_ppath)->pe_unichars; pSav = pir->ir_hfunc; memset((LPVOID)&hfnSav, 0, sizeof(hndlfunc)); pir->ir_hfunc = (hfunc_t)&hfnSav;
// and call his function
(*(pResource->pVolTab->vfn_func[VFN_OPEN]))(pir); iRet = pir->ir_error;
pir->ir_hfunc = pSav; // Plug our resource handle
pir->ir_rh = (rh_t)pResource; pir->ir_error = 0; if (!iRet) { // succeeded
// Save his file handle
pFileInfo->fhProFile = pir->ir_fh;
// Save his function table
pFileInfo->hfFileHandle = hfnSav;
// point back to our parent
pFileInfo->pResource = pResource;
#if VERBOSE > 1
KdPrint(("OpenFileRemote: pFileInfo= %x fhPro=%x, read=%x write=%x\r\n" , pFileInfo, pFileInfo->fhProFile, hfnSav.hf_read, hfnSav.hf_write)); #endif //VERBOSE > 1
} else { memcpy(pir, LpIoreqFromFileInfo(pFileInfo), sizeof(ioreq)); FreeMem(pFileInfo); #if VERBOSE > 1
KdPrint(("OpenFileRemote: Error %x \r\n", iRet)); #endif //VERBOSE > 1
pFileInfo = NULL; }
*lphFile = (HFREMOTE)pFileInfo; return (iRet); }
int ReadFileRemote( PFILEINFO pFileInfo, PIOREQ pir, ULONG pos, LPVOID lpBuff, ULONG count ) { int iRet;
if(mQueryBits(pFileInfo->usLocalFlags, FLAG_FILEINFO_INTERNAL_HANDLE)) { pir = (PIOREQ)(pFileInfo->pnextFileInfo); } pir->ir_data = lpBuff; pir->ir_length = count; pir->ir_pos = pos; pir->ir_options = 0; pir->ir_sfn = pFileInfo->sfnFile; pir->ir_pid = pFileInfo->pidFile; pir->ir_user = pFileInfo->userFile; pir->ir_rh = pFileInfo->pResource->rhPro; pir->ir_fh = pFileInfo->fhProFile;
(*(pFileInfo->hfFileHandle.hf_read))(pir); iRet = pir->ir_error; pir->ir_rh = (rh_t)(pFileInfo->pResource); return ((!iRet)?pir->ir_length:-1); }
int WriteFileRemote( PFILEINFO pFileInfo, PIOREQ pir, ULONG pos, LPVOID lpBuff, ULONG count ) { int iRet;
if(mQueryBits(pFileInfo->usLocalFlags, FLAG_FILEINFO_INTERNAL_HANDLE)) { pir = (PIOREQ)(pFileInfo->pnextFileInfo); }
pir->ir_data = lpBuff; pir->ir_length = count; pir->ir_pos = pos; pir->ir_options = 0; pir->ir_sfn = pFileInfo->sfnFile; pir->ir_pid = pFileInfo->pidFile; pir->ir_user = pFileInfo->userFile; pir->ir_rh = pFileInfo->pResource->rhPro; pir->ir_fh = pFileInfo->fhProFile; (*(pFileInfo->hfFileHandle.hf_write))(pir); iRet = pir->ir_error; pir->ir_rh = (rh_t)(pFileInfo->pResource); return ((!iRet)?pir->ir_length:-1); }
int TimeStampRemote( PFILEINFO pFileInfo, LPFILETIME lpFt, int type ) { BOOL fGetType; ioreq ir; PIOREQ pir = &ir; int iRet;
fGetType = ((type==GET_MODIFY_DATETIME)|| (type==GET_LAST_ACCESS_DATETIME)|| (type==GET_CREATION_DATETIME));
pir->ir_flags = (UCHAR)type; pir->ir_sfn = pFileInfo->sfnFile; pir->ir_pid = pFileInfo->pidFile; pir->ir_user = pFileInfo->userFile; pir->ir_rh = pFileInfo->pResource->rhPro; pir->ir_fh = pFileInfo->fhProFile; pir->ir_options = 0; if (!fGetType) { pir->ir_dostime = IFSMgr_Win32ToDosTime(*lpFt); } (*(pFileInfo->hfFileHandle.hf_write))(pir); iRet = pir->ir_error; if (!iRet && fGetType) { *lpFt = IFSMgr_DosToWin32Time(pir->ir_dostime); } return (iRet); }
int CloseFileRemote( PFILEINFO pFileInfo, PIOREQ pir ) { int iRet;
if(mQueryBits(pFileInfo->usLocalFlags, FLAG_FILEINFO_INTERNAL_HANDLE)) { pir = (PIOREQ)(pFileInfo->pnextFileInfo); }
pir->ir_rh = pFileInfo->pResource->rhPro; pir->ir_fh = pFileInfo->fhProFile; pir->ir_options = 0; pir->ir_flags = CLOSE_FINAL; (*(pFileInfo->hfFileHandle.hf_misc->hm_func[HM_CLOSE]))(pir); iRet = pir->ir_error; if (iRet) { KdPrint(("CloseFileRemote: error hf= %x #=%x \r\n", pFileInfo, iRet)); } else { } pir->ir_rh = (rh_t)(pFileInfo->pResource);
if (mQueryBits(pFileInfo->usLocalFlags, FLAG_FILEINFO_INTERNAL_HANDLE)) { memcpy((PIOREQ)(pFileInfo->pnextFileInfo), LpIoreqFromFileInfo(pFileInfo), sizeof(ioreq)); FreeMem(pFileInfo); }
return (iRet); }
int CloseAllRemoteFiles( PRESOURCE pResource ) { PFILEINFO pFileInfo = NULL; PFDB pFdb = NULL; ioreq sIoreq;
for (pFileInfo = pResource->pheadFileInfo; pFileInfo; pFileInfo=pFileInfo->pnextFileInfo) { if (IsDupHandle(pFileInfo)) continue; pFdb = pFileInfo->pFdb; if (pFileInfo->fhProFile) { // Do final close only once
if (!(pFdb->usLocalFlags & FLAG_FDB_FINAL_CLOSE_DONE)) { memset(&sIoreq, 0, sizeof(ioreq)); CloseFileRemote(pFileInfo, &sIoreq); pFdb->usLocalFlags |= FLAG_FDB_FINAL_CLOSE_DONE; }
pFileInfo->fhProFile = 0; if (pFileInfo->hfShadow) { if (mShadowSparse(pFdb->usFlags)) { CloseFileLocal(pFileInfo->hfShadow); pFileInfo->hfShadow = 0; mSetBits(pFileInfo->usLocalFlags, FLAG_FILEINFO_INVALID_HANDLE); } } else { mSetBits(pFileInfo->usLocalFlags, FLAG_FILEINFO_INVALID_HANDLE); } } } for (pFdb = pResource->pheadFdb; pFdb; pFdb = pFdb->pnextFdb) { pFdb->usLocalFlags &= ~FLAG_FDB_FINAL_CLOSE_DONE; } return SRET_OK; }
int CloseAllRemoteFinds( PRESOURCE pResource ) { PFINDINFO pFindInfo = NULL; ioreq sIoreq;
for (pFindInfo = pResource->pheadFindInfo; pFindInfo; pFindInfo=pFindInfo->pnextFindInfo) { if (pFindInfo->fhProFind) { memset(&sIoreq, 0, sizeof(ioreq)); FindCloseRemote(pFindInfo, &sIoreq); pFindInfo->fhProFind = 0; pFindInfo->usLocalFlags |= FLAG_FINDINFO_INVALID_HANDLE; } } return SRET_OK; }
int DisconnectResource( PRESOURCE pResource ) { #ifdef RESOURCE
ioreq sIoreq;
CloseAllRemoteFiles(pResource); CloseAllRemoteFinds(pResource);
memset(&sIoreq, 0, sizeof(ioreq));
Assert(pResource->rhPro); Assert(pResource->pVolTab);
// Let us restore his rh
sIoreq.ir_rh = pResource->rhPro;
// and call his function
(*(pResource->pVolTab->vfn_func[VFN_DISCONNECT]))(&sIoreq);
pResource->rhPro = 0; pResource->pVolTab = 0; return(sIoreq.ir_error); #endif //RESOURCE
return (0); }
#ifdef LATER
int PUBLIC CommitFile( CSCHFILE hf ) { return (-1); }
#endif
/*************************** Utility Functions ******************************/ #ifndef CSC_RECORDMANAGER_WINNT
//for NT, these have been macro-ed to the appropriate Rx Functions
LPVOID AllocMem ( ULONG uSize ) { LPVOID lpBuff;
if (lpBuff = (LPVOID)FGHS(uSize)) { memset(lpBuff, 0, uSize); } return (lpBuff); }
VOID FreeMem ( LPVOID lp ) { // CheckHeap(lp);
if (lp) { RetHeap(lp); } }
//for NT, these have been macro-ed to the appropriate Rx Functions
LPVOID AllocMemPaged( ULONG uSize ) { return NULL; }
//for NT, these have been macro-ed to the appropriate Rx Functions
VOID FreeMemPaged( LPVOID lp ) { lp; }
int GetAttributesLocalEx ( LPSTR lpPath, BOOL fFile, ULONG *lpuAttributes ) { return(GetAttributesLocal(lpPath, lpuAttributes)); }
int CreateDirectoryLocal( LPSTR lpPath ) { return -1; } #endif //ifndef CSC_RECORDMANAGER_WINNT
#ifdef CSC_RECORDMANAGER_WINNT
PELEM PAllocElem ( int cbSize ) { return ((PELEM)AllocMem(cbSize)); }
void FreeElem ( PELEM p ) { FreeMem(p); }
void LinkElem ( PELEM pElem, PPELEM ppHead ) { pElem->pnextElem = *ppHead; *ppHead = pElem; }
PELEM PUnlinkElem ( PELEM pElem, PPELEM ppHead ) { PELEM p; for(;p = *ppHead; ppHead = &(p->pnextElem)) { if (p == pElem) { // Found the guy
*ppHead = p->pnextElem; return (p); } } return (NULL); }
#endif //ifdef CSC_RECORDMANAGER_WINNT
#ifndef CSC_RECORDMANAGER_WINNT
VOID GetSystemTime( _FILETIME *lpft ) { LONG ltime = IFSMgr_Get_NetTime();
*lpft = IFSMgr_NetToWin32Time(ltime);
} #endif
ULONG GetTimeInSecondsSince1970( VOID ) { return ((ULONG)IFSMgr_Get_NetTime()); }
BOOL IterateOnUNCPathElements( USHORT *lpuPath, PATHPROC lpfn, LPVOID lpCookie ) /*++
Routine Description:
This routine takes a unicode UNC path and iterates over each path element, calling the callback function. Thus for a path \\server\share\dir1\dir2\file1.txt, the function makes the following calls to the lpfn callback function
(lpfn)(\\server\share, \\server\share, lpCookie) (lpfn)(\\server\share\dir1, dir1, lpCookie) (lpfn)(\\server\share\dir1\dir2, dir2, lpCookie) (lpfn)(\\server\share\dir1\dir2\file1, file1, lpCookie)
Arguments:
lpuPath NULL terminated unicode string (NOT NT style, just a plain unicode string)
lpfn callback function. If the function returns TRUE on a callback, the iteration proceeds, else it terminates
lpCookie context passed back on each callback
Returns:
return TRUE if the entire iteration went through, FALSE if some error occurred or the callback function terminated the iteration
Notes:
--*/ { int cnt, cntSlashes=0, cbSize; USHORT *lpuT, *lpuLastElement = NULL, *lpuCopy = NULL; BOOL fRet = FALSE;
// DEBUG_PRINT(("InterateOnUNCPathElements:Path on entry =%ws\r\n", lpuPath));
if (!lpuPath || ((cnt = wstrlen(lpuPath)) <= 3)) { return FALSE; }
// check for the first two backslashes
if (!(*lpuPath == (USHORT)'\\') && (*(lpuPath+1) == (USHORT)'\\')) { return FALSE; }
// ensure that the server field is not NULL
if (*(lpuPath+2) == (USHORT)'\\') { return FALSE; }
cbSize = (wstrlen(lpuPath)+1) * sizeof(USHORT);
lpuCopy = (USHORT *)AllocMem(cbSize);
if (!lpuCopy) { return FALSE; }
memcpy(lpuCopy, lpuPath, cbSize);
cntSlashes = 2;
lpuLastElement = lpuCopy;
for (lpuT= lpuCopy+2;; ++lpuT) { if (*lpuT == (USHORT)'\\') { BOOL fContinue;
++cntSlashes;
if (cntSlashes == 3) { if (lpuT == (lpuCopy+2)) { goto bailout; }
continue; }
*lpuT = 0;
fContinue = (lpfn)(lpuCopy, lpuLastElement, lpCookie);
*lpuT = (USHORT)'\\';
if (!fContinue) { goto bailout; }
lpuLastElement = (lpuT+1); } else if (!*lpuT) { (lpfn)(lpuCopy, lpuLastElement, lpCookie); break; } }
fRet = TRUE; bailout:
if (lpuCopy) { FreeMem(lpuCopy); } return (fRet); }
BOOL IsPathUNC( USHORT *lpuPath, int cntMaxChars ) { USHORT *lpuT; int i, cntSlash=0; BOOL fRet = FALSE;
for(lpuT = lpuPath, i=0; (i < cntMaxChars) && *lpuT; lpuT++, ++i) { if (cntSlash <= 1) { // look for the first two backslashes
if (*lpuT != (USHORT)'\\') { break; }
++cntSlash; } else if (cntSlash == 2) { // look for the 3rd one
if (*lpuT == (USHORT)'\\') { if (((DWORD_PTR)lpuT - (DWORD_PTR)lpuPath) < 3) { // NULL server field
break; } else { ++cntSlash; } } } else // all three slashes accounted for
{ Assert(cntSlash == 3);
// if a non-slash character, then this path is OK
fRet = (*lpuT != (USHORT)'\\'); break; } } return (fRet); }
|