diff --git a/Sources/Plasma/NucleusLib/pnAsyncCore/Private/pnAcIo.h b/Sources/Plasma/NucleusLib/pnAsyncCore/Private/pnAcIo.h
index 287e3a4b..e789cb41 100644
--- a/Sources/Plasma/NucleusLib/pnAsyncCore/Private/pnAcIo.h
+++ b/Sources/Plasma/NucleusLib/pnAsyncCore/Private/pnAcIo.h
@@ -64,174 +64,6 @@ typedef struct AsyncCancelIdStruct * AsyncCancelId;
const unsigned kAsyncSocketBufferSize = 1460;
-enum EFileError {
- kFileSuccess,
- kFileErrorInvalidParameter,
- kFileErrorFileNotFound,
- kFileErrorPathNotFound,
- kFileErrorAccessDenied,
- kFileErrorSharingViolation,
- kNumFileErrors
-};
-
-EFileError AsyncGetLastFileError ();
-
-const wchar_t * FileErrorToString (EFileError error);
-
-
-/****************************************************************************
-*
-* File notifications
-*
-***/
-
-enum EAsyncNotifyFile {
- kNotifyFileFlush,
- kNotifyFileRead,
- kNotifyFileWrite,
- kNotifyFileSequence,
- kNumFileNotifications
-};
-
-struct AsyncNotifyFile {
- void * param;
- AsyncId asyncId;
-};
-
-struct AsyncNotifyFileConnect : AsyncNotifyFile {
- uint64_t fileSize;
- uint64_t fileLastWriteTime;
-};
-
-struct AsyncNotifyFileFlush : AsyncNotifyFile {
- EFileError error;
- uint64_t truncateSize;
-};
-
-struct AsyncNotifyFileRead : AsyncNotifyFile {
- uint64_t offset;
- uint8_t * buffer;
- unsigned bytes;
-};
-
-typedef AsyncNotifyFileRead AsyncNotifyFileWrite;
-
-struct AsyncNotifyFileSequence : AsyncNotifyFile {
- // no additional fields
-};
-
-typedef void (* FAsyncNotifyFileProc)(
- AsyncFile file,
- EAsyncNotifyFile code,
- AsyncNotifyFile * notify,
- void ** userState
-);
-
-
-/****************************************************************************
-*
-* File I/O functions
-*
-***/
-
-// Desired access
-const unsigned kAsyncFileReadAccess = 0x80000000;
-const unsigned kAsyncFileWriteAccess = 0x40000000;
-// Open mode (creation disposition)
-const unsigned kAsyncFileModeCreateNew = 1;
-const unsigned kAsyncFileModeCreateAlways = 2;
-const unsigned kAsyncFileModeOpenExisting = 3;
-const unsigned kAsyncFileModeOpenAlways = 4;
-// Share mode flags
-const unsigned kAsyncFileShareRead = 0x00000001;
-const unsigned kAsyncFileShareWrite = 0x00000002;
-
-AsyncFile AsyncFileOpen (
- const wchar_t fullPath[],
- FAsyncNotifyFileProc notifyProc,
- EFileError * error,
- unsigned desiredAccess,
- unsigned openMode,
- unsigned shareModeFlags, // optional
- void * userState, // optional
- uint64_t * fileSize, // optional
- uint64_t * fileLastWriteTime // optional
-);
-
-// Use with AsyncFileDelete/AsyncFileFlushBuffers
-const uint64_t kAsyncFileDontTruncate = (uint64_t) -1;
-
-// This function may ONLY be called when there is no outstanding I/O against a file
-// and no more I/O will be initiated against it. This function guarantees that it
-// will close the system file handle before it returns to that another open against
-// the same filename can succeed.
-void AsyncFileClose (
- AsyncFile file,
- uint64_t truncateSize
-);
-
-void AsyncFileSetLastWriteTime (
- AsyncFile file,
- uint64_t lastWriteTime
-);
-
-uint64_t AsyncFileGetLastWriteTime (
- const wchar_t fileName[]
-);
-
-// Truncation occurs atomically, any writes which occur after
-// AsyncFileFlushBuffers will be queued until the truncation completes
-AsyncId AsyncFileFlushBuffers (
- AsyncFile file,
- uint64_t truncateSize,
- bool notify,
- void * param
-);
-
-const unsigned kAsyncFileRwNotify = 1<<0;
-const unsigned kAsyncFileRwSync = 1<<1;
-
-AsyncId AsyncFileRead (
- AsyncFile file,
- uint64_t offset,
- void * buffer,
- unsigned bytes,
- unsigned flags,
- void * param
-);
-
-// Buffer must stay valid until I/O is completed
-AsyncId AsyncFileWrite (
- AsyncFile file,
- uint64_t offset,
- const void * buffer,
- unsigned bytes,
- unsigned flags,
- void * param
-);
-
-// Inserts a "null operation" into the list of reads and writes. The callback
-// will be called when all preceding operations have successfully completed.
-AsyncId AsyncFileCreateSequence (
- AsyncFile file,
- bool notify,
- void * param
-);
-
-enum EFileSeekFrom {
- kFileSeekFromBegin,
- kFileSeekFromCurrent,
- kFileSeekFromEnd,
- kNumFileSeekFroms
-};
-
-bool AsyncFileSeek (
- AsyncFile file,
- uint64_t distance,
- EFileSeekFrom seekFrom
-);
-
-
/****************************************************************************
*
* Socket connect packet
diff --git a/Sources/Plasma/NucleusLib/pnAsyncCore/Private/pnAcLog.cpp b/Sources/Plasma/NucleusLib/pnAsyncCore/Private/pnAcLog.cpp
index 56fa0e39..de48ee9e 100644
--- a/Sources/Plasma/NucleusLib/pnAsyncCore/Private/pnAcLog.cpp
+++ b/Sources/Plasma/NucleusLib/pnAsyncCore/Private/pnAcLog.cpp
@@ -49,79 +49,12 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include "plStatusLog/plStatusLog.h"
#pragma hdrstop
-
-/*****************************************************************************
-*
-* Private
-*
-***/
-
-static const unsigned kMaxHandlers = 8;
-static CCritSect s_critsect;
-static FLogHandler s_asyncHandlers[kMaxHandlers];
-
-
-/*****************************************************************************
-*
-* Internal functions
-*
-***/
-
-//===========================================================================
-static void Dispatch (ELogSeverity severity, const wchar_t msg[]) {
-
- // Dispatch to default debug handler
- char dbg[1024];
- StrToAnsi(dbg, msg, arrsize(dbg));
- DEBUG_MSG(dbg);
-
- // We don't need to enter a critical section to read the handlers because they
- // are atomically set and cleared
- for (unsigned i = 0; i < arrsize(s_asyncHandlers); ++i) {
- if (FLogHandler asyncHandler = s_asyncHandlers[i])
- asyncHandler(severity, msg);
- }
-}
-
-
/*****************************************************************************
*
* Exports
*
***/
-//===========================================================================
-void LogRegisterHandler (FLogHandler callback) {
- ASSERT(callback);
-
- unsigned i;
- s_critsect.Enter();
- for (i = 0; i < arrsize(s_asyncHandlers); ++i) {
- if (!s_asyncHandlers[i]) {
- s_asyncHandlers[i] = callback;
- break;
- }
- }
- s_critsect.Leave();
-
- #ifdef HS_DEBUGGING
- if (i >= arrsize(s_asyncHandlers))
- FATAL("Maximum number of log handlers exceeded.");
- #endif
-}
-
-//===========================================================================
-void LogUnregisterHandler (FLogHandler callback) {
- s_critsect.Enter();
- for (unsigned i = 0; i < arrsize(s_asyncHandlers); ++i) {
- if (s_asyncHandlers[i] == callback) {
- s_asyncHandlers[i] = nil;
- break;
- }
- }
- s_critsect.Leave();
-}
-
//===========================================================================
void CDECL LogMsg (ELogSeverity severity, const char format[], ...) {
ASSERT(format);
diff --git a/Sources/Plasma/NucleusLib/pnAsyncCore/Private/pnAcLog.h b/Sources/Plasma/NucleusLib/pnAsyncCore/Private/pnAcLog.h
index 3489cb90..e2445c32 100644
--- a/Sources/Plasma/NucleusLib/pnAsyncCore/Private/pnAcLog.h
+++ b/Sources/Plasma/NucleusLib/pnAsyncCore/Private/pnAcLog.h
@@ -81,33 +81,6 @@ void LogMsg (ELogSeverity severity, const wchar_t format[], ...);
void LogMsgV (ELogSeverity severity, const char format[], va_list args);
void LogMsgV (ELogSeverity severity, const wchar_t format[], va_list args);
-void LogBreakOnErrors (bool breakOnErrors);
-
-void AsyncLogInitialize (
- const wchar_t logDirName[],
- bool breakOnErrors
-);
-void AsyncLogDestroy ();
-void AsyncLogFlush ();
-
-void AsyncLogGetDirectory (wchar_t * dest, unsigned destChars);
-
-
-// Low(er) level log API; call this from your LogHander function
-// if you want to use the asynchronous log facility.
-void AsyncLogWriteMsg (
- const wchar_t facility[],
- ELogSeverity severity,
- const wchar_t msg[]
-);
-
-// FLogHandler must be capable of handling multiple threads and re-entrancy
-typedef void (* FLogHandler) (ELogSeverity severity, const wchar_t msg[]);
-
-void LogRegisterHandler (FLogHandler callback);
-void LogUnregisterHandler (FLogHandler callback);
-
-
/****************************************************************************
*
* Debugging API
diff --git a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/CMakeLists.txt b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/CMakeLists.txt
index 0fe44fb0..4ae85f4b 100644
--- a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/CMakeLists.txt
+++ b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/CMakeLists.txt
@@ -4,7 +4,6 @@ include_directories(../../NucleusLib)
set(pnAsyncCoreExe_SOURCES
pnAceCore.cpp
pnAceIo.cpp
- pnAceLog.cpp
pnAceThread.cpp
pnAceTimer.cpp
)
@@ -23,7 +22,6 @@ set(pnAysncCoreExe_PRIVATE
set(pnAysncCoreExe_PRIVATE_NT
Private/Nt/pnAceNt.cpp
Private/Nt/pnAceNt.h
- Private/Nt/pnAceNtFile.cpp
Private/Nt/pnAceNtInt.h
Private/Nt/pnAceNtSocket.cpp
Private/Nt/pnAceNtThread.cpp
@@ -36,7 +34,6 @@ set(pnAsyncCoreExe_PRIVATE_UNIX
set(pnAsyncCoreExe_PRIVATE_W9X
Private/W9x/pnAceW9x.cpp
Private/W9x/pnAceW9x.h
- Private/W9x/pnAceW9xFile.cpp
Private/W9x/pnAceW9xInt.h
Private/W9x/pnAceW9xSocket.cpp
Private/W9x/pnAceW9xThread.cpp
@@ -61,4 +58,4 @@ source_group("Private" FILES ${pnAsyncCoreExe_PRIVATE})
source_group("Private\\Nt" FILES ${pnAysncCoreExe_PRIVATE_NT})
source_group("Private\\Unix" FILES ${pnAsyncCoreExe_PRIVATE_UNIX})
source_group("Private\\W9x" FILES ${pnAsyncCoreExe_PRIVATE_W9X})
-source_group("Private\\Win32" FILES ${pnAsyncCoreExe_PRIVATE_WIN32})
\ No newline at end of file
+source_group("Private\\Win32" FILES ${pnAsyncCoreExe_PRIVATE_WIN32})
diff --git a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNt.cpp b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNt.cpp
index d41d3a94..73447c69 100644
--- a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNt.cpp
+++ b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNt.cpp
@@ -466,16 +466,6 @@ void NtGetApi (AsyncApi * api) {
api->waitForShutdown = NtWaitForShutdown;
api->sleep = NtSleep;
- api->fileOpen = NtFileOpen;
- api->fileClose = NtFileClose;
- api->fileRead = NtFileRead;
- api->fileWrite = NtFileWrite;
- api->fileFlushBuffers = NtFileFlushBuffers;
- api->fileSetLastWriteTime = NtFileSetLastWriteTime;
- api->fileGetLastWriteTime = NtFileGetLastWriteTime;
- api->fileCreateSequence = NtFileCreateSequence;
- api->fileSeek = NtFileSeek;
-
api->socketConnect = NtSocketConnect;
api->socketConnectCancel = NtSocketConnectCancel;
api->socketDisconnect = NtSocketDisconnect;
diff --git a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNtFile.cpp b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNtFile.cpp
deleted file mode 100644
index d717b69a..00000000
--- a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNtFile.cpp
+++ /dev/null
@@ -1,1010 +0,0 @@
-/*==LICENSE==*
-
-CyanWorlds.com Engine - MMOG client, server and tools
-Copyright (C) 2011 Cyan Worlds, Inc.
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-
-Additional permissions under GNU GPL version 3 section 7
-
-If you modify this Program, or any covered work, by linking or
-combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
-NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
-JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
-(or a modified version of those libraries),
-containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
-PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
-JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
-licensors of this Program grant you additional
-permission to convey the resulting work. Corresponding Source for a
-non-source form of such a combination shall include the source code for
-the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
-work.
-
-You can contact Cyan Worlds, Inc. by email legal@cyan.com
- or by snail mail at:
- Cyan Worlds, Inc.
- 14617 N Newport Hwy
- Mead, WA 99021
-
-*==LICENSE==*/
-/*****************************************************************************
-*
-* $/Plasma20/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNtFile.cpp
-*
-***/
-
-#include "../../Pch.h"
-#pragma hdrstop
-
-#include "pnAceNtInt.h"
-
-
-namespace Nt {
-
-/****************************************************************************
-*
-* Private
-*
-***/
-
-// Must be a multiple of largest possible disk sector size
-const unsigned kSplitRwBytes = 4 * 1024 * 1024;
-
-
-struct NtOpFileReadWrite : Operation {
- NtOpFileReadWrite * masterOp;
- unsigned win32Bytes;
- AsyncNotifyFileRead rw;
-};
-
-struct NtOpFileFlush : Operation {
- AsyncNotifyFileFlush flush;
-};
-
-struct NtOpFileSequence : Operation {
- AsyncNotifyFileSequence sequence;
-};
-
-struct NtFile : NtObject {
- FAsyncNotifyFileProc notifyProc;
- LINK(NtFile) openLink; // protected by s_fileCrit
- LINK(NtFile) pendLink; // protected by s_fileCrit
- unsigned queueWrites;
- unsigned sectorSizeMask;
- wchar_t fullPath[MAX_PATH];
-
- NtFile ();
- ~NtFile ();
-};
-
-static long s_fileOps;
-static CNtCritSect s_fileCrit;
-static LISTDECL(NtFile, openLink) s_openFiles;
-static LISTDECL(NtFile, pendLink) s_pendFiles;
-static AsyncTimer * s_timer;
-
-
-//===========================================================================
-inline NtFile::NtFile () {
- PerfAddCounter(kAsyncPerfFilesCurr, 1);
- PerfAddCounter(kAsyncPerfFilesTotal, 1);
-}
-
-//===========================================================================
-NtFile::~NtFile () {
- PerfSubCounter(kAsyncPerfFilesCurr, 1);
-}
-
-//===========================================================================
-static void FatalOnNonRecoverableError (
- const NtOpFileReadWrite & op,
- unsigned error
-) {
- switch (error) {
- case ERROR_NO_SYSTEM_RESOURCES:
- case ERROR_NONPAGED_SYSTEM_RESOURCES:
- case ERROR_PAGED_SYSTEM_RESOURCES:
- case ERROR_WORKING_SET_QUOTA:
- case ERROR_PAGEFILE_QUOTA:
- case ERROR_COMMITMENT_LIMIT:
- return;
- }
-
- ASSERT((op.opType == kOpFileRead) || (op.opType == kOpFileWrite));
- ErrorAssert(
- __LINE__, __FILE__,
- "Disk %s failed, error: %u",
- op.opType == kOpFileRead ? "read" : "write",
- error
- );
-}
-
-//===========================================================================
-static unsigned INtFileTimerProc (void *) {
- if (!s_pendFiles.Head())
- return INFINITE;
-
- if (!s_fileCrit.TryEnter())
- return 10;
-
- // dequeue head of list
- NtFile * file = s_pendFiles.Head();
- if (file)
- s_pendFiles.Unlink(file);
- s_fileCrit.Leave();
- if (!file)
- return INFINITE;
-
- // retry operation
- ASSERT(file->opList.Head());
- ASSERT((file->opList.Head()->opType == kOpQueuedFileRead)
- || (file->opList.Head()->opType == kOpQueuedFileWrite)
- );
- INtFileOpCompleteQueuedReadWrite(file, (NtOpFileReadWrite *) file->opList.Head());
- return 0;
-}
-
-//===========================================================================
-static void HandleFailedOp (
- NtFile * file,
- NtOpFileReadWrite * op,
- unsigned error
-) {
- ASSERT((op->opType == kOpFileRead) || (op->opType == kOpFileWrite));
-
- // break the operation into a bunch of sub-operations if it hasn't already been done
- unsigned subOperations = 0;
- LISTDECL(NtOpFileReadWrite, link) opList;
- if (!op->masterOp) {
- // setup master operation to read the start of the buffer; this
- // ensures that op->rw.* is unchanged for the master operation,
- // which is important for the user notification callback
- op->masterOp = op;
- op->win32Bytes = min(kSplitRwBytes, op->rw.bytes);
- unsigned position = op->win32Bytes;
-
- // create sub-operations to read the rest of the buffer
- for (; position < op->rw.bytes; ++subOperations) {
- NtOpFileReadWrite * childOp = new NtOpFileReadWrite;
- childOp->overlapped.hEvent = op->overlapped.hEvent ? CreateEvent(nil, true, false, nil) : nil;
- childOp->overlapped.Offset = (uint32_t) ((op->rw.offset + position) & 0xffffffff);
- childOp->overlapped.OffsetHigh = (uint32_t) ((op->rw.offset + position) >> 32);
- childOp->opType = op->opType;
- childOp->asyncId = 0;
- childOp->notify = false;
- childOp->pending = 1;
- childOp->signalComplete = nil;
- childOp->masterOp = op;
- childOp->win32Bytes = min(kSplitRwBytes, op->rw.bytes - position);
- childOp->rw.param = nil;
- childOp->rw.asyncId = 0;
- childOp->rw.offset = op->rw.offset + position;
- childOp->rw.buffer = op->rw.buffer + position;
- childOp->rw.bytes = childOp->win32Bytes;
- opList.Link(childOp, kListTail);
- position += childOp->win32Bytes;
- }
-
- InterlockedExchangeAdd(&file->ioCount, (long) subOperations);
- }
-
- bool autoComplete = true;
- unsigned eventCount = 0;
- HANDLE events[MAXIMUM_WAIT_OBJECTS];
-
- file->critsect.Enter();
-
- // start with the master operation since it points to the start of the buffer
- NtOpFileReadWrite * childOp = op;
- op->pending += subOperations;
- for (;;) {
- // if we're not repeating the previous operation then dequeue a new one
- if (!childOp) {
- if (nil == (childOp = opList.Head()))
- break;
- opList.Unlink(childOp);
- file->opList.Link(childOp, kListLinkBefore, op);
- }
-
- // issue the operation
- bool result;
- const HANDLE hEvent = childOp->overlapped.hEvent;
- if (childOp->opType == kOpFileRead) {
- result = ReadFile(
- file->handle,
- childOp->rw.buffer,
- childOp->win32Bytes,
- 0,
- &childOp->overlapped
- );
- }
- else {
- ASSERT(childOp->opType == kOpFileWrite);
- result = WriteFile(
- file->handle,
- childOp->rw.buffer,
- childOp->win32Bytes,
- 0,
- &childOp->overlapped
- );
- }
-
- if (!result && ((error = GetLastError()) != ERROR_IO_PENDING)) {
- FatalOnNonRecoverableError(*childOp, error);
-
- if (eventCount) {
- LogMsg(kLogError, "HandleFailedOp1 failed");
- // wait for other operations to complete on this file before retrying
- }
- else if (childOp->overlapped.hEvent) {
- LogMsg(kLogError, "HandleFailedOp2 failed");
- // wait a while and retry operation again
- Sleep(10);
- continue;
- }
- else {
- // convert operation into pending operation
- const EOpType opType = (childOp->opType == kOpFileRead)
- ? kOpQueuedFileRead
- : kOpQueuedFileWrite;
- childOp->opType = opType;
-
- // convert all other operations into pending operations
- while (nil != (childOp = opList.Head())) {
- childOp->opType = opType;
- opList.Unlink(childOp);
- file->opList.Link(childOp, kListLinkBefore, op);
- }
-
- // if there is an operation at the head of the list that will complete
- // without help then it will autostart the operations we queued
- autoComplete = file->opList.Head()->opType != opType;
- break;
- }
- }
- else {
- // operation was successful
- childOp = nil;
-
- // if we didn't fill the synchronous event array then continue issuing operations
- if (nil == (events[eventCount] = hEvent))
- continue;
- if (++eventCount < arrsize(events))
- continue;
- }
-
- // wait for all synchronous operations to complete
- if (eventCount) {
- file->critsect.Leave();
- WaitForMultipleObjects(eventCount, events, true, INFINITE);
- for (unsigned i = 0; i < eventCount; ++i)
- CloseHandle(events[i]);
- eventCount = 0;
- file->critsect.Enter();
- }
- }
- file->critsect.Leave();
-
- if (eventCount) {
- WaitForMultipleObjects(eventCount, events, true, INFINITE);
- for (unsigned i = 0; i < eventCount; ++i)
- CloseHandle(events[i]);
- }
- else if (!autoComplete) {
- s_fileCrit.Enter();
- s_pendFiles.Link(file, kListTail);
- s_fileCrit.Leave();
-
- AsyncTimerUpdate(s_timer, 0, kAsyncTimerUpdateSetPriorityHigher);
- }
-}
-
-//===========================================================================
-static void InternalFileSetSize (NtObject * file, uint64_t size) {
- LONG sizeHigh = (long) (size >> 32);
- DWORD seek = SetFilePointer(file->handle, (uint32_t) size, &sizeHigh, FILE_BEGIN);
- if ((seek != (DWORD) -1) || (GetLastError() == NO_ERROR))
- SetEndOfFile(file->handle);
-}
-
-
-/****************************************************************************
-*
-* Module functions
-*
-***/
-
-//===========================================================================
-void INtFileInitialize () {
- AsyncTimerCreate(&s_timer, INtFileTimerProc, INFINITE);
-}
-
-//===========================================================================
-void INtFileStartCleanup () {
- // wait until outstanding file I/O is complete
- for (;; Sleep(10)) {
- if (s_fileOps)
- continue;
- if (AsyncPerfGetCounter(kAsyncPerfFileBytesReadQueued))
- continue;
- if (AsyncPerfGetCounter(kAsyncPerfFileBytesWriteQueued))
- continue;
- if (volatile bool pending = (s_pendFiles.Head() != nil))
- continue;
- break;
- }
-
- // slam closed any files which are still open
- for (;;) {
- s_fileCrit.Enter();
- NtFile * file = s_openFiles.Head();
- if (file)
- s_openFiles.Unlink(file);
- s_fileCrit.Leave();
- if (!file)
- break;
-
- char msg[256 + MAX_PATH];
- StrPrintf(msg, arrsize(msg), "Error: file '%S' still open", file->fullPath);
- ErrorAssert(__LINE__, __FILE__, msg);
-
- file->notifyProc = nil;
- INtConnCompleteOperation(file);
- }
-}
-
-//===========================================================================
-void INtFileDestroy () {
- if (s_timer) {
- AsyncTimerDelete(s_timer, kAsyncTimerDestroyWaitComplete);
- s_timer = nil;
- }
-}
-
-//===========================================================================
-void INtFileDelete (
- NtFile * file
-) {
- file->critsect.Enter();
- if (file->handle != INVALID_HANDLE_VALUE) {
- CloseHandle(file->handle);
- file->handle = INVALID_HANDLE_VALUE;
- }
- file->critsect.Leave();
-
- delete file;
-}
-
-//===========================================================================
-void INtFileOpCompleteQueuedReadWrite (
- NtFile * file,
- NtOpFileReadWrite * op
-) {
- bool result;
- const HANDLE hEvent = op->overlapped.hEvent;
- switch (op->opType) {
- case kOpQueuedFileRead:
- op->opType = kOpFileRead;
- // fall through
-
- case kOpFileRead:
- result = ReadFile(
- file->handle,
- op->rw.buffer,
- op->win32Bytes,
- 0,
- &op->overlapped
- );
- break;
-
- case kOpQueuedFileWrite:
- op->opType = kOpFileWrite;
- // fall through
-
- case kOpFileWrite:
- result = WriteFile(
- file->handle,
- op->rw.buffer,
- op->win32Bytes,
- 0,
- &op->overlapped
- );
- break;
-
- DEFAULT_FATAL(opType);
- }
-
- unsigned error;
- if (!result && ((error = GetLastError()) != ERROR_IO_PENDING)) {
- FatalOnNonRecoverableError(*op, error);
- HandleFailedOp(file, op, error);
- }
- else if (hEvent) {
- WaitForSingleObject(hEvent, INFINITE);
- CloseHandle(hEvent);
- }
-}
-
-//===========================================================================
-bool INtFileOpCompleteReadWrite (
- NtFile * file,
- NtOpFileReadWrite * op,
- unsigned bytes
-) {
- // adjust outstanding bytes
- if (bytes != op->win32Bytes) {
- if (!file->sectorSizeMask)
- ErrorAssert(__LINE__, __FILE__, "Disk %s failed", op->opType == kOpFileRead ? "read" : "write");
- if (op->opType == kOpFileRead)
- memset(op->rw.buffer + bytes, 0, op->win32Bytes - bytes);
- }
-
- if (op->masterOp) {
- bool bail = false;
- file->critsect.Enter();
-
- // if this is a child operation (!op->asyncId) then
- // decrement the master operation's pending count
- if (!op->asyncId && (--op->masterOp->pending == 1)) {
- if (!op->masterOp->masterOp)
- INtConnPostOperation(file, op->masterOp, op->masterOp->win32Bytes);
- }
- // this is the master operation; wait until all the child operations complete
- else if (op->pending != 1) {
- op->masterOp->masterOp = nil;
- bail = true;
- }
- file->critsect.Leave();
- if (bail)
- return false;
- }
-
- // callback notification procedure if requested
- if (op->notify) {
- // before we dispatch the operation to the handler, change its
- // type to indicate that the operation is being dispatched
- op->notify = false;
- file->notifyProc(
- (AsyncFile) file,
- op->opType == kOpFileRead ? kNotifyFileRead : kNotifyFileWrite,
- &op->rw,
- &file->userState
- );
- }
-
- PerfSubCounter(
- op->opType == kOpFileRead ? kAsyncPerfFileBytesReadQueued : kAsyncPerfFileBytesWriteQueued,
- op->win32Bytes
- );
- return true;
-}
-
-//===========================================================================
-void INtFileOpCompleteFileFlush (
- NtFile * file,
- NtOpFileFlush * op
-) {
- ASSERT(file->ioType == kNtFile);
-
- // complete flush operation
- if (!FlushFileBuffers(file->handle))
- op->flush.error = AsyncGetLastFileError();
- else
- op->flush.error = kFileSuccess;
-
- if (op->flush.truncateSize != kAsyncFileDontTruncate)
- InternalFileSetSize(file, op->flush.truncateSize);
-
- // start any queued writes which were waiting for this flush operation to
- // complete, but only complete any writes up to the next flush operation
- file->critsect.Enter();
- --file->queueWrites;
- for (Operation * scan = file->opList.Head(); scan; scan = file->opList.Next(scan)) {
- if (scan->opType == kOpQueuedFileWrite)
- INtFileOpCompleteQueuedReadWrite(file, (NtOpFileReadWrite *) scan);
- else if ((scan->opType == kOpFileFlush) && (scan != op))
- break;
- }
- file->critsect.Leave();
-
- if (op->notify) {
- op->notify = false;
- file->notifyProc((AsyncFile) file, kNotifyFileFlush, &op->flush, &file->userState);
- }
- InterlockedDecrement(&s_fileOps);
-}
-
-//===========================================================================
-void INtFileOpCompleteSequence (
- NtFile * file,
- NtOpFileSequence * op
-) {
- if (op->notify) {
- op->notify = false;
- file->notifyProc((AsyncFile) file, kNotifyFileSequence, &op->sequence, &file->userState);
- }
- InterlockedDecrement(&s_fileOps);
-}
-
-
-/****************************************************************************
-*
-* Exported functions
-*
-***/
-
-//===========================================================================
-AsyncFile NtFileOpen (
- const wchar_t fullPath[],
- FAsyncNotifyFileProc notifyProc,
- EFileError * error,
- unsigned desiredAccess,
- unsigned openMode,
- unsigned shareModeFlags,
- void * userState,
- uint64_t * fileSize,
- uint64_t * fileLastWriteTime
-) {
- unsigned attributeFlags = 0;
- attributeFlags |= FILE_FLAG_OVERLAPPED;
-
- HANDLE handle = CreateFileW(
- fullPath,
- desiredAccess,
- shareModeFlags,
- nil, // plSecurityAttributes
- openMode,
- attributeFlags,
- nil // hTemplateFile
- );
- *error = AsyncGetLastFileError();
-
- if (INVALID_HANDLE_VALUE == handle)
- return nil;
-
- // don't allow users to open devices like "LPT1", etc.
- if (GetFileType(handle) != FILE_TYPE_DISK) {
- LogMsg(kLogFatal, "!FILE_TYPE_DISK");
- *error = kFileErrorFileNotFound;
- CloseHandle(handle);
- return nil;
- }
-
- // get file size
- DWORD sizeHi, sizeLo = GetFileSize(handle, &sizeHi);
- if ((sizeLo == (DWORD) -1) && (NO_ERROR != GetLastError())) {
- *error = AsyncGetLastFileError();
- LogMsg(kLogFatal, "GetFileSize");
- CloseHandle(handle);
- return nil;
- }
- const uint64_t size = ((uint64_t) sizeHi << (uint64_t) 32) | (uint64_t) sizeLo;
-
- uint64_t lastWriteTime;
- ASSERT(sizeof(lastWriteTime) >= sizeof(FILETIME));
- GetFileTime(handle, nil, nil, (FILETIME *) &lastWriteTime);
-
- // allocate and initialize a new file
- NtFile * conn = NEWZERO(NtFile);
- conn->ioType = kNtFile;
- conn->handle = handle;
- conn->notifyProc = notifyProc;
- conn->ioCount = 1;
- conn->queueWrites = 0;
- conn->userState = userState;
- conn->sectorSizeMask = 0;
-
- conn->closed = false;
- StrCopy(conn->fullPath, fullPath, arrsize(conn->fullPath));
-
- if (!INtConnInitialize(conn)) {
- *error = kFileErrorFileNotFound;
- conn->notifyProc = nil;
- INtConnCompleteOperation(conn);
- return nil;
- }
-
- // add to list of open files
- s_fileCrit.Enter();
- s_openFiles.Link(conn);
- s_fileCrit.Leave();
-
- // return out parameters
- if (fileSize)
- *fileSize = size;
- if (fileLastWriteTime)
- *fileLastWriteTime = lastWriteTime;
- return (AsyncFile) conn;
-}
-
-//===========================================================================
-AsyncId NtFileRead (
- AsyncFile conn,
- uint64_t offset,
- void * buffer,
- unsigned bytes,
- unsigned flags,
- void * param
-) {
- NtFile * file = (NtFile *) conn;
- ASSERT(file->ioType == kNtFile);
- ASSERT(file->handle != INVALID_HANDLE_VALUE);
- ASSERT((flags & (kAsyncFileRwNotify|kAsyncFileRwSync)) != (kAsyncFileRwNotify|kAsyncFileRwSync));
- ASSERT(! (offset & file->sectorSizeMask));
- ASSERT(! (bytes & file->sectorSizeMask));
- ASSERT(! ((uintptr_t) buffer & file->sectorSizeMask));
-
- // Normally, I/O events do not complete until both the WIN32 operation has completed
- // and the callback notification has occurred. A deadlock can occur if a thread attempts
- // to perform a series of operations and then waits for those operations to complete if
- // that thread holds a critical section, because all the I/O worker threads cannot
- // enter that critical section to complete their required notification callbacks. To
- // enable the sequential thread to perform a wait operation, we set the event field
- // into the Overlapped structure, because the event will be signaled prior to the
- // potentially deadlocking callback notification.
- NtOpFileReadWrite * op = new NtOpFileReadWrite;
- op->overlapped.Offset = (uint32_t) (offset & 0xffffffff);
- op->overlapped.OffsetHigh = (uint32_t) (offset >> 32);
- op->overlapped.hEvent = (flags & kAsyncFileRwSync) ? CreateEvent(nil, true, false, nil) : nil;
- op->opType = kOpFileRead;
- op->notify = (flags & kAsyncFileRwNotify) != 0;
- op->pending = 1;
- op->signalComplete = nil;
- op->masterOp = nil;
- op->win32Bytes = bytes;
- op->rw.param = param;
- op->rw.offset = offset;
- op->rw.buffer = (uint8_t *) buffer;
- op->rw.bytes = bytes;
-
- InterlockedIncrement(&file->ioCount);
- PerfAddCounter(kAsyncPerfFileBytesReadQueued, bytes);
-
- file->critsect.Enter();
- const AsyncId asyncId = op->rw.asyncId = op->asyncId = INtConnSequenceStart(file);
- file->opList.Link(op, kListTail);
- file->critsect.Leave();
-
- INtFileOpCompleteQueuedReadWrite(file, op);
-
- return asyncId;
-}
-
-//===========================================================================
-// buffer must stay valid until I/O is completed
-AsyncId NtFileWrite (
- AsyncFile conn,
- uint64_t offset,
- const void * buffer,
- unsigned bytes,
- unsigned flags,
- void * param
-) {
- NtFile * file = (NtFile *) conn;
- ASSERT(file->ioType == kNtFile);
- ASSERT(file->handle != INVALID_HANDLE_VALUE);
- ASSERT((flags & (kAsyncFileRwNotify|kAsyncFileRwSync)) != (kAsyncFileRwNotify|kAsyncFileRwSync));
- ASSERT(! (offset & file->sectorSizeMask));
- ASSERT(! (bytes & file->sectorSizeMask));
- ASSERT(! ((uintptr_t) buffer & file->sectorSizeMask));
-
- // Normally, I/O events do not complete until both the WIN32 operation has completed
- // and the callback notification has occurred. A deadlock can occur if a thread attempts
- // to perform a series of operations and then waits for those operations to complete if
- // that thread holds a critical section, because all the I/O worker threads cannot
- // enter that critical section to complete their required notification callbacks. To
- // enable the sequential thread to perform a wait operation, we set the event field
- // into the Overlapped structure, because the event will be signaled prior to the
- // potentially deadlocking callback notification.
- NtOpFileReadWrite * op = new NtOpFileReadWrite;
- op->overlapped.Offset = (uint32_t) (offset & 0xffffffff);
- op->overlapped.OffsetHigh = (uint32_t) (offset >> 32);
- op->overlapped.hEvent = (flags & kAsyncFileRwSync) ? CreateEvent(nil, true, false, nil) : nil;
- op->opType = kOpFileWrite;
- op->notify = (flags & kAsyncFileRwNotify) != 0;
- op->pending = 1;
- op->signalComplete = nil;
- op->masterOp = nil;
- op->win32Bytes = bytes;
- op->rw.param = param;
- op->rw.offset = offset;
- op->rw.buffer = (uint8_t *) buffer;
- op->rw.bytes = bytes;
-
- InterlockedIncrement(&file->ioCount);
- PerfAddCounter(kAsyncPerfFileBytesWriteQueued, bytes);
-
- // to avoid a potential deadlock, we MUST issue the write if the SYNC flag is set
- file->critsect.Enter();
- ASSERT(!file->queueWrites || !op->overlapped.hEvent);
- const bool startOperation = !file->queueWrites || op->overlapped.hEvent;
- if (!startOperation)
- op->opType = kOpQueuedFileWrite;
- const AsyncId asyncId = op->asyncId = op->rw.asyncId = INtConnSequenceStart(file);
- file->opList.Link(op, kListTail);
- file->critsect.Leave();
-
- if (startOperation)
- INtFileOpCompleteQueuedReadWrite(file, op);
-
- return asyncId;
-}
-
-//===========================================================================
-AsyncId NtFileFlushBuffers (
- AsyncFile conn,
- uint64_t truncateSize,
- bool notify,
- void * param
-) {
- NtFile * file = (NtFile *) conn;
- ASSERT(file);
- ASSERT(file->ioType == kNtFile);
- ASSERT(file->handle != INVALID_HANDLE_VALUE);
- ASSERT((truncateSize == kAsyncFileDontTruncate) || !(truncateSize & file->sectorSizeMask));
-
- // create new operation
- NtOpFileFlush * op = new NtOpFileFlush;
- file->critsect.Enter();
-
- // write operations cannot complete while a flush is in progress
- ++file->queueWrites;
-
- // init Operation
- const AsyncId asyncId = INtConnSequenceStart(file);
- op->overlapped.Offset = 0;
- op->overlapped.OffsetHigh = 0;
- op->overlapped.hEvent = nil;
- op->opType = kOpFileFlush;
- op->asyncId = asyncId;
- op->notify = notify;
- op->pending = 1;
- op->signalComplete = nil;
- file->opList.Link(op, kListTail);
-
- // init OpFileFlush
- op->flush.param = param;
- op->flush.asyncId = asyncId;
- op->flush.error = kFileSuccess;
- op->flush.truncateSize = truncateSize;
-
- InterlockedIncrement(&s_fileOps);
- InterlockedIncrement(&file->ioCount);
-
- // if there are other operations already on the list we can't complete this one
- if (op != file->opList.Head())
- op = nil;
-
- file->critsect.Leave();
-
- // If the operation is at the head of the
- // list then issue it for immediate complete
- if (op)
- INtConnPostOperation(file, op, 0);
- return asyncId;
-}
-
-//===========================================================================
-void NtFileClose (
- AsyncFile conn,
- uint64_t truncateSize
-) {
- NtFile * file = (NtFile *) conn;
- ASSERT(file);
- ASSERT(file->ioType == kNtFile);
-
- file->critsect.Enter();
- {
- {
- // AsyncFileClose guarantees that when it returns the file handle will be
- // closed so that an immediate call to AsyncFileOpen will succeed. In order
- // to successfully close the file handle immediately, we must ensure that
- // there is be no active I/O on the file; either no operations on list, or
- // only operations on list which are being dispatched or have been dispatched.
- ASSERT(!file->pendLink.IsLinked());
- for (Operation * op = file->opList.Head(); op; op = file->opList.Next(op)) {
- // skip completed operations
- if (!op->pending)
- continue;
-
- // skip operations which are "technically complete"
- if (!op->notify)
- continue;
-
- ErrorAssert(__LINE__, __FILE__, "AsyncFileClose: File has pending I/O!");
- break;
- }
-
- // make sure the user doesn't attempt to close the file twice
- ASSERT(!file->closed);
- file->closed = true;
- }
-
- if (truncateSize != kAsyncFileDontTruncate)
- InternalFileSetSize(file, truncateSize);
-
- ASSERT(file->handle != INVALID_HANDLE_VALUE);
- CloseHandle(file->handle);
- file->handle = INVALID_HANDLE_VALUE;
- }
- file->critsect.Leave();
-
- // remove file from list of open files
- s_fileCrit.Enter();
- ASSERT(!file->pendLink.IsLinked());
- s_openFiles.Unlink(file);
- s_fileCrit.Leave();
-
- INtConnCompleteOperation(file);
-}
-
-//===========================================================================
-void NtFileSetLastWriteTime (
- AsyncFile conn,
- uint64_t lastWriteTime
-) {
- NtFile * file = (NtFile *) conn;
- ASSERT(file);
- ASSERT(file->ioType == kNtFile);
-
- file->critsect.Enter();
- ASSERT(file->handle != INVALID_HANDLE_VALUE);
- SetFileTime(file->handle, nil, nil, (FILETIME *) &lastWriteTime);
- file->critsect.Leave();
-}
-
-//===========================================================================
-uint64_t NtFileGetLastWriteTime (
- const wchar_t fileName[]
-) {
- WIN32_FILE_ATTRIBUTE_DATA info;
- bool f = GetFileAttributesExW(fileName, GetFileExInfoStandard, &info);
- return f ? *((uint64_t *) &info.ftLastWriteTime) : 0;
-}
-
-//===========================================================================
-// Inserts a "null operation" into the list of reads and writes. The callback
-// will be called when all preceding operations have successfully completed.
-AsyncId NtFileCreateSequence (
- AsyncFile conn,
- bool notify,
- void * param
-) {
- NtFile * file = (NtFile *) conn;
- ASSERT(file);
- ASSERT(file->ioType == kNtFile);
-
- // create new operation
- NtOpFileSequence * op = new NtOpFileSequence;
- file->critsect.Enter();
-
- // init Operation
- const AsyncId asyncId = INtConnSequenceStart(file);
- op->overlapped.Offset = 0;
- op->overlapped.OffsetHigh = 0;
- op->overlapped.hEvent = nil;
- op->opType = kOpSequence;
- op->asyncId = asyncId;
- op->notify = notify;
- op->pending = 1;
- op->signalComplete = nil;
- file->opList.Link(op, kListTail);
-
- // init OpFileSequence
- op->sequence.param = param;
- op->sequence.asyncId = asyncId;
-
- InterlockedIncrement(&s_fileOps);
- InterlockedIncrement(&file->ioCount);
-
- // if there are other operations already on the list we can't complete this one
- if (op != file->opList.Head())
- op = nil;
-
- file->critsect.Leave();
-
- // If the operation is at the head of the
- // list then issue it for immediate complete
- if (op)
- INtConnPostOperation(file, op, 0);
- return asyncId;
-}
-
-//===========================================================================
-// This function allows the caller to wait until an I/O operation completes for
-// a file. However, it is an EXTREMELY DANGEROUS function, so you should follow
-// these rules to avoid a deadlock:
-// 1. AsyncWaitId CAN NEVER be called in response to an I/O completion notification
-// callback (a call to an FAsyncNotifyFileProc), because if all I/O threads were
-// blocking for I/O there would be no threads left to complete the I/O.
-// 2. AsyncWaitId CAN NEVER be called from a timer callback for the same reason as #1.
-// 3. AsyncWaitId can be called from inside an idle callback (FAsyncIdleProc), because
-// only half of the I/O threads can be inside an idle callback at the same time,
-// which leaves the other half available to complete I/O.
-// 4. When calling AsyncWaitId, the thread which makes the call MUST NOT hold any
-// locks (critical section or reader/writer locks) which would cause an I/O
-// thread to block while completing I/O that might be needed to complete the
-// I/O operation that is being waited. That means not only the specific I/O
-// operation that is being waited, but also any I/O that will call the same
-// FAsyncNotifyFileProc.
-// 5. Spin-blocking (calling AsyncWaitId in a loop with a small timeout value) IS NOT
-// a solution to the deadlock problem, it will still create a deadlock because
-// the I/O thread is still fully occupied and cannot complete any I/O
-bool NtFileWaitId (AsyncFile conn, AsyncId asyncId, unsigned timeoutMs) {
- NtFile * file = (NtFile *) conn;
- ASSERT(asyncId);
- ASSERT(file);
- ASSERT(file->ioType == kNtFile);
- ASSERT(file->handle != INVALID_HANDLE_VALUE);
-
- ThreadAssertCanBlock(__FILE__, __LINE__);
-
- // has the AsyncId already completed?
- if (file->nextCompleteSequence - (long) asyncId >= 0)
- return true;
-
- // is this a non-blocking wait?
- if (!timeoutMs)
- return false;
-
- // find the I/O operation the user is waiting for
- CNtWaitHandle * signalComplete = nil;
- file->critsect.Enter();
- for (Operation * op = file->opList.Head(); op; op = file->opList.Next(op)) {
- if (asyncId != op->asyncId)
- continue;
-
- // create an object to wait on
- if (!op->signalComplete)
- op->signalComplete = new CNtWaitHandle;
- signalComplete = op->signalComplete;
- signalComplete->IncRef();
- break;
- }
- file->critsect.Leave();
-
- // if we didn't find or create a signal then the operation must have
- // completed just before we managed to enter the critical section
- if (!signalComplete)
- return true;
-
- const bool result = signalComplete->WaitForObject(timeoutMs);
- signalComplete->DecRef();
- return result;
-}
-
-//============================================================================
-bool NtFileSeek (
- AsyncFile conn,
- uint64_t distance,
- EFileSeekFrom from
-) {
- COMPILER_ASSERT(kFileSeekFromBegin == FILE_BEGIN);
- COMPILER_ASSERT(kFileSeekFromCurrent == FILE_CURRENT);
- COMPILER_ASSERT(kFileSeekFromEnd == FILE_END);
-
- NtFile * file = (NtFile *) conn;
- LONG low = (LONG)(distance % 0x100000000ul);
- LONG high = (LONG)(distance / 0x100000000ul);
- uint32_t result = SetFilePointer(file->handle, low, &high, from);
- if ((result == (uint32_t)-1) && (GetLastError() != NO_ERROR)) {
- LogMsg(kLogFatal, "failed: SetFilePointer");
- return false;
- }
- else
- return true;
-}
-
-} // namespace Nt
diff --git a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNtInt.h b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNtInt.h
index 0d2bc7d4..8f702287 100644
--- a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNtInt.h
+++ b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/Nt/pnAceNtInt.h
@@ -142,45 +142,6 @@ bool INtConnInitialize (NtObject * ntObj);
void INtConnCompleteOperation (NtObject * ntObj);
-/*****************************************************************************
-*
-* NtFile.cpp internal functions
-*
-***/
-
-struct NtFile;
-struct NtOpFileFlush;
-struct NtOpFileReadWrite;
-struct NtOpFileSequence;
-
-void INtFileInitialize ();
-void INtFileStartCleanup ();
-void INtFileDestroy ();
-
-void INtFileDelete (
- NtFile * file
-);
-
-bool INtFileOpCompleteReadWrite (
- NtFile * ioConn,
- NtOpFileReadWrite * op,
- unsigned bytes
-);
-void INtFileOpCompleteQueuedReadWrite (
- NtFile * ioConn,
- NtOpFileReadWrite * op
-);
-void INtFileOpCompleteFileFlush (
- NtFile * ioConn,
- NtOpFileFlush * op
-);
-void INtFileOpCompleteSequence (
- NtFile * ioConn,
- NtOpFileSequence * op
-);
-
-void INtFileStartCleanup ();
-
/*****************************************************************************
*
@@ -228,60 +189,6 @@ void NtDestroy (unsigned exitThreadWaitMs);
void NtSignalShutdown ();
void NtWaitForShutdown ();
void NtSleep (unsigned sleepMs);
-AsyncFile NtFileOpen (
- const wchar_t fullPath[],
- FAsyncNotifyFileProc notifyProc,
- EFileError * error,
- unsigned desiredAccess,
- unsigned openMode,
- unsigned shareModeFlags,
- void * userState,
- uint64_t * fileSize,
- uint64_t * fileLastWriteTime
-);
-void NtFileClose (
- AsyncFile file,
- uint64_t truncateSize
-);
-void NtFileSetLastWriteTime (
- AsyncFile file,
- uint64_t lastWriteTime
-);
-uint64_t NtFileGetLastWriteTime (
- const wchar_t fileName[]
-);
-AsyncId NtFileFlushBuffers (
- AsyncFile file,
- uint64_t truncateSize,
- bool notify,
- void * param
-);
-AsyncId NtFileRead (
- AsyncFile file,
- uint64_t offset,
- void * buffer,
- unsigned bytes,
- unsigned flags,
- void * param
-);
-AsyncId NtFileWrite (
- AsyncFile file,
- uint64_t offset,
- const void *buffer,
- unsigned bytes,
- unsigned flags,
- void * param
-);
-AsyncId NtFileCreateSequence (
- AsyncFile file,
- bool notify,
- void * param
-);
-bool NtFileSeek (
- AsyncFile file,
- uint64_t distance,
- EFileSeekFrom from
-);
void NtSocketConnect (
AsyncCancelId * cancelId,
const NetAddress & netAddr,
diff --git a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9x.cpp b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9x.cpp
index 05a439d1..6d8a5db4 100644
--- a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9x.cpp
+++ b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9x.cpp
@@ -67,16 +67,6 @@ void W9xGetApi (AsyncApi * api) {
api->waitForShutdown = W9xThreadWaitForShutdown;
api->sleep = W9xThreadSleep;
- api->fileOpen = W9xFileOpen;
- api->fileClose = W9xFileClose;
- api->fileRead = W9xFileRead;
- api->fileWrite = W9xFileWrite;
- api->fileFlushBuffers = W9xFileFlushBuffers;
- api->fileSetLastWriteTime = W9xFileSetLastWriteTime;
- api->fileGetLastWriteTime = W9xFileGetLastWriteTime;
- api->fileCreateSequence = W9xFileCreateSequence;
- api->fileSeek = W9xFileSeek;
-
api->socketConnect = W9xSocketConnect;
api->socketConnectCancel = W9xSocketConnectCancel;
api->socketDisconnect = W9xSocketDisconnect;
diff --git a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9xFile.cpp b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9xFile.cpp
deleted file mode 100644
index d35f9f8b..00000000
--- a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9xFile.cpp
+++ /dev/null
@@ -1,518 +0,0 @@
-/*==LICENSE==*
-
-CyanWorlds.com Engine - MMOG client, server and tools
-Copyright (C) 2011 Cyan Worlds, Inc.
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-
-Additional permissions under GNU GPL version 3 section 7
-
-If you modify this Program, or any covered work, by linking or
-combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
-NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
-JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
-(or a modified version of those libraries),
-containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
-PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
-JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
-licensors of this Program grant you additional
-permission to convey the resulting work. Corresponding Source for a
-non-source form of such a combination shall include the source code for
-the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
-work.
-
-You can contact Cyan Worlds, Inc. by email legal@cyan.com
- or by snail mail at:
- Cyan Worlds, Inc.
- 14617 N Newport Hwy
- Mead, WA 99021
-
-*==LICENSE==*/
-/*****************************************************************************
-*
-* $/Plasma20/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9xFile.cpp
-*
-***/
-
-#include "../../Pch.h"
-#pragma hdrstop
-
-#include "pnAceW9xInt.h"
-
-
-namespace W9x {
-
-
-/****************************************************************************
-*
-* FileOp
-*
-***/
-
-struct FileOp {
- EAsyncNotifyFile code;
- bool notify;
- union {
- AsyncNotifyFileFlush flush;
- AsyncNotifyFileRead read;
- AsyncNotifyFileSequence sequence;
- AsyncNotifyFileWrite write;
- } data;
-};
-
-
-/****************************************************************************
-*
-* CFile
-*
-***/
-
-class CFile : public CThreadDispObject {
-private:
- CCritSect m_critSect;
- HANDLE m_handle;
- FAsyncNotifyFileProc m_notifyProc;
- void * m_userState;
-
-protected:
- void Complete (void * op, CCritSect * critSect, AsyncId asyncId);
- void Delete (void * op);
-
-public:
- CFile (
- HANDLE handle,
- FAsyncNotifyFileProc notifyProc,
- void * userState
- );
- ~CFile ();
-
- void Read (
- uint64_t offset,
- void * buffer,
- unsigned bytes
- );
-
- void SetLastWriteTime (uint64_t lastWriteTime);
-
- void Truncate (uint64_t size);
-
- void Write (
- uint64_t offset,
- const void * buffer,
- unsigned bytes
- );
-
- bool Seek (uint64_t offset, EFileSeekFrom from);
-};
-
-//===========================================================================
-CFile::CFile (
- HANDLE handle,
- FAsyncNotifyFileProc notifyProc,
- void * userState
-) :
- m_handle(handle),
- m_notifyProc(notifyProc),
- m_userState(userState)
-{
-}
-
-//===========================================================================
-CFile::~CFile () {
- CloseHandle(m_handle);
- m_handle = INVALID_HANDLE_VALUE;
-}
-
-//===========================================================================
-void CFile::Complete (void * op, CCritSect * critSect, AsyncId asyncId) {
- FileOp * fileOp = (FileOp *)op;
-
- // Enter our local critical section and leave the global one
- m_critSect.Enter();
- critSect->Leave();
-
- // Complete the operation
- switch (fileOp->code) {
-
- case kNotifyFileFlush: {
- if (fileOp->data.flush.truncateSize != kAsyncFileDontTruncate)
- Truncate(fileOp->data.flush.truncateSize);
- BOOL result = FlushFileBuffers(m_handle);
- fileOp->data.flush.error = result ? kFileSuccess : AsyncGetLastFileError();
- }
- break;
-
- case kNotifyFileRead:
- Read(
- fileOp->data.read.offset,
- fileOp->data.read.buffer,
- fileOp->data.read.bytes
- );
- break;
-
- case kNotifyFileWrite:
- Write(
- fileOp->data.write.offset,
- fileOp->data.write.buffer,
- fileOp->data.write.bytes
- );
- break;
-
- }
-
- // Leave our local critical section
- m_critSect.Leave();
-
- // Dispatch a completion notification
- if (fileOp->notify) {
- fileOp->data.flush.asyncId = asyncId;
- m_notifyProc(
- (AsyncFile)this,
- fileOp->code,
- &fileOp->data.flush,
- &m_userState
- );
- }
-
-}
-
-//===========================================================================
-void CFile::Delete (void * op) {
- FileOp * fileOp = (FileOp *)op;
- delete fileOp;
-}
-
-//===========================================================================
-void CFile::Read (
- uint64_t offset,
- void * buffer,
- unsigned bytes
-) {
-
- // Seek to the start of the read
- Seek(offset, kFileSeekFromBegin);
-
- // Perform the read
- DWORD bytesRead;
- BOOL result = ReadFile(
- m_handle,
- buffer,
- bytes,
- &bytesRead,
- nil // overlapped
- );
-
- // Handle errors
- if (bytesRead != bytes)
- memset((uint8_t *)buffer + bytesRead, 0, bytes - bytesRead);
- if ( (!result && (GetLastError() != ERROR_IO_PENDING)) ||
- (bytesRead != bytes) )
- LogMsg(kLogFatal, "failed: ReadFile");
-
-}
-
-//===========================================================================
-bool CFile::Seek (uint64_t offset, EFileSeekFrom from) {
- COMPILER_ASSERT(kFileSeekFromBegin == FILE_BEGIN);
- COMPILER_ASSERT(kFileSeekFromCurrent == FILE_CURRENT);
- COMPILER_ASSERT(kFileSeekFromEnd == FILE_END);
-
- LONG low = (LONG)(offset % 0x100000000ul);
- LONG high = (LONG)(offset / 0x100000000ul);
- uint32_t result = SetFilePointer(m_handle, low, &high, from);
- if ((result == (uint32_t)-1) && (GetLastError() != NO_ERROR)) {
- LogMsg(kLogFatal, "failed: SetFilePointer");
- return false;
- }
- else
- return true;
-}
-
-//===========================================================================
-void CFile::SetLastWriteTime (uint64_t lastWriteTime) {
- COMPILER_ASSERT(sizeof(lastWriteTime) == sizeof(FILETIME));
- SetFileTime(m_handle, nil, nil, (const FILETIME *)&lastWriteTime);
-}
-
-//===========================================================================
-void CFile::Truncate (uint64_t size) {
- ASSERT(size != kAsyncFileDontTruncate);
-
- if (Seek(size, kFileSeekFromBegin) && !SetEndOfFile(m_handle))
- LogMsg(kLogFatal, "failed: SetEndOfFile");
-}
-
-//===========================================================================
-void CFile::Write (
- uint64_t offset,
- const void * buffer,
- unsigned bytes
-) {
-
- // Seek to the start of the write
- Seek(offset, kFileSeekFromBegin);
-
- // Perform the write
- DWORD bytesWritten;
- BOOL result = WriteFile(
- m_handle,
- buffer,
- bytes,
- &bytesWritten,
- nil // overlapped
- );
-
- // Handle errors
- if ( (!result && (GetLastError() != ERROR_IO_PENDING)) ||
- (bytesWritten != bytes) ) {
- LogMsg(kLogFatal, "failed: WriteFile");
- if (!result && (GetLastError() == ERROR_DISK_FULL)) {
- MessageBox(nil, "Disk full!", "Error", MB_ICONSTOP | MB_SYSTEMMODAL);
-// DebugDisableLeakChecking();
- ExitProcess(1);
- }
- }
-
-}
-
-
-/****************************************************************************
-*
-* Exported functions
-*
-***/
-
-//===========================================================================
-void W9xFileClose (
- AsyncFile file,
- uint64_t truncateSize
-) {
-
- // Dereference the object
- CFile * object = (CFile *)file;
-
- // If requested, truncate the file
- if (truncateSize != kAsyncFileDontTruncate)
- object->Truncate(truncateSize);
-
- // Close the file object
- object->Close();
-
-}
-
-//===========================================================================
-AsyncId W9xFileCreateSequence (
- AsyncFile file,
- bool notify,
- void * param
-) {
-
- // Dereference the object
- CFile * object = (CFile *)file;
-
- // Queue an operation
- FileOp * op = new FileOp;
- op->code = kNotifyFileSequence;
- op->notify = notify;
- op->data.flush.param = param;
- return object->Queue(op);
-
-}
-
-//===========================================================================
-AsyncId W9xFileFlushBuffers (
- AsyncFile file,
- uint64_t truncateSize,
- bool notify,
- void * param
-) {
-
- // Dereference the object
- CFile * object = (CFile *)file;
-
- // Queue an operation
- FileOp * op = new FileOp;
- op->code = kNotifyFileFlush;
- op->notify = notify;
- op->data.flush.param = param;
- op->data.flush.truncateSize = truncateSize;
- // op->data.flush.error filled in upon completion
- return object->Queue(op);
-
-}
-
-//===========================================================================
-AsyncFile W9xFileOpen (
- const wchar_t fullPath[],
- FAsyncNotifyFileProc notifyProc,
- EFileError * error,
- unsigned desiredAccess,
- unsigned openMode,
- unsigned shareModeFlags,
- void * userState,
- uint64_t * fileSize,
- uint64_t * fileLastWriteTime
-) {
- HANDLE fileHandle = CreateFileW(
- fullPath,
- desiredAccess,
- shareModeFlags,
- nil, // plSecurityAttributes
- openMode,
- 0, // attributeFlags
- nil // hTemplateFile
- );
- *error = AsyncGetLastFileError();
-
- if (INVALID_HANDLE_VALUE == fileHandle)
- return nil;
-
- // don't allow users to open devices like "LPT1", etc.
- if (GetFileType(fileHandle) != FILE_TYPE_DISK) {
- LogMsg(kLogFatal, "failed: !FILE_TYPE_DISK");
- *error = kFileErrorFileNotFound;
- CloseHandle(fileHandle);
- return nil;
- }
-
- // Get the file size
- DWORD sizeHi, sizeLo = GetFileSize(fileHandle, &sizeHi);
- if ((sizeLo == (DWORD) -1) && (NO_ERROR != GetLastError())) {
- *error = AsyncGetLastFileError();
- LogMsg(kLogFatal, "failed: GetFileSize");
- CloseHandle(fileHandle);
- return nil;
- }
- const uint64_t size = ((uint64_t) sizeHi << (uint64_t) 32) | (uint64_t) sizeLo;
-
- uint64_t lastWriteTime;
- ASSERT(sizeof(lastWriteTime) >= sizeof(FILETIME));
- GetFileTime(fileHandle, nil, nil, (FILETIME *) &lastWriteTime);
-
- // Create a file object
- CFile * object = new CFile(
- fileHandle,
- notifyProc,
- userState
- );
-
- // return out parameters
- if (fileSize)
- *fileSize = size;
- if (fileLastWriteTime)
- *fileLastWriteTime = lastWriteTime;
- return (AsyncFile)object;
-}
-
-//===========================================================================
-AsyncId W9xFileRead (
- AsyncFile file,
- uint64_t offset,
- void * buffer,
- unsigned bytes,
- unsigned flags,
- void * param
-) {
-
- // Dereference the object
- CFile * object = (CFile *)file;
-
- // Perform synchronous operations immediately
- if (flags & kAsyncFileRwSync) {
- object->Read(offset, buffer, bytes);
- return 0;
- }
-
- // Queue asynchronous operations
- else {
- FileOp * op = new FileOp;
- op->code = kNotifyFileRead;
- op->notify = (flags & kAsyncFileRwNotify) != 0;
- op->data.read.param = param;
- op->data.read.offset = offset;
- op->data.read.buffer = (uint8_t *)buffer;
- op->data.read.bytes = bytes;
- return object->Queue(op);
- }
-
-}
-
-//===========================================================================
-void W9xFileSetLastWriteTime (
- AsyncFile file,
- uint64_t lastWriteTime
-) {
-
- // Dereference the object
- CFile * object = (CFile *)file;
-
- // Set the file time
- object->SetLastWriteTime(lastWriteTime);
-
-}
-
-//===========================================================================
-uint64_t W9xFileGetLastWriteTime (
- const wchar_t fileName[]
-) {
- WIN32_FILE_ATTRIBUTE_DATA info;
- bool f = GetFileAttributesExW(fileName, GetFileExInfoStandard, &info);
- return f ? *((uint64_t *) &info.ftLastWriteTime) : 0;
-}
-
-//===========================================================================
-AsyncId W9xFileWrite (
- AsyncFile file,
- uint64_t offset,
- const void * buffer,
- unsigned bytes,
- unsigned flags,
- void * param
-) {
-
- // Dereference the object
- CFile * object = (CFile *)file;
-
- // Perform synchronous operations immediately
- if (flags & kAsyncFileRwSync) {
- object->Write(offset, buffer, bytes);
- return 0;
- }
-
- // Queue asynchronous operations
- else {
- FileOp * op = new FileOp;
- op->code = kNotifyFileWrite;
- op->notify = (flags & kAsyncFileRwNotify) != 0;
- op->data.write.param = param;
- op->data.write.offset = offset;
- op->data.write.buffer = (uint8_t *)buffer;
- op->data.write.bytes = bytes;
- return object->Queue(op);
- }
-
-}
-
-//============================================================================
-bool W9xFileSeek (
- AsyncFile file,
- uint64_t distance,
- EFileSeekFrom from
-) {
- CFile * object = (CFile *)file;
- return object->Seek(distance, from);
-}
-
-
-} // namespace W9x
diff --git a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9xInt.h b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9xInt.h
index f8668c1b..d518dbe1 100644
--- a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9xInt.h
+++ b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/W9x/pnAceW9xInt.h
@@ -86,61 +86,6 @@ bool W9xThreadWaitId (
AsyncId asyncId,
unsigned timeoutMs
);
-
-AsyncFile W9xFileOpen (
- const wchar_t fullPath[],
- FAsyncNotifyFileProc notifyProc,
- EFileError * error,
- unsigned desiredAccess,
- unsigned openMode,
- unsigned shareModeFlags,
- void * userState,
- uint64_t * fileSize,
- uint64_t * fileLastWriteTime
-);
-void W9xFileClose (
- AsyncFile file,
- uint64_t truncateSize
-);
-void W9xFileSetLastWriteTime (
- AsyncFile file,
- uint64_t lastWriteTime
-);
-uint64_t W9xFileGetLastWriteTime (
- const wchar_t fileName[]
-);
-AsyncId W9xFileFlushBuffers (
- AsyncFile file,
- uint64_t truncateSize,
- bool notify,
- void * param
-);
-AsyncId W9xFileRead (
- AsyncFile file,
- uint64_t offset,
- void * buffer,
- unsigned bytes,
- unsigned flags,
- void * param
-);
-AsyncId W9xFileWrite (
- AsyncFile file,
- uint64_t offset,
- const void *buffer,
- unsigned bytes,
- unsigned flags,
- void * param
-);
-AsyncId W9xFileCreateSequence (
- AsyncFile file,
- bool notify,
- void * param
-);
-bool W9xFileSeek (
- AsyncFile file,
- uint64_t distance,
- EFileSeekFrom from
-);
void W9xSocketConnect (
AsyncCancelId * cancelId,
const NetAddress & netAddr,
diff --git a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/pnAceInt.h b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/pnAceInt.h
index 3a2d274b..83270e82 100644
--- a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/pnAceInt.h
+++ b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/Private/pnAceInt.h
@@ -103,76 +103,6 @@ typedef void (* FSignalShutdown) ();
typedef void (* FWaitForShutdown) ();
typedef void (* FSleep) (unsigned sleepMs);
-// Files
-typedef AsyncFile (* FAsyncFileOpen) (
- const wchar_t fullPath[],
- FAsyncNotifyFileProc notifyProc,
- EFileError * error,
- unsigned desiredAccess,
- unsigned openMode,
- unsigned shareModeFlags,
- void * userState,
- uint64_t * fileSize,
- uint64_t * fileLastWriteTime
-);
-
-typedef void (* FAsyncFileClose) (
- AsyncFile file,
- uint64_t truncateSize
-);
-
-typedef void (* FAsyncFileSetLastWriteTime) (
- AsyncFile file,
- uint64_t lastWriteTime
-);
-
-typedef uint64_t (* FAsyncFileGetLastWriteTime) (
- const wchar_t fileName[]
-);
-
-typedef AsyncId (* FAsyncFileFlushBuffers) (
- AsyncFile file,
- uint64_t truncateSize,
- bool notify,
- void * param
-);
-
-typedef AsyncId (* FAsyncFileRead) (
- AsyncFile file,
- uint64_t offset,
- void * buffer,
- unsigned bytes,
- unsigned flags,
- void * param
-);
-
-typedef AsyncId (* FAsyncFileWrite) (
- AsyncFile file,
- uint64_t offset,
- const void * buffer,
- unsigned bytes,
- unsigned flags,
- void * param
-);
-
-typedef AsyncId (* FAsyncFileCreateSequence) (
- AsyncFile file,
- bool notify,
- void * param
-);
-
-typedef bool (* FAsyncFileSeek) (
- AsyncFile file,
- uint64_t distance,
- EFileSeekFrom from
-);
-
-typedef bool (* FAsyncFileWaitId) (
- AsyncFile file,
- AsyncId asyncId,
- unsigned timeoutMs
-);
-
// Sockets
typedef void (* FAsyncSocketConnect) (
AsyncCancelId * cancelId,
@@ -252,17 +182,6 @@ struct AsyncApi {
FWaitForShutdown waitForShutdown;
FSleep sleep;
- // Files
- FAsyncFileOpen fileOpen;
- FAsyncFileClose fileClose;
- FAsyncFileRead fileRead;
- FAsyncFileWrite fileWrite;
- FAsyncFileFlushBuffers fileFlushBuffers;
- FAsyncFileSetLastWriteTime fileSetLastWriteTime;
- FAsyncFileGetLastWriteTime fileGetLastWriteTime;
- FAsyncFileCreateSequence fileCreateSequence;
- FAsyncFileSeek fileSeek;
-
// Sockets
FAsyncSocketConnect socketConnect;
FAsyncSocketConnectCancel socketConnectCancel;
diff --git a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceIo.cpp b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceIo.cpp
index cf4d78c2..bd4ef8d1 100644
--- a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceIo.cpp
+++ b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceIo.cpp
@@ -203,179 +203,6 @@ static unsigned GetConnHash (
*
***/
-//===========================================================================
-EFileError AsyncGetLastFileError () {
- const unsigned error = GetLastError();
- switch (error) {
-
- case NO_ERROR:
- return kFileSuccess;
-
- case ERROR_FILE_NOT_FOUND:
- return kFileErrorFileNotFound;
-
- case ERROR_ACCESS_DENIED:
- case ERROR_FILE_EXISTS:
- case ERROR_ALREADY_EXISTS:
- return kFileErrorAccessDenied;
-
- case ERROR_SHARING_VIOLATION:
- return kFileErrorSharingViolation;
-
- case ERROR_BAD_NETPATH:
- case ERROR_PATH_NOT_FOUND:
- case ERROR_INVALID_NAME:
- case ERROR_BAD_NET_NAME:
- case ERROR_CANT_ACCESS_DOMAIN_INFO:
- case ERROR_NETWORK_UNREACHABLE:
- case ERROR_HOST_UNREACHABLE:
- return kFileErrorPathNotFound;
- }
-
- LogMsg(kLogPerf, "Unexpected Win32 error [%#x]", error);
-
- return kFileErrorPathNotFound;
-}
-
-//============================================================================
-const wchar_t * FileErrorToString (EFileError error) {
-
- static wchar_t * s_fileErrorStrings[] = {
- L"FileSuccess",
- L"FileErrorInvalidParameter",
- L"FileErrorFileNotFound",
- L"FileErrorPathNotFound",
- L"FileErrorAccessDenied",
- L"FileErrorSharingViolation",
- };
- COMPILER_ASSERT(kNumFileErrors == arrsize(s_fileErrorStrings));
-
- return s_fileErrorStrings[error];
-}
-
-//============================================================================
-AsyncFile AsyncFileOpen (
- const wchar_t fullPath[],
- FAsyncNotifyFileProc notifyProc,
- EFileError * error,
- unsigned desiredAccess,
- unsigned openMode,
- unsigned shareModeFlags,
- void * userState,
- uint64_t * fileSize,
- uint64_t * fileLastWriteTime
-) {
- ASSERT(g_api.fileOpen);
- return g_api.fileOpen(
- fullPath,
- notifyProc,
- error,
- desiredAccess,
- openMode,
- shareModeFlags,
- userState,
- fileSize,
- fileLastWriteTime
- );
-}
-
-//============================================================================
-void AsyncFileClose (
- AsyncFile file,
- uint64_t truncateSize
-) {
- ASSERT(g_api.fileClose);
- g_api.fileClose(file, truncateSize);
-}
-
-//============================================================================
-void AsyncFileSetLastWriteTime (
- AsyncFile file,
- uint64_t lastWriteTime
-) {
- ASSERT(g_api.fileSetLastWriteTime);
- g_api.fileSetLastWriteTime(file, lastWriteTime);
-}
-
-//============================================================================
-uint64_t AsyncFileGetLastWriteTime (
- const wchar_t fileName[]
-) {
- ASSERT(g_api.fileGetLastWriteTime);
- return g_api.fileGetLastWriteTime(fileName);
-}
-
-//============================================================================
-AsyncId AsyncFileFlushBuffers (
- AsyncFile file,
- uint64_t truncateSize,
- bool notify,
- void * param
-) {
- ASSERT(g_api.fileFlushBuffers);
- return g_api.fileFlushBuffers(file, truncateSize, notify, param);
-}
-
-//============================================================================
-AsyncId AsyncFileRead (
- AsyncFile file,
- uint64_t offset,
- void * buffer,
- unsigned bytes,
- unsigned flags,
- void * param
-) {
- ASSERT(g_api.fileRead);
- return g_api.fileRead(
- file,
- offset,
- buffer,
- bytes,
- flags,
- param
- );
-}
-
-//============================================================================
-AsyncId AsyncFileWrite (
- AsyncFile file,
- uint64_t offset,
- const void * buffer,
- unsigned bytes,
- unsigned flags,
- void * param
-) {
- ASSERT(g_api.fileWrite);
- return g_api.fileWrite(
- file,
- offset,
- buffer,
- bytes,
- flags,
- param
- );
-}
-
-//============================================================================
-AsyncId AsyncFileCreateSequence (
- AsyncFile file,
- bool notify,
- void * param
-) {
- ASSERT(g_api.fileCreateSequence);
- return g_api.fileCreateSequence(file, notify, param);
-}
-
-//============================================================================
-bool AsyncFileSeek (
- AsyncFile file,
- uint64_t distance,
- EFileSeekFrom seekFrom
-) {
- ASSERT(g_api.fileSeek);
- return g_api.fileSeek(file, distance, seekFrom);
-}
-
//===========================================================================
void AsyncSocketConnect (
AsyncCancelId * cancelId,
diff --git a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceLog.cpp b/Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceLog.cpp
deleted file mode 100644
index dfb4584d..00000000
--- a/Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceLog.cpp
+++ /dev/null
@@ -1,478 +0,0 @@
-/*==LICENSE==*
-
-CyanWorlds.com Engine - MMOG client, server and tools
-Copyright (C) 2011 Cyan Worlds, Inc.
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-
-Additional permissions under GNU GPL version 3 section 7
-
-If you modify this Program, or any covered work, by linking or
-combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
-NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
-JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
-(or a modified version of those libraries),
-containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
-PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
-JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
-licensors of this Program grant you additional
-permission to convey the resulting work. Corresponding Source for a
-non-source form of such a combination shall include the source code for
-the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
-work.
-
-You can contact Cyan Worlds, Inc. by email legal@cyan.com
- or by snail mail at:
- Cyan Worlds, Inc.
- 14617 N Newport Hwy
- Mead, WA 99021
-
-*==LICENSE==*/
-/*****************************************************************************
-*
-* $/Plasma20/Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceLog.cpp
-*
-***/
-
-#include "Pch.h"
-#pragma hdrstop
-
-#if defined(PLASMA_EXTERNAL_RELEASE)
- // If this is an external build then don't write log files
- #define ACELOG_NO_LOG_FILES
-#endif
-
-
-namespace AsyncLog {
-
-/****************************************************************************
-*
-* Private
-*
-***/
-
-static const unsigned kLogFlushMs = 10 * 1000;
-
-enum ELogType {
-#ifdef SERVER
- kLogTypeDebug,
- kLogTypePerf,
- kLogTypeError,
-#else
- kLogTypeDebug,
-#endif
- kNumLogTypes
-};
-
-static bool s_breakOnErrors;
-static wchar_t s_directory[MAX_PATH];
-static CCritSect s_logCrit[kNumLogTypes];
-static char * s_logBuf[kNumLogTypes];
-static unsigned s_logPos[kNumLogTypes];
-static uint64_t s_logWritePos[kNumLogTypes];
-static TimeDesc s_logTime[kNumLogTypes];
-static unsigned s_logWriteMs[kNumLogTypes];
-static AsyncFile s_logFile[kNumLogTypes];
-static long s_opsPending;
-static bool s_running;
-static AsyncTimer * s_timer;
-
-static unsigned s_logSize[kNumLogTypes] = {
-#ifdef SERVER
- 64 * 1024,
- 64 * 1024,
- 8 * 1024,
-#else
- 64 * 1024,
-#endif
-};
-
-static const wchar_t * s_logNameFmt[kNumLogTypes] = {
-#ifdef SERVER
- L"Dbg%02u%02u%02u.log",
- L"Inf%02u%02u%02u.log",
- L"Err%02u%02u%02u.log",
-#else
- L"%s%02u%02u%02u.log",
-#endif
-};
-
-static ELogType s_logSeverityToType[kNumLogSeverity] = {
-#ifdef SERVER
- kLogTypeDebug, // kLogDebug
- kLogTypePerf, // kLogPerf
- kLogTypeError, // kLogError
- kLogTypeError, // kLogFatal
-#else
- kLogTypeDebug, // kLogDebug
- kLogTypeDebug, // kLogPerf
- kLogTypeDebug, // kLogError
- kLogTypeDebug, // kLogFatal
-#endif
-};
-
-static char * s_logSeverityToText[kNumLogSeverity] = {
- "Debug",
- "Info",
- "Error",
- "Fatal",
-};
-
-
-/****************************************************************************
-*
-* Local functions
-*
-***/
-
-//============================================================================
-static void LogFileNotifyProc (
- AsyncFile file,
- EAsyncNotifyFile code,
- AsyncNotifyFile * notify,
- void ** userState
-) {
- switch (code) {
- case kNotifyFileWrite:
- free(notify->param);
- AtomicAdd(&s_opsPending, -1);
- break;
-
- case kNotifyFileFlush:
- AsyncFileClose(file, kAsyncFileDontTruncate);
- AtomicAdd(&s_opsPending, -1);
- break;
-
- DEFAULT_FATAL(code);
- }
-}
-
-//============================================================================
-static void AllocLogBuffer_CS (unsigned index) {
- ASSERT(!s_logBuf[index]);
- s_logBuf[index] = (char *)malloc(s_logSize[index]);
- s_logPos[index] = 0;
-
- if (!s_logBuf[index])
- ErrorAssert(__LINE__, __FILE__, "Out of memory");
-}
-
-//============================================================================
-static void FreeLogBuffer_CS (unsigned index) {
- if (s_logBuf[index]) {
- free(s_logBuf[index]);
- s_logBuf[index] = nil;
- }
-}
-
-//============================================================================
-static void GetLogFilename (
- unsigned index,
- TimeDesc timeDesc,
- wchar_t * filename,
- unsigned chars
-) {
- StrPrintf(
- filename,
- chars,
- s_logNameFmt[index],
-#ifndef SERVER
- ProductShortName(),
-#endif
- timeDesc.year % 100,
- timeDesc.month,
- timeDesc.day
- );
- PathAddFilename(filename, s_directory, filename, chars);
-}
-
-//============================================================================
-static bool OpenLogFile_CS (unsigned index) {
- if (s_logFile[index] != nil)
- return true;
-
- // Build filename
- wchar_t filename[MAX_PATH];
- GetLogFilename(
- index,
- s_logTime[index],
- filename,
- arrsize(filename)
- );
-
- // Open file
- uint64_t fileTime;
- EFileError fileError;
- bool fileExist = PathDoesFileExist(filename);
- s_logFile[index] = AsyncFileOpen(
- filename,
- LogFileNotifyProc,
- &fileError,
- kAsyncFileWriteAccess,
- kAsyncFileModeOpenAlways,
- kAsyncFileShareRead,
- nil, // userState
- &s_logWritePos[index],
- &fileTime
- );
-
- if (s_logFile[index] == nil)
- return false;
-
- TimeGetDesc(fileTime, &s_logTime[index]);
- s_logWriteMs[index] = TimeGetMs();
-
- // Seek to end of file
- AsyncFileSeek(s_logFile[index], s_logWritePos[index], kFileSeekFromBegin);
-
- // If this is a new file, write uint8_t Order Mark
- if (!fileExist) {
- static const char s_bom[] = "\xEF\xBB\xBF";
- AsyncFileWrite(
- s_logFile[index],
- s_logWritePos[index],
- s_bom,
- arrsize(s_bom)- 1,
- kAsyncFileRwSync, // perform blocking write
- nil // param
- );
- s_logWritePos[index] += arrsize(s_bom) - 1;
- }
-
- // Write a sentinel in case there are multiple runs in one day
- static const char s_logOpened[] = "Log Opened\r\n";
- AsyncFileWrite(
- s_logFile[index],
- s_logWritePos[index],
- s_logOpened,
- arrsize(s_logOpened)- 1,
- kAsyncFileRwSync, // perform blocking write
- nil
- );
- s_logWritePos[index] += arrsize(s_logOpened) - 1;
-
- return true;
-}
-
-//============================================================================
-static void WriteLogFile_CS (unsigned index, bool close) {
- unsigned flags = kAsyncFileRwSync; // kAsyncFileRwNotify
- if (s_logPos[index]) {
- if (OpenLogFile_CS(index)) {
- AsyncFileWrite(
- s_logFile[index],
- s_logWritePos[index],
- s_logBuf[index],
- s_logPos[index],
- flags,
- s_logBuf[index]
- );
- if (flags == kAsyncFileRwSync)
- delete s_logBuf[index];
- else
- AtomicAdd(&s_opsPending, 1);
- s_logWritePos[index] += s_logPos[index];
- s_logWriteMs[index] = TimeGetMs();
- s_logBuf[index] = nil;
- s_logPos[index] = 0;
- }
- }
-
- if (close && s_logFile[index]) {
- if (flags == kAsyncFileRwNotify) {
- AtomicAdd(&s_opsPending, 1);
- AsyncFileFlushBuffers(
- s_logFile[index],
- kAsyncFileDontTruncate,
- true,
- nil
- );
- }
- else {
- AsyncFileClose(
- s_logFile[index],
- kAsyncFileDontTruncate
- );
- }
- s_logFile[index] = nil;
- }
-}
-
-//============================================================================
-static void FlushLogFile_CS (
- unsigned index,
- TimeDesc timeDesc
-) {
- bool close = !s_running || (s_logTime[index].day != timeDesc.day);
- WriteLogFile_CS(index, close);
- if (close)
- s_logTime[index] = timeDesc;
-}
-
-//============================================================================
-static unsigned FlushLogsTimerCallback (void *) {
- AsyncLogFlush();
- return kAsyncTimeInfinite;
-}
-
-
-} using namespace AsyncLog;
-
-
-/****************************************************************************
-*
-* Exported functions
-*
-***/
-
-//============================================================================
-void AsyncLogInitialize (
- const wchar_t logDirName[],
- bool breakOnErrors
-) {
- s_running = true;
-
- // Save options
- s_breakOnErrors = breakOnErrors;
-
- // Build log directory name
-#ifdef SERVER
- PathGetProgramDirectory(s_directory, arrsize(s_directory));
-#else
- PathGetUserDirectory(s_directory, arrsize(s_directory));
-#endif
- PathAddFilename(s_directory, s_directory, logDirName, arrsize(s_directory));
-
-#ifndef ACELOG_NO_LOG_FILES
- // Create log directory
- if (kPathCreateDirSuccess != PathCreateDirectory(s_directory, 0))
- PathRemoveFilename(s_directory, s_directory, arrsize(s_directory));
-
- // Allocate log buffers
- for (unsigned index = 0; index < kNumLogTypes; ++index) {
- s_logCrit[index].Enter();
- AllocLogBuffer_CS(index);
- s_logCrit[index].Leave();
- }
-
- AsyncTimerCreate(&s_timer, FlushLogsTimerCallback, kAsyncTimeInfinite, nil);
-#endif // ndef ACELOG_NO_LOG_FILES
-}
-
-//============================================================================
-void AsyncLogDestroy () {
- s_running = false;
-
-#ifndef ACELOG_NO_LOG_FILES
- AsyncTimerDelete(s_timer, kAsyncTimerDestroyWaitComplete);
-
- for (unsigned index = 0; index < kNumLogTypes; ++index) {
- s_logCrit[index].Enter();
- {
- WriteLogFile_CS(index, true);
- FreeLogBuffer_CS(index);
- }
- s_logCrit[index].Leave();
- }
- while (s_opsPending)
- AsyncSleep(10);
-#endif // ndef ACELOG_NO_LOG_FILES
-}
-
-//============================================================================
-void AsyncLogFlush () {
-#ifndef ACELOG_NO_LOG_FILES
- TimeDesc timeDesc;
- TimeGetDesc(TimeGetTime(), &timeDesc);
-
- for (unsigned index = 0; index < kNumLogTypes; ++index) {
- s_logCrit[index].Enter();
- FlushLogFile_CS(index, timeDesc);
- s_logCrit[index].Leave();
- }
-#endif // ndef ACELOG_NO_LOG_FILES
-}
-
-//============================================================================
-void LogBreakOnErrors (bool breakOnErrors) {
- s_breakOnErrors = breakOnErrors;
-}
-
-//============================================================================
-void AsyncLogWriteMsg (
- const wchar_t facility[],
- ELogSeverity severity,
- const wchar_t msg[]
-) {
- if (!s_running)
- return;
-
-#ifndef ACELOG_NO_LOG_FILES
- TimeDesc timeDesc;
- TimeGetDesc(TimeGetTime(), &timeDesc);
-
- char buffer[2048];
- const unsigned chars = StrPrintf(
- buffer,
- arrsize(buffer),
- "%02u/%02u/%02u % 2u:%02u:%02u [%S] %s %S\r\n",
- timeDesc.month,
- timeDesc.day,
- timeDesc.year % 100,
- timeDesc.hour,
- timeDesc.minute,
- timeDesc.second,
- facility,
- s_logSeverityToText[severity],
- msg
- );
-
- unsigned index = s_logSeverityToType[severity];
- s_logCrit[index].Enter();
- {
- // If day changed then write and flush file
- if (s_logTime[index].day != timeDesc.day)
- FlushLogFile_CS(index, timeDesc);
- // Otherwise if the buffer is full then write to file
- else if (s_logPos[index] + chars > s_logSize[index])
- WriteLogFile_CS(index, false);
-
- // Allocate log buffer if necessary
- if (!s_logBuf[index])
- AllocLogBuffer_CS(index);
-
- // Add new data to the log buffer
- memcpy(s_logBuf[index] + s_logPos[index], buffer, chars);
- s_logPos[index] += chars;
-
- // Write, flush and close file immediately if this is a fatal error
- if (severity == kLogFatal)
- WriteLogFile_CS(index, true);
-
- // Drop to debugger if this is an error msg and that option was specified
- if (s_breakOnErrors && severity >= kLogError)
- DebugBreakIfDebuggerPresent();
- }
- s_logCrit[index].Leave();
-
- // Queue flush
- AsyncTimerUpdate(s_timer, kLogFlushMs, kAsyncTimerUpdateSetPriorityHigher);
-#endif // ndef ACELOG_NO_LOG_FILES
-}
-
-//============================================================================
-void AsyncLogGetDirectory (wchar_t * dest, unsigned destChars) {
- ASSERT(dest);
- StrCopy(dest, s_directory, destChars);
-}
diff --git a/Sources/Plasma/PubUtilLib/plNetClientComm/plNetClientComm.cpp b/Sources/Plasma/PubUtilLib/plNetClientComm/plNetClientComm.cpp
index b817fbae..fb403161 100644
--- a/Sources/Plasma/PubUtilLib/plNetClientComm/plNetClientComm.cpp
+++ b/Sources/Plasma/PubUtilLib/plNetClientComm/plNetClientComm.cpp
@@ -151,15 +151,6 @@ static NetCommMsgHandler s_defaultHandler(0, nil, nil);
static NetCommMsgHandler s_preHandler(0, nil, nil);
-//============================================================================
-static void INetLogCallback (
- ELogSeverity severity,
- const wchar_t msg[]
-) {
- // Use the async log facility
- AsyncLogWriteMsg(ProductShortName(), severity, msg);
-}
-
//============================================================================
static void INetErrorCallback (
ENetProtocol protocol,
@@ -755,9 +746,7 @@ void NetCommChangeMyPassword (
void NetCommStartup () {
s_shutdown = false;
- LogRegisterHandler(INetLogCallback);
AsyncCoreInitialize();
- AsyncLogInitialize(L"Log", false);
wchar_t productString[256];
ProductString(productString, arrsize(productString));
LogMsg(kLogPerf, L"Client: %s", productString);
@@ -797,9 +786,7 @@ void NetCommShutdown () {
NetCliFileDisconnect();
NetClientDestroy(false);
- AsyncLogDestroy();
AsyncCoreDestroy(30 * 1000);
- LogUnregisterHandler(INetLogCallback);
}
//============================================================================