📄 win32.cxx
字号:
if (::GetLastError() == ERROR_INVALID_HANDLE)
break;
// sometimes WaitForMultipleObjects fails. No idea why, so allow some retries
else {
retries--;
if (retries <= 0)
break;
}
}
}
}
void PProcess::SignalTimerChange()
{
deleteThreadMutex.Wait();
if (houseKeeper == NULL)
houseKeeper = new HouseKeepingThread;
else
houseKeeper->breakBlock.Signal();
deleteThreadMutex.Signal();
}
#ifndef _DEBUG
#undef PMEMORY_CHECK
#endif
///////////////////////////////////////////////////////////////////////////////
// PProcess
PProcess::~PProcess()
{
// do whatever needs to shutdown
PreShutdown();
Sleep(100); // Give threads time to die a natural death
// Get rid of the house keeper (majordomocide)
delete houseKeeper;
// OK, if there are any left we get really insistent...
activeThreadMutex.Wait();
for (PINDEX i = 0; i < activeThreads.GetSize(); i++) {
PThread & thread = activeThreads.GetDataAt(i);
if (this != &thread && !thread.IsTerminated())
TerminateThread(thread.GetHandle(), 1); // With extreme prejudice
}
activeThreadMutex.Signal();
deleteThreadMutex.Wait();
autoDeleteThreads.RemoveAll();
deleteThreadMutex.Signal();
#if PMEMORY_CHECK || _DEBUG
extern void PWaitOnExitConsoleWindow();
PWaitOnExitConsoleWindow();
#endif
}
PString PProcess::GetOSClass()
{
return "Windows";
}
PString PProcess::GetOSName()
{
OSVERSIONINFO info;
info.dwOSVersionInfoSize = sizeof(info);
GetVersionEx(&info);
switch (info.dwPlatformId) {
case VER_PLATFORM_WIN32s :
return "32s";
#ifdef VER_PLATFORM_WIN32_CE
case VER_PLATFORM_WIN32_CE :
return "CE";
#endif
case VER_PLATFORM_WIN32_WINDOWS :
if (info.dwMinorVersion < 10)
return "95";
if (info.dwMinorVersion < 90)
return "98";
return "ME";
case VER_PLATFORM_WIN32_NT :
if (info.dwMajorVersion < 5)
return "NT";
else if (info.dwMinorVersion == 0)
return "2000";
else if (info.dwMinorVersion == 1)
return "XP";
else
return "Server 2003";
}
return "?";
}
PString PProcess::GetOSHardware()
{
SYSTEM_INFO info;
GetSystemInfo(&info);
switch (info.wProcessorArchitecture) {
case PROCESSOR_ARCHITECTURE_INTEL :
switch (info.dwProcessorType) {
case PROCESSOR_INTEL_386 :
return "i386";
case PROCESSOR_INTEL_486 :
return "i486";
case PROCESSOR_INTEL_PENTIUM :
return "i586";
}
return "iX86";
case PROCESSOR_ARCHITECTURE_MIPS :
return "mips";
case PROCESSOR_ARCHITECTURE_ALPHA :
return "alpha";
case PROCESSOR_ARCHITECTURE_PPC :
return "ppc";
}
return "?";
}
PString PProcess::GetOSVersion()
{
OSVERSIONINFO info;
info.dwOSVersionInfoSize = sizeof(info);
GetVersionEx(&info);
WORD wBuildNumber = (WORD)info.dwBuildNumber;
return psprintf(wBuildNumber > 0 ? "v%u.%u.%u" : "v%u.%u",
info.dwMajorVersion, info.dwMinorVersion, wBuildNumber);
}
PDirectory PProcess::GetOSConfigDir()
{
#ifdef _WIN32_WCE
return PString("\\Windows");
#else
OSVERSIONINFO info;
info.dwOSVersionInfoSize = sizeof(info);
GetVersionEx(&info);
char dir[_MAX_PATH];
if (info.dwPlatformId != VER_PLATFORM_WIN32_NT) {
PAssertOS(GetWindowsDirectory(dir, sizeof(dir)) != 0);
return dir;
}
PAssertOS(GetSystemDirectory(dir, sizeof(dir)) != 0);
PDirectory sysdir = dir;
return sysdir; //+ "drivers\\etc";
#endif
}
PString PProcess::GetUserName() const
{
PString username;
unsigned long size = 50;
#ifndef _WIN32_WCE
::GetUserName(username.GetPointer((PINDEX)size), &size);
#else
TCHAR wcsuser[50] = {0};
HKEY hKeyComm, hKeyIdent;
RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Comm"), 0, 0, &hKeyComm);
RegOpenKeyEx(hKeyComm, _T("Ident"), 0, 0, &hKeyIdent);
DWORD dwType = REG_SZ; DWORD dw = 50;
if( ERROR_SUCCESS != RegQueryValueEx(
hKeyIdent, _T("Username"), NULL, &dwType, (LPBYTE) wcsuser, &dw)
|| !*wcsuser )
{
RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Ident"), 0, 0, &hKeyIdent);
dw = 50L;
if( ERROR_SUCCESS == RegQueryValueEx(
hKeyIdent, _T("Name"), NULL, &dwType, (LPBYTE) wcsuser, &dw))
wcscat( wcsuser, _T(" user") ); // like "Pocket_PC User"
}
USES_CONVERSION;
username = T2A(wcsuser);
#endif
username.MakeMinimumSize();
return username;
}
BOOL PProcess::SetUserName(const PString & username, BOOL)
{
if (username.IsEmpty())
return FALSE;
PAssertAlways(PUnimplementedFunction);
return FALSE;
}
PString PProcess::GetGroupName() const
{
return "Users";
}
BOOL PProcess::SetGroupName(const PString & groupname, BOOL)
{
if (groupname.IsEmpty())
return FALSE;
PAssertAlways(PUnimplementedFunction);
return FALSE;
}
DWORD PProcess::GetProcessID() const
{
return GetCurrentProcessId();
}
BOOL PProcess::IsServiceProcess() const
{
return FALSE;
}
BOOL PProcess::IsGUIProcess() const
{
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////
// PSemaphore
PSemaphore::PSemaphore(HANDLE h)
{
handle = h;
PAssertOS(handle != NULL);
}
PSemaphore::PSemaphore(unsigned initial, unsigned maxCount)
{
initialVal = initial;
maxCountVal = maxCount;
if (initial > maxCount)
initial = maxCount;
handle = CreateSemaphore(NULL, initial, maxCount, NULL);
PAssertOS(handle != NULL);
}
PSemaphore::PSemaphore(const PSemaphore & sem)
{
initialVal = sem.GetInitialVal();
maxCountVal = sem.GetMaxCountVal();
if (initialVal > maxCountVal)
initialVal = maxCountVal;
handle = CreateSemaphore(NULL, initialVal, maxCountVal, NULL);
PAssertOS(handle != NULL);
}
PSemaphore::~PSemaphore()
{
if (handle != NULL)
PAssertOS(CloseHandle(handle));
}
void PSemaphore::Wait()
{
PAssertOS(WaitForSingleObject(handle, INFINITE) != WAIT_FAILED);
}
BOOL PSemaphore::Wait(const PTimeInterval & timeout)
{
DWORD result = WaitForSingleObject(handle, timeout.GetInterval());
PAssertOS(result != WAIT_FAILED);
return result != WAIT_TIMEOUT;
}
void PSemaphore::Signal()
{
if (!ReleaseSemaphore(handle, 1, NULL))
PAssertOS(GetLastError() != ERROR_INVALID_HANDLE);
SetLastError(ERROR_SUCCESS);
}
BOOL PSemaphore::WillBlock() const
{
PSemaphore * unconst = (PSemaphore *)this;
if (!unconst->Wait(0))
return TRUE;
unconst->Signal();
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////
// PTimedMutex
PTimedMutex::PTimedMutex()
: PSemaphore(::CreateMutex(NULL, FALSE, NULL))
{
}
PTimedMutex::PTimedMutex(const PTimedMutex &)
: PSemaphore(::CreateMutex(NULL, FALSE, NULL))
{
}
void PTimedMutex::Signal()
{
PAssertOS(::ReleaseMutex(handle));
}
///////////////////////////////////////////////////////////////////////////////
// PSyncPoint
PSyncPoint::PSyncPoint()
: PSemaphore(::CreateEvent(NULL, FALSE, FALSE, NULL))
{
}
PSyncPoint::PSyncPoint(const PSyncPoint &)
: PSemaphore(::CreateEvent(NULL, FALSE, FALSE, NULL))
{
}
void PSyncPoint::Signal()
{
PAssertOS(::SetEvent(handle));
}
///////////////////////////////////////////////////////////////////////////////
// PDynaLink
PDynaLink::PDynaLink()
{
_hDLL = NULL;
}
PDynaLink::PDynaLink(const PString & name)
{
Open(name);
}
PDynaLink::~PDynaLink()
{
Close();
}
PString PDynaLink::GetExtension()
{
return ".DLL";
}
BOOL PDynaLink::Open(const PString & name)
{
#ifdef UNICODE
USES_CONVERSION;
_hDLL = LoadLibrary(A2T(name));
#else
_hDLL = LoadLibrary(name);
#endif
return _hDLL != NULL;
}
void PDynaLink::Close()
{
if (_hDLL != NULL) {
FreeLibrary(_hDLL);
_hDLL = NULL;
}
}
BOOL PDynaLink::IsLoaded() const
{
return _hDLL != NULL;
}
PString PDynaLink::GetName(BOOL full) const
{
PFilePathString str;
if (_hDLL != NULL)
{
#ifdef UNICODE
TCHAR path[_MAX_PATH];
GetModuleFileName(_hDLL, path, _MAX_PATH-1);
str=PString(path);
#else
GetModuleFileName(_hDLL, str.GetPointer(_MAX_PATH), _MAX_PATH-1);
#endif
if (!full)
{
str.Delete(0, str.FindLast('\\')+1);
PINDEX pos = str.Find(".DLL");
if (pos != P_MAX_INDEX)
str.Delete(pos, P_MAX_INDEX);
}
}
str.MakeMinimumSize();
return str;
}
BOOL PDynaLink::GetFunction(PINDEX index, Function & func)
{
if (_hDLL == NULL)
return FALSE;
#ifndef _WIN32_WCE
FARPROC p = GetProcAddress(_hDLL, (LPSTR)(DWORD)LOWORD(index));
#else
FARPROC p = GetProcAddress(_hDLL, (LPTSTR)(DWORD)LOWORD(index));
#endif
if (p == NULL)
return FALSE;
func = (Function)p;
return TRUE;
}
BOOL PDynaLink::GetFunction(const PString & name, Function & func)
{
if (_hDLL == NULL)
return FALSE;
#ifdef UNICODE
USES_CONVERSION;
FARPROC p = GetProcAddress(_hDLL, A2T(name));
#else
FARPROC p = GetProcAddress(_hDLL, name);
#endif
if (p == NULL)
return FALSE;
func = (Function)p;
return TRUE;
}
///////////////////////////////////////////////////////////////////////////////
// PDebugStream
PDebugStream::PDebugStream()
: ostream(&buffer)
{
}
PDebugStream::Buffer::Buffer()
{
setg(buffer, buffer, &buffer[sizeof(buffer)-2]);
setp(buffer, &buffer[sizeof(buffer)-2]);
}
int PDebugStream::Buffer::overflow(int c)
{
int bufSize = pptr() - pbase();
if (c != EOF) {
*pptr() = (char)c;
bufSize++;
}
if (bufSize != 0) {
char * p = pbase();
setp(p, epptr());
p[bufSize] = '\0';
#ifdef UNICODE
USES_CONVERSION;
OutputDebugString(A2T(p));
#else
OutputDebugString(p);
#endif
}
return 0;
}
int PDebugStream::Buffer::underflow()
{
return EOF;
}
int PDebugStream::Buffer::sync()
{
return overflow(EOF);
}
// End Of File ///////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -