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.
 
 
 
 
 
 

1398 lines
31 KiB

/*++
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);
}