|
|
/*
* DemLFN.H * * Include file for all the things that lfn implementation is using * * VadimB Created 09-12-96 * */
/* --------------------------------------------------------------------------
LFN function numbers defined as enum
-------------------------------------------------------------------------- */
typedef enum tagLFNFunctionNumber { fnLFNCreateDirectory = 0x39, fnLFNRemoveDirectory = 0x3A, fnLFNSetCurrentDirectory = 0x3B, fnLFNDeleteFile = 0x41, fnLFNGetSetFileAttributes= 0x43, fnLFNGetCurrentDirectory = 0x47, fnLFNFindFirstFile = 0x4e, fnLFNFindNextFile = 0x4f, fnLFNMoveFile = 0x56, fnLFNGetPathName = 0x60, fnLFNOpenFile = 0x6c, fnLFNGetVolumeInformation = 0xa0, fnLFNFindClose = 0xa1, fnLFNGetFileInformationByHandle = 0xa6, fnLFNFileTime = 0xa7, fnLFNGenerateShortFileName = 0xa8, fnLFNSubst = 0xaa } enumLFNFunctionNumber;
#define fnLFNMajorFunction 0x71
/* --------------------------------------------------------------------------
Useful Macros
-------------------------------------------------------------------------- */
// returns : count of elements in an array
#define ARRAYCOUNT(rgX) (sizeof(rgX)/sizeof(rgX[0]))
// returns : length (in characters) of a counted Unicode string
#define UNICODESTRLENGTH(pStr) ((pStr)->Length >> 1)
// returns : whether an api (like GetShortPathName) has returned count of
// characters required and failed to succeed (due to buffer being too short)
// Note that api here means win32 api, not rtl api (as return value is assumed
// be count of chars, not bytes
#define CHECK_LENGTH_RESULT_USTR(dwStatus, pUnicodeString) \
CHECK_LENGTH_RESULT(dwStatus, \ (pUnicodeString)->MaximumLength, \ (pUnicodeString)->Length)
// returns : dwStatus - whether an api that returns char count
// succeeded on a call, takes string count variables instead of
// unicode string structure (see prev call)
#define CHECK_LENGTH_RESULT(dwStatus, MaximumLength, Length) \
{ \ if (0 == dwStatus) { \ dwStatus = GET_LAST_STATUS(); \ } \ else { \ Length = (USHORT)dwStatus * sizeof(WCHAR); \ if ((MaximumLength) > (Length)) { \ dwStatus = STATUS_SUCCESS; \ } \ else { \ dwStatus = NT_STATUS_FROM_WIN32(ERROR_BUFFER_OVERFLOW); \ Length = 0; \ } \ } \ }
// these 2 macros are identical to the ones above but dwStatus is assumed
// to represent a byte count rather than the char count (as in rtl apis)
#define CHECK_LENGTH_RESULT_RTL(dwStatus, MaximumLength, Length) \
{ \ if (0 == dwStatus) { \ dwStatus = GET_LAST_STATUS(); \ } \ else { \ Length = (USHORT)dwStatus; \ if ((MaximumLength) > (Length)) { \ dwStatus = STATUS_SUCCESS; \ } \ else { \ dwStatus = NT_STATUS_FROM_WIN32(ERROR_BUFFER_OVERFLOW); \ Length = 0; \ } \ } \ }
#define CHECK_LENGTH_RESULT_RTL_USTR(dwStatus, pUnicodeString) \
CHECK_LENGTH_RESULT_RTL(dwStatus, \ (pUnicodeString)->MaximumLength, \ (pUnicodeString)->Length)
/* --------------------------------------------------------------------------
STATUS and ERROR code macros
-------------------------------------------------------------------------- */
// returns nt status code assembled from separate parts
// see ntstatus.h for details
#define MAKE_STATUS_CODE(Severity,Facility,ErrorCode) \
(((ULONG)Severity << 30) | ((ULONG)Facility << 16) | ((ULONG)ErrorCode))
#define ERROR_CODE_FROM_NT_STATUS(Status) \
((ULONG)Status & 0xffff)
#define FACILITY_FROM_NT_STATUS(Status) \
(((ULONG)Status >> 16) & 0x0fff)
// returns TRUE if nt status signifies error
#define IS_NT_STATUS_ERROR(Status) \
(((ULONG)Status >> 30) == STATUS_SEVERITY_ERROR)
// converts win32 error code to nt status code
#define NT_STATUS_FROM_WIN32(dwErrorCode) \
MAKE_STATUS_CODE(STATUS_SEVERITY_WARNING,FACILITY_WIN32,dwErrorCode)
// converts nt status to win32 error code
#define WIN32_ERROR_FROM_NT_STATUS(Status) \
RtlNtStatusToDosError(Status)
// returns last win32 error in nt status format
#define GET_LAST_STATUS() NT_STATUS_FROM_WIN32(GetLastError())
/* --------------------------------------------------------------------------
String Conversion macros and functions
-------------------------------------------------------------------------- */
//
// Macro to provide init fn for oem counted strings
//
#define RtlInitOemString(lpOemStr,lpBuf) \
RtlInitString(lpOemStr, lpBuf)
//
// defines a conversion fn from Unicode to Destination type (as accepted by the
// application (oem or ansi)
//
//
typedef NTSTATUS (*PFNUNICODESTRINGTODESTSTRING)( PVOID pDestString, // counted oem/ansi string -- returned
PUNICODE_STRING pUnicodeString, // unicode string to convert
BOOLEAN fAllocateDestination, // allocate destination dynamically ?
BOOLEAN fVerifyTranslation); // should the translation unicode->oem/ansi be verified ?
//
// defines a conversion fn from Oem/Ansi to Unicode type (as needed by dem)
//
//
typedef NTSTATUS (*PFNSRCSTRINGTOUNICODESTRING)( PUNICODE_STRING pUnicodeString, // counted unicode string -- returned
PVOID pSrcString, // oem or ansi string to convert
BOOLEAN fAllocateDestination); // allocate destination dynamically ?
//
// these two macros define apis we use for consistency across lfn support land
//
#define DemAnsiStringToUnicodeString RtlAnsiStringToUnicodeString
#define DemOemStringToUnicodeString RtlOemStringToUnicodeString
//
// these two functions provide actual translations
// oem/ansi to unicode
//
NTSTATUS DemUnicodeStringToAnsiString( PANSI_STRING pAnsiString, PUNICODE_STRING pUnicodeString, BOOLEAN fAllocateResult, BOOLEAN fVerifyTranslation);
NTSTATUS DemUnicodeStringToOemString( POEM_STRING pOemString, PUNICODE_STRING pUnicodeString, BOOLEAN fAllocateResult, BOOLEAN fVerifyTranslation);
//
// This macro returns a pointer (in the current teb) to a unicode string,
// we are using this buffer for unicode/ansi/oem translations
// be careful with inter-function passing of this buffer
// Many Win32's Ansi apis use this buffer as a translation buffer
//
#define GET_STATIC_UNICODE_STRING_PTR() \
(&NtCurrentTeb()->StaticUnicodeString)
/* --------------------------------------------------------------------------
DOS and Windows call frame definition These macros allow for access to the User's registers, that is registers which the calling application receives after dos returns
-------------------------------------------------------------------------- */
/*
* See dossym.inc for more details (if any) * These values represent offsets from user stack top * during the system call (again, as defined in dossym.inc) * * The stack layout is formed by dos and mimicked by kernel in windows * */
#pragma pack(1)
// macro: used to declare a named word size register
//
#define DECLARE_WORDREG(Name) \
union { \ USHORT User_ ## Name ## X; \ struct { \ UCHAR User_ ## Name ## L; \ UCHAR User_ ## Name ## H; \ }; \ }
typedef struct tagUserFrame {
DECLARE_WORDREG(A); // ax 0x00
DECLARE_WORDREG(B); // bx 0x02
DECLARE_WORDREG(C); // cx 0x04
DECLARE_WORDREG(D); // dx 0x06
USHORT User_SI; // si 0x8
USHORT User_DI; // di 0xa
USHORT User_BP; // bp 0xc
USHORT User_DS; // ds 0xe
USHORT User_ES; // es 0x10
union { USHORT User_IP; // ip 0x12 -- Real Mode IP
USHORT User_ProtMode_F; // prot-mode Flags (see i21entry.asm)
};
USHORT User_CS; // cs 0x14 -- this is Real Mode CS!
USHORT User_F; // f 0x16 -- this is Real Mode Flags!!!
} DEMUSERFRAME;
typedef DEMUSERFRAME UNALIGNED *PDEMUSERFRAME;
#pragma pack()
// macro: retrieve flat ptr given separate segment/offset and prot mode
// flag
//
#define dempGetVDMPtr(Segment, Offset, fProtMode) \
Sim32GetVDMPointer((ULONG)MAKELONG(Offset, Segment), 0, (UCHAR)fProtMode)
/*
* Macros to set misc registers on user's stack - * this is equivalent to what dos kernel does with regular calls * * remember that ax is set according to the call result * (and then dos takes care of it) * */
#define getUserDSSI(pUserEnv, fProtMode) \
dempGetVDMPtr(getUserDS(pUserEnv), getUserSI(pUserEnv), fProtMode)
#define getUserDSDX(pUserEnv, fProtMode) \
dempGetVDMPtr(getUserDS(pUserEnv), getUserDX(pUserEnv), fProtMode)
#define getUserESDI(pUserEnv, fProtMode) \
dempGetVDMPtr(getUserES(pUserEnv), getUserDI(pUserEnv), fProtMode)
#define setUserReg(pUserEnv, Reg, Value) \
( ((PDEMUSERFRAME)pUserEnv)->User_ ## Reg = Value )
#define getUserReg(pUserEnv, Reg) \
(((PDEMUSERFRAME)pUserEnv)->User_ ## Reg)
#define getUserAX(pUserEnv) getUserReg(pUserEnv,AX)
#define getUserBX(pUserEnv) getUserReg(pUserEnv,BX)
#define getUserCX(pUserEnv) getUserReg(pUserEnv,CX)
#define getUserDX(pUserEnv) getUserReg(pUserEnv,DX)
#define getUserSI(pUserEnv) getUserReg(pUserEnv,SI)
#define getUserDI(pUserEnv) getUserReg(pUserEnv,DI)
#define getUserES(pUserEnv) getUserReg(pUserEnv,ES)
#define getUserDS(pUserEnv) getUserReg(pUserEnv,DS)
#define getUserAL(pUserEnv) getUserReg(pUserEnv,AL)
#define getUserAH(pUserEnv) getUserReg(pUserEnv,AH)
#define getUserBL(pUserEnv) getUserReg(pUserEnv,BL)
#define getUserBH(pUserEnv) getUserReg(pUserEnv,BH)
#define getUserCL(pUserEnv) getUserReg(pUserEnv,CL)
#define getUserCH(pUserEnv) getUserReg(pUserEnv,CH)
#define getUserDL(pUserEnv) getUserReg(pUserEnv,DL)
#define getUserDH(pUserEnv) getUserReg(pUserEnv,DH)
#define setUserAX(Value, pUserEnv) setUserReg(pUserEnv, AX, Value)
#define setUserBX(Value, pUserEnv) setUserReg(pUserEnv, BX, Value)
#define setUserCX(Value, pUserEnv) setUserReg(pUserEnv, CX, Value)
#define setUserDX(Value, pUserEnv) setUserReg(pUserEnv, DX, Value)
#define setUserSI(Value, pUserEnv) setUserReg(pUserEnv, SI, Value)
#define setUserDI(Value, pUserEnv) setUserReg(pUserEnv, DI, Value)
#define setUserAL(Value, pUserEnv) setUserReg(pUserEnv, AL, Value)
#define setUserAH(Value, pUserEnv) setUserReg(pUserEnv, AH, Value)
#define setUserBL(Value, pUserEnv) setUserReg(pUserEnv, BL, Value)
#define setUserBH(Value, pUserEnv) setUserReg(pUserEnv, BH, Value)
#define setUserCL(Value, pUserEnv) setUserReg(pUserEnv, CL, Value)
#define setUserCH(Value, pUserEnv) setUserReg(pUserEnv, CH, Value)
#define setUserDL(Value, pUserEnv) setUserReg(pUserEnv, DL, Value)
#define setUserDH(Value, pUserEnv) setUserReg(pUserEnv, DH, Value)
//
// These macros are supposed to be used ONLY when being called from
// protected mode Windows (i.e. krnl386 supplies proper stack)
//
#define getUserPModeFlags(pUserEnv) getUserReg(pUserEnv, ProtMode_F)
#define setUserPModeFlags(Value, pUserEnv) setUserReg(pUserEnv, ProtMode_F, Value)
/* --------------------------------------------------------------------------
Volume information definitions as they apply to a GetVolumeInformation api
-------------------------------------------------------------------------- */
typedef struct tagLFNVolumeInformation { DWORD dwFSNameBufferSize; LPSTR lpFSNameBuffer; DWORD dwMaximumFileNameLength; DWORD dwMaximumPathNameLength; DWORD dwFSFlags; } LFNVOLUMEINFO, *PLFNVOLUMEINFO, *LPLFNVOLUMEINFO;
//
// defines a flag that indicates LFN api support on a volume
//
#define FS_LFN_APIS 0x00004000UL
//
// allowed lfn volume flags
//
#define LFN_FS_ALLOWED_FLAGS \
(FS_CASE_IS_PRESERVED | FS_CASE_SENSITIVE | \ FS_UNICODE_STORED_ON_DISK | FS_VOL_IS_COMPRESSED | \ FS_LFN_APIS)
/* --------------------------------------------------------------------------
File Time /Dos time conversion definitions
-------------------------------------------------------------------------- */
//
// minor code to use in demLFNFileTimeControl
//
typedef enum tagFileTimeControlMinorCode {
fnFileTimeToDosDateTime = 0, fnDosDateTimeToFileTime = 1
} enumFileTimeControlMinorCode;
// this constant masks enumFileTimeControlMinorCode values
//
#define FTCTL_CODEMASK (UINT)0x000F
// this flag tells file time control to use UTC time in conversion
//
#define FTCTL_UTCTIME (UINT)0x0010
//
// structure that is used in time conversion calls in demlfn.c
//
typedef struct tagLFNFileTimeInfo { USHORT uDosDate; USHORT uDosTime; USHORT uMilliseconds; // spill-over
} LFNFILETIMEINFO, *PLFNFILETIMEINFO, *LPLFNFILETIMEINFO;
//
// These functions determine whether the target file's time should not be
// converted to local time -- such as files from the cdrom
//
BOOL dempUseUTCTimeByHandle(HANDLE hFile); BOOL dempUseUTCTimeByName(PUNICODE_STRING pFileName);
/* --------------------------------------------------------------------------
Get/Set File attributes definitions
-------------------------------------------------------------------------- */
typedef enum tagGetSetFileAttributesMinorCode { fnGetFileAttributes = 0, fnSetFileAttributes = 1, fnGetCompressedFileSize = 2, fnSetLastWriteDateTime = 3, fnGetLastWriteDateTime = 4, fnSetLastAccessDateTime = 5, fnGetLastAccessDateTime = 6, fnSetCreationDateTime = 7, fnGetCreationDateTime = 8 } enumGetSetFileAttributesMinorCode;
typedef union tagLFNFileAttributes {
USHORT wFileAttributes; // file attrs
LFNFILETIMEINFO TimeInfo; // for date/time
DWORD dwFileSize; // for compressed file size
} LFNFILEATTRIBUTES, *PLFNFILEATTRIBUTES;
/* --------------------------------------------------------------------------
Get/Set File Time (by handle) definitions - fn 57h handled by demFileTimes
-------------------------------------------------------------------------- */
//
// flag in SFT indicating that entry references a device (com1:, lpt1:, etc)
//
#define SFTFLAG_DEVICE_ID 0x0080
//
// Minor code for file time requests
//
typedef enum tagFileTimeMinorCode { fnFTGetLastWriteDateTime = 0x00, fnFTSetLastWriteDateTime = 0x01, fnFTGetLastAccessDateTime = 0x04, fnFTSetLastAccessDateTime = 0x05, fnFTGetCreationDateTime = 0x06, fnFTSetCreationDateTime = 0x07 } enumFileTimeMinorCode;
/* --------------------------------------------------------------------------
Open File (function 716ch) definitions largely equivalent to handling fn 6ch
-------------------------------------------------------------------------- */
//
// Access flags
//
#define DEM_OPEN_ACCESS_READONLY 0x0000
#define DEM_OPEN_ACCESS_WRITEONLY 0x0001
#define DEM_OPEN_ACCESS_READWRITE 0x0002
#define DEM_OPEN_ACCESS_RESERVED 0x0003
// Not supported
#define DEM_OPEN_ACCESS_RO_NOMODLASTACCESS 0x0004
#define DEM_OPEN_ACCESS_MASK 0x000F
//
// Share flags
//
#define DEM_OPEN_SHARE_COMPATIBLE 0x0000
#define DEM_OPEN_SHARE_DENYREADWRITE 0x0010
#define DEM_OPEN_SHARE_DENYWRITE 0x0020
#define DEM_OPEN_SHARE_DENYREAD 0x0030
#define DEM_OPEN_SHARE_DENYNONE 0x0040
#define DEM_OPEN_SHARE_MASK 0x0070
//
// Open flags
//
#define DEM_OPEN_FLAGS_NOINHERIT 0x0080
#define DEM_OPEN_FLAGS_NO_BUFFERING 0x0100
#define DEM_OPEN_FLAGS_NO_COMPRESS 0x0200
// Not supported
#define DEM_OPEN_FLAGS_ALIAS_HINT 0x0400
#define DEM_OPEN_FLAGS_NOCRITERR 0x2000
#define DEM_OPEN_FLAGS_COMMIT 0x4000
#define DEM_OPEN_FLAGS_VALID \
(DEM_OPEN_FLAGS_NOINHERIT | DEM_OPEN_FLAGS_NO_BUFFERING | \ DEM_OPEN_FLAGS_NO_COMPRESS | DEM_OPEN_FLAGS_ALIAS_HINT | \ DEM_OPEN_FLAGS_NOCRITERR | DEM_OPEN_FLAGS_COMMIT) #define DEM_OPEN_FLAGS_MASK 0xFF00
//
// Action flags
//
// DEM_OPEN_FUNCTION_FILE_CREATE combines with action_file_open or
// action_file_truncate flags
#define DEM_OPEN_ACTION_FILE_CREATE 0x0010
#define DEM_OPEN_ACTION_FILE_OPEN 0x0001
#define DEM_OPEN_ACTION_FILE_TRUNCATE 0x0002
//
// resulting action (returned to the app)
//
#define ACTION_OPENED 0x0001
#define ACTION_CREATED_OPENED 0x0002
#define ACTION_REPLACED_OPENED 0x0003
/* --------------------------------------------------------------------------
Additional file attribute definitions
-------------------------------------------------------------------------- */
// Volume id attribute
#define DEM_FILE_ATTRIBUTE_VOLUME_ID 0x00000008L
//
// Valid file attributes mask as understood by dos
//
#define DEM_FILE_ATTRIBUTE_VALID \
(FILE_ATTRIBUTE_READONLY| FILE_ATTRIBUTE_HIDDEN| \ FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY | \ FILE_ATTRIBUTE_ARCHIVE | DEM_FILE_ATTRIBUTE_VOLUME_ID)
//
// Valid to set attributes
//
#define DEM_FILE_ATTRIBUTE_SET_VALID \
(FILE_ATTRIBUTE_READONLY| FILE_ATTRIBUTE_HIDDEN| \ FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_ARCHIVE)
/* --------------------------------------------------------------------------
FindFirst/FindNext definitions
-------------------------------------------------------------------------- */
//
// Definition for the handle table entries
// Handle (which is returned to the app) references this entry
// providing all the relevant info for FindFirst/FindNext
//
typedef struct tagLFNFindHandleTableEntry { union { HANDLE hFindHandle; // handle for searching
UINT nNextFreeEntry; };
USHORT wMustMatchAttributes; USHORT wSearchAttributes;
UNICODE_STRING unicodeFileName; // counted file name string,
// only used if matched a vol label
// process id, aka pdb requesting this handle
// or 0xffff if the entry is empty
USHORT wProcessPDB;
} LFN_SEARCH_HANDLE_ENTRY, *PLFN_SEARCH_HANDLE_ENTRY;
//
// Definition of a handle table
// Table is dynamic and it expands/shrinks as necessary
//
typedef struct tagFindHandleTable {
PLFN_SEARCH_HANDLE_ENTRY pHandleTable; UINT nTableSize; // total size in entries
UINT nFreeEntry; // free list head
UINT nHandleCount; // handles stored (bottom)
} DemSearchHandleTable;
//
// Definitions of a constants used in managing handle table
//
// initial table size
#define LFN_SEARCH_HANDLE_INITIAL_SIZE 0x20
// handle table growth increment
#define LFN_SEARCH_HANDLE_INCREMENT 0x10
// used to mark a last free list entry
#define LFN_SEARCH_HANDLE_LIST_END ((UINT)-1)
//
// Application receives handles in format
// LFN_DOS_HANDLE_MASK + (index to the handle table)
// so that it looks legit to the app
//
#define LFN_DOS_HANDLE_MASK ((USHORT)0x4000)
// max number of search handles we can support
#define LFN_DOS_HANDLE_LIMIT ((USHORT)0x3FFF)
//
// Date/Time format as returned in WIN32_FIND_DATAA structure
//
typedef enum tagLFNDateTimeFormat { dtfWin32 = 0, // win32 file time/date format
dtfDos = 1 // dos date time format
} enumLFNDateTimeFormat;
/* --------------------------------------------------------------------------
GetPathName definitions
-------------------------------------------------------------------------- */
//
// minor code for the fn 7160h
//
typedef enum tagFullPathNameMinorCode { fnGetFullPathName = 0, fnGetShortPathName = 1, fnGetLongPathName = 2 } enumFullPathNameMinorCode;
/* --------------------------------------------------------------------------
Subst function definitions
-------------------------------------------------------------------------- */
//
// minor code for the fn 71aah
// used in demLFNSubstControl
//
typedef enum tagSubstMinorCode { fnCreateSubst = 0, fnRemoveSubst = 1, fnQuerySubst = 2 } enumSubstMinorCode;
|