📄 apis.c
字号:
__try
{
// This exception will be handled by OsAxsT0.dll if
// we succesfully generate a dump file. The RaisException
// will return if handled, otherwise it will caught by the
// the try catch block.
RaiseException(STATUS_CRASH_DUMP,0,5,&dwArguments[0]);
fHandled = TRUE;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
// We end up here if no dump was captured, in which case we return FALSE
fHandled = FALSE;
if (ERROR_SUCCESS == GetLastError())
{
SetLastError(ERROR_NOT_SUPPORTED);
}
}
Exit:
return fHandled;
}
#if defined(x86)
// Re-Enable optimization
#pragma optimize("",on)
#endif
EFaultRepRetVal APIENTRY ReportFault(LPEXCEPTION_POINTERS pep, DWORD dwMode)
{
if (!CaptureDumpFileOnDevice(-1,-1,(LPCWSTR)pep))
{
return frrvErrNoDW;
}
return frrvOk;
}
BOOL SetInterruptEvent(DWORD idInt) {
long mask;
long pend;
long *ptrPend;
if ((idInt < SYSINTR_DEVICES) || (idInt >= SYSINTR_MAXIMUM))
return FALSE;
idInt -= SYSINTR_DEVICES;
ptrPend = (long *) UserKInfo[KINX_PENDEVENTS];
// calculate which DWORD based on idInt
ptrPend += idInt >> 5; // idInt / 32
idInt &= 0x1f; // idInt % 32
mask = 1 << idInt;
do {
pend = *ptrPend;
if (pend & mask)
return TRUE; // The bit is already set, so all done.
} while (InterlockedTestExchange(ptrPend, pend, pend|mask) != pend);
return TRUE;
}
// Macallan: Power Handler can call SetEvent directly
BOOL CeSetPowerOnEvent (HANDLE hEvt)
{
return SetEvent (hEvt);
}
VOID FreeLibraryAndExitThread(HMODULE hLibModule, DWORD dwExitCode) {
FreeLibrary(hLibModule);
ExitThread(dwExitCode);
}
static CONST WCHAR szHex[] = L"0123456789ABCDEF";
UINT GetTempFileNameW(LPCWSTR lpPathName, LPCWSTR lpPrefixString, UINT uUnique, LPWSTR lpTempFileName) {
DWORD Length, Length2, PassCount, dwAttr;
UINT uMyUnique;
HANDLE hFile;
Length = wcslen(lpPathName);
if (!Length || (Length >= MAX_PATH)) {
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
memcpy(lpTempFileName,lpPathName,Length*sizeof(WCHAR));
if (lpTempFileName[Length-1] != (WCHAR)'\\')
Length++;
lpTempFileName[Length-1] = 0;
dwAttr = GetFileAttributesW(lpTempFileName);
if ((dwAttr == 0xFFFFFFFF) || !(dwAttr & FILE_ATTRIBUTE_DIRECTORY)) {
SetLastError(ERROR_DIRECTORY);
return 0;
}
lpTempFileName[Length-1] = L'\\';
PassCount = 0;
Length2 = wcslen(lpPrefixString);
if (Length2 > 3)
Length2 = 3;
memcpy(&lpTempFileName[Length],lpPrefixString,Length2*sizeof(WCHAR));
Length += Length2;
uUnique &= 0x0000ffff;
if ((Length + 9) > MAX_PATH) { // 4 hex digits, .tmp, and a null
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
lpTempFileName[Length+4] = '.';
lpTempFileName[Length+5] = 't';
lpTempFileName[Length+6] = 'm';
lpTempFileName[Length+7] = 'p';
try_again:
if (!uUnique) {
if (!(uMyUnique = (UINT)Random() & 0x0000ffff)) {
if (!(++PassCount & 0xffff0000))
goto try_again;
SetLastError(ERROR_RETRY);
return 0;
}
} else
uMyUnique = uUnique;
lpTempFileName[Length] = szHex[(uMyUnique >> 12) & 0xf];
lpTempFileName[Length+1] = szHex[(uMyUnique >> 8) & 0xf];
lpTempFileName[Length+2] = szHex[(uMyUnique >> 4) & 0xf];
lpTempFileName[Length+3] = szHex[uMyUnique & 0xf];
lpTempFileName[Length+8] = 0;
if (!uUnique) {
if ((hFile = CreateFileW(lpTempFileName, GENERIC_READ, 0, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0)) == INVALID_HANDLE_VALUE) {
switch (GetLastError()) {
case ERROR_FILE_EXISTS:
case ERROR_ALREADY_EXISTS:
if (!(++PassCount & 0xffff0000))
goto try_again;
break;
}
return 0;
} else
xxx_CloseHandle(hFile);
}
return uMyUnique;
}
// On success, return length of lpCanonicalPathName. Otherwise, return 0.
DWORD
CeGetCanonicalPathNameW(
LPCWSTR lpPathName,
LPWSTR lpCanonicalPathName,
DWORD cchCanonicalPathName,
DWORD dwReserved
)
{
ULONG cchPathName; // length of lpPathName; number of remaining characters
ULONG ulPathIndex; // current index in path
ULONG ulNextDirectoryIndex; // index(next directory relative to uiPathIndex)
ULONG ulJumpOffset; // skip extraneous '\\'-s or '/'-s
PATH Path; // path object
PATH_NODE PathNode; // current path node
PATH_NODE_TYPE PathNodeType; // type of current path node
HRESULT hResult; // StringCchLength return
// Note: lpCanonicalPathName can be NULL
if (!lpPathName) {
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
// Calculate length of lpPathName; StringCchLength succeeds if lpPathName <= MAX_PATH
hResult = StringCchLength(lpPathName, MAX_PATH, &cchPathName);
if (FAILED(hResult)) {
SetLastError(ERROR_FILENAME_EXCED_RANGE);
return 0;
}
// Initialize path object
InitPath(&Path);
// Determine path type
GetPathType(lpPathName, cchPathName, &Path.PathType);
// Jump to first path node; Subtract jump offset from cchPathName
ulPathIndex = GetIndexOfNextPathNodeInPath(lpPathName, &cchPathName);
// Process path name
while (cchPathName > 0) {
// Reset path node type
PathNodeType = PNT_UNKNOWN;
ulNextDirectoryIndex = GetIndexOfNextDirectoryInPath(&lpPathName[ulPathIndex], cchPathName);
if (ulNextDirectoryIndex > 0) {
// Directory
GetPathNodeType(
&lpPathName[ulPathIndex], ulNextDirectoryIndex, &PathNodeType);
switch (PathNodeType) {
case PNT_SELF:
break;
case PNT_PARENT:
PopPathNode(&Path);
break;
case PNT_FILE:
PathNode.ulPathIndex = ulPathIndex;
PathNode.ulNameLength = ulNextDirectoryIndex;
PathNode.PathNodeType = PathNodeType;
PushPathNode(&Path, PathNode);
break;
default:
// This should never happen
DEBUGCHK(0);
}
// Jump over path node
cchPathName -= (1 + ulNextDirectoryIndex);
ulPathIndex += (1 + ulNextDirectoryIndex);
// Ignore extraneous '\\'-s or '/'-s; Subtract jump offset from cchPathName
ulJumpOffset = GetIndexOfNextPathNodeInPath(&lpPathName[ulPathIndex], &cchPathName);
ulPathIndex += ulJumpOffset;
}
else {
// File; Last node in path
GetPathNodeType(&lpPathName[ulPathIndex], cchPathName, &PathNodeType);
switch (PathNodeType) {
case PNT_SELF:
break;
case PNT_PARENT:
PopPathNode(&Path);
break;
case PNT_FILE:
PathNode.ulPathIndex = ulPathIndex;
PathNode.ulNameLength = cchPathName;
PathNode.PathNodeType = PathNodeType;
PushPathNode(&Path, PathNode);
break;
default:
// This should never happen
DEBUGCHK(0);
}
cchPathName = 0;
}
}
// Calculate (cache) length of canonical path name
cchPathName = GetPathLength(&Path);
// If lpCanonicalPathName == NULL, then caller is only interested in the
// length of the canonicalized version of lpPathName; Ignore cchCanonicalPathName
if (lpCanonicalPathName == NULL) {
return cchPathName;
}
// lpCanonicalPathName must be large enough to contain canonical path name
if (cchPathName > cchCanonicalPathName) {
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return 0;
}
// Pop canonical path from stack into lpCanonicalPathName
return PopPath(&Path, lpPathName, lpCanonicalPathName);
}
#define FS_COPYBLOCK_SIZE (64*1024) // Perfect size for a VirtualAlloc
#define COPYFILEEX_FAIL_IF_DST_EXISTS (1 << 0)
#define COPYFILEEX_SRC_READ_ONLY (1 << 1)
#define COPYFILEEX_QUIET (1 << 2)
#define COPYFILEEX_RET (1 << 3)
#define COPYFILEEX_DELETE_DST (1 << 4)
BOOL
CopyFileExW(
LPCWSTR lpExistingFileName,
LPCWSTR lpNewFileName,
LPPROGRESS_ROUTINE lpProgressRoutine,
LPVOID lpData,
LPBOOL pbCancel,
DWORD dwCopyFlags // NT ignores COPY_FILE_RESTARTABLE
)
{
// File support
HANDLE hExistingFile, hNewFile; // Source and destination file handles
DWORD dwFileAttributes; // Source file attributes
LARGE_INTEGER liExistingFileSize; // Source file size
FILETIME ftCreation, ftLastAccess, ftLastWrite; // Source file times
WCHAR lpszCExisting[MAX_PATH]; // Canonical version of lpszExisting
WCHAR lpszCNew[MAX_PATH]; // Canonical version of lpszNew
BOOL fNewFileExists = FALSE; // Destination file exists
// Copy support
LPBYTE lpbCopyChunk = NULL; // Copy buffer
DWORD dwBytesRead, dwBytesWritten; // Copy bytes read and written
DWORD dwCopyProgressResult; // CopyProgressRoutine result
LARGE_INTEGER liTotalBytesTransferred; // Bytes transferred
// Result support
DWORD dwError; // Capture last error of nested calls
// Status flags
DWORD dwFlags = COPYFILEEX_DELETE_DST; // bit 0=fFailIfDestinationExists;
// bit 1=fDestinationFileExists
// bit 2=fSourceFileReadyOnly
// bit 3=fQuiet (Call CopyProgressRoutine)
// bit 4=fRet
// bit 5=fDeleteDestinationFile
// Canonicalize lpExistingFileName and lpNewFileName
if (!CeGetCanonicalPathName(lpNewFileName, lpszCNew, MAX_PATH, 0)) {
return FALSE;
}
if (!CeGetCanonicalPathName(lpExistingFileName, lpszCExisting, MAX_PATH, 0)) {
return FALSE;
}
if (dwCopyFlags & COPY_FILE_FAIL_IF_EXISTS) dwFlags |= COPYFILEEX_FAIL_IF_DST_EXISTS;
// Open source file
hExistingFile = CreateFile(lpszCExisting, GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
if (INVALID_HANDLE_VALUE == hExistingFile) {
return FALSE;
}
if (!(dwFlags & COPYFILEEX_FAIL_IF_DST_EXISTS) &&
(0 == _wcsnicmp(lpszCExisting, lpszCNew, MAX_PATH))) {
// Cannot copy a file onto itself
VERIFY(CloseHandle(hExistingFile));
SetLastError(ERROR_SHARING_VIOLATION);
return FALSE;
}
// Get source file's attributes
dwFileAttributes = GetFileAttributes(lpszCExisting);
if (0xFFFFFFFF == dwFileAttributes) {
// This shouldn't happen
ERRORMSG(1, (_T(
"CopyFileEx: Failed to get attributes of open file %s\r\n"
), lpszCExisting));
VERIFY(CloseHandle(hExistingFile));
return FALSE;
}
else {
// Remove ROM flag to/and make sure the destination file can be written to
dwFileAttributes &= ~(FILE_ATTRIBUTE_INROM);
if (dwFileAttributes & FILE_ATTRIBUTE_READONLY) dwFlags |= COPYFILEEX_SRC_READ_ONLY;
dwFileAttributes = dwFileAttributes & ~FILE_ATTRIBUTE_READONLY;
}
// TODO: Since we move the destination file's file pointer, should we allow shared access?
// Attempt to open destination file
hNewFile = CreateFile(
lpszCNew,
GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
0,
CREATE_NEW,
dwFileAttributes,
0);
if (INVALID_HANDLE_VALUE == hNewFile) {
// The destination file already exists
fNewFileExists = TRUE;
if (dwFlags & COPYFILEEX_FAIL_IF_DST_EXISTS) {
VERIFY(CloseHandle(hExistingFile));
return FALSE;
}
// Open the destination file
hNewFile = CreateFile(
lpszCNew,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -