📄 win32.cxx
字号:
* * Revision 1.7 1995/08/24 12:42:33 robertj * Changed PChannel so not a PContainer. * Rewrote PSerialChannel::Read yet again so can break out of I/O. * * Revision 1.6 1995/07/02 01:26:52 robertj * Changed thread internal variables. * Added service process support for NT. * * Revision 1.5 1995/06/17 01:03:08 robertj * Added NT service process type. * * Revision 1.4 1995/06/04 12:48:52 robertj * Fixed bug in directory path creation. * Fixed bug in comms channel open error. * * Revision 1.3 1995/04/25 11:33:54 robertj * Fixed Borland compiler warnings. * * Revision 1.2 1995/03/22 13:56:18 robertj * Fixed directory handle value check for closing directory. *// Revision 1.1 1995/03/14 12:45:20 robertj// Initial revision// */#include <ptlib.h>#include <process.h>#include <ptlib/msos/ptlib/debstrm.h>#include <winsock2.h>#include <ws2tcpip.h>#ifndef _WIN32_WCE#pragma comment(lib, "mpr.lib")#endif#define new PNEW#if defined(_WIN32_DCOM) #include <objbase.h> #pragma comment(lib, _OLE_LIB)#endif#include "../common/pglobalstatic.cxx"///////////////////////////////////////////////////////////////////////////////// PTimePTime::PTime(){ // Magic constant to convert epoch from 1601 to 1970 static const PInt64 delta = ((PInt64)369*365+(369/4)-3)*24*60*60U; static const PInt64 scale = 10000000; PInt64 timestamp;#ifndef _WIN32_WCE GetSystemTimeAsFileTime((LPFILETIME)×tamp);#else SYSTEMTIME SystemTime; GetSystemTime(&SystemTime); SystemTimeToFileTime(&SystemTime, (LPFILETIME)×tamp);#endif theTime = (time_t)(timestamp/scale - delta); microseconds = (long)(timestamp%scale/10);}#ifdef UNICODEstatic void PWIN32GetLocaleInfo(LCID Locale,LCTYPE LCType,LPSTR lpLCData,int cchData){ TCHAR* pw = new TCHAR[cchData+1]; GetLocaleInfo(Locale,LCType,pw,cchData); lpLCData[0]=0; WideCharToMultiByte(GetACP(), 0, pw, -1, lpLCData, cchData, NULL, NULL);}#else#define PWIN32GetLocaleInfo GetLocaleInfo#endifPString PTime::GetTimeSeparator(){ PString str; PWIN32GetLocaleInfo(GetUserDefaultLCID(), LOCALE_STIME, str.GetPointer(100), 99); str.MakeMinimumSize(); return str;}BOOL PTime::GetTimeAMPM(){ char str[2]; PWIN32GetLocaleInfo(GetUserDefaultLCID(), LOCALE_ITIME, str, sizeof(str)); return str[0] == '0';}PString PTime::GetTimeAM(){ PString str; PWIN32GetLocaleInfo(GetUserDefaultLCID(), LOCALE_S1159, str.GetPointer(100), 99); str.MakeMinimumSize(); return str;}PString PTime::GetTimePM(){ PString str; PWIN32GetLocaleInfo(GetUserDefaultLCID(), LOCALE_S2359, str.GetPointer(100), 99); str.MakeMinimumSize(); return str;}PString PTime::GetDayName(Weekdays dayOfWeek, NameType type){ PString str; // Of course Sunday is 6 and Monday is 1... PWIN32GetLocaleInfo(GetUserDefaultLCID(), (dayOfWeek+6)%7 + (type == Abbreviated ? LOCALE_SABBREVDAYNAME1 : LOCALE_SDAYNAME1), str.GetPointer(100), 99); str.MakeMinimumSize(); return str;}PString PTime::GetDateSeparator(){ PString str; PWIN32GetLocaleInfo(GetUserDefaultLCID(), LOCALE_SDATE, str.GetPointer(100), 99); str.MakeMinimumSize(); return str;}PString PTime::GetMonthName(Months month, NameType type){ PString str; PWIN32GetLocaleInfo(GetUserDefaultLCID(), month-1 + (type == Abbreviated ? LOCALE_SABBREVMONTHNAME1 : LOCALE_SMONTHNAME1), str.GetPointer(100), 99); str.MakeMinimumSize(); return str;}PTime::DateOrder PTime::GetDateOrder(){ char str[2]; PWIN32GetLocaleInfo(GetUserDefaultLCID(), LOCALE_IDATE, str, sizeof(str)); return (DateOrder)(str[0] - '0');}BOOL PTime::IsDaylightSavings(){ TIME_ZONE_INFORMATION tz; DWORD result = GetTimeZoneInformation(&tz); PAssertOS(result != 0xffffffff); return result == TIME_ZONE_ID_DAYLIGHT;}int PTime::GetTimeZone(TimeZoneType type){ TIME_ZONE_INFORMATION tz; PAssertOS(GetTimeZoneInformation(&tz) != 0xffffffff); if (type == DaylightSavings) tz.Bias += tz.DaylightBias; return -tz.Bias;}PString PTime::GetTimeZoneString(TimeZoneType type){ TIME_ZONE_INFORMATION tz; PAssertOS(GetTimeZoneInformation(&tz) != 0xffffffff); return type == StandardTime ? tz.StandardName : tz.DaylightName;}///////////////////////////////////////////////////////////////////////////////// PTimeInterval static unsigned GetDivisor(){ LARGE_INTEGER frequency; if (QueryPerformanceFrequency(&frequency)) return (unsigned)frequency.QuadPart/1000; return 0;}PTimeInterval PTimer::Tick(){ static unsigned divisor = GetDivisor(); if (divisor == 0) return (int)(GetTickCount()&0x7fffffff); LARGE_INTEGER count; QueryPerformanceCounter(&count); return count.QuadPart/divisor;}unsigned PTimer::Resolution(){ LARGE_INTEGER frequency; if (QueryPerformanceFrequency(&frequency) && frequency.QuadPart >= 1000) return 1; DWORD err = GetLastError();#ifndef _WIN32_WCE DWORD timeAdjustment; DWORD timeIncrement; BOOL timeAdjustmentDisabled; if (GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement, &timeAdjustmentDisabled)) return timeIncrement/10000; err = GetLastError();#endif return 55;}///////////////////////////////////////////////////////////////////////////////// Directoriesvoid PDirectory::Construct(){ hFindFile = INVALID_HANDLE_VALUE; fileinfo.cFileName[0] = '\0'; PCaselessString::AssignContents(CreateFullPath(*this, TRUE));}void PDirectory::CopyContents(const PDirectory & dir){ scanMask = dir.scanMask; hFindFile = INVALID_HANDLE_VALUE; fileinfo = dir.fileinfo;}BOOL PDirectory::Open(int newScanMask){ scanMask = newScanMask;#ifdef UNICODE USES_CONVERSION; hFindFile = FindFirstFile(A2T(operator+("*.*")), &fileinfo);#else hFindFile = FindFirstFile(operator+("*.*"), &fileinfo);#endif if (hFindFile == INVALID_HANDLE_VALUE) return FALSE; return Filtered() ? Next() : TRUE;}BOOL PDirectory::Next(){ if (hFindFile == INVALID_HANDLE_VALUE) return FALSE; do { if (!FindNextFile(hFindFile, &fileinfo)) return FALSE; } while (Filtered()); return TRUE;}PCaselessString PDirectory::GetEntryName() const{ return fileinfo.cFileName;}BOOL PDirectory::IsSubDir() const{ return (fileinfo.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) != 0;}PCaselessString PDirectory::GetVolume() const{#ifdef _WIN32_WCE return PCaselessString("\\");#else char volName[100]; PAssertOS(GetVolumeInformation(NULL, volName, sizeof(volName), NULL, NULL, NULL, NULL, 0)); return PCaselessString(volName);#endif}void PDirectory::Close(){ if (hFindFile != INVALID_HANDLE_VALUE) { FindClose(hFindFile); hFindFile = INVALID_HANDLE_VALUE; }}PString PDirectory::CreateFullPath(const PString & path, BOOL isDirectory){ if (path.IsEmpty() && !isDirectory) return path;#ifdef _WIN32_WCE //doesn't support Current Directory so the path suppose to be full PString fullpath=path; PINDEX len = fullpath.GetLength();#else PString partialpath = path; // Look for special case of "\c:\" at start of string as some generalised // directory processing algorithms have a habit of adding a leading // PDIR_SEPARATOR as it would be for Unix. if (partialpath.NumCompare("\\\\\\") == EqualTo || (partialpath.GetLength() > 3 && partialpath[0] == PDIR_SEPARATOR && partialpath[2] == ':')) partialpath.Delete(0, 1); LPSTR dummy; PString fullpath; PINDEX len = (PINDEX)GetFullPathName(partialpath, _MAX_PATH, fullpath.GetPointer(_MAX_PATH), &dummy);#endif if (isDirectory && len > 0 && fullpath[len-1] != PDIR_SEPARATOR) fullpath += PDIR_SEPARATOR; PINDEX pos = 0; while ((pos = fullpath.Find('/', pos)) != P_MAX_INDEX) fullpath[pos] = PDIR_SEPARATOR; return fullpath;}typedef BOOL (WINAPI *GetDiskFreeSpaceExType)(LPCTSTR lpDirectoryName, PULARGE_INTEGER lpFreeBytesAvailableToCaller, PULARGE_INTEGER lpTotalNumberOfBytes, PULARGE_INTEGER lpTotalNumberOfFreeBytes);BOOL PDirectory::GetVolumeSpace(PInt64 & total, PInt64 & free, DWORD & clusterSize) const{ clusterSize = 512; total = free = ULONG_MAX; PString root; if ((*this)[1] == ':') root = Left(3); else if (theArray[0] == '\\' && theArray[1] == '\\') { PINDEX backslash = Find('\\', 2); if (backslash != P_MAX_INDEX) { backslash = Find('\\', backslash+1); if (backslash != P_MAX_INDEX) root = Left(backslash+1); } } if (root.IsEmpty()) return FALSE;#ifndef _WIN32_WCE BOOL needTotalAndFree = TRUE; static GetDiskFreeSpaceExType GetDiskFreeSpaceEx = (GetDiskFreeSpaceExType)GetProcAddress(LoadLibrary("KERNEL32.DLL"), "GetDiskFreeSpaceExA"); if (GetDiskFreeSpaceEx != NULL) { ULARGE_INTEGER freeBytesAvailableToCaller; ULARGE_INTEGER totalNumberOfBytes; ULARGE_INTEGER totalNumberOfFreeBytes; if (GetDiskFreeSpaceEx(root, &freeBytesAvailableToCaller, &totalNumberOfBytes, &totalNumberOfFreeBytes)) { total = totalNumberOfBytes.QuadPart; free = totalNumberOfFreeBytes.QuadPart; needTotalAndFree = FALSE; } } clusterSize = 0; char fsName[100]; if (GetVolumeInformation(root, NULL, 0, NULL, NULL, NULL, fsName, sizeof(fsName))) { if (stricmp(fsName, "FAT32") == 0) { clusterSize = 4096; // Cannot use GetDiskFreeSpace() results for FAT32 if (!needTotalAndFree) return TRUE; } } DWORD sectorsPerCluster; // address of sectors per cluster DWORD bytesPerSector; // address of bytes per sector DWORD numberOfFreeClusters; // address of number of free clusters DWORD totalNumberOfClusters; // address of total number of clusters if (!GetDiskFreeSpace(root, §orsPerCluster, &bytesPerSector, &numberOfFreeClusters, &totalNumberOfClusters)) { if (root[0] != '\\' || ::GetLastError() != ERROR_NOT_SUPPORTED) return FALSE; PString drive = "A:"; while (WNetAddConnection(root, NULL, drive) != NO_ERROR) { if (GetLastError() != ERROR_ALREADY_ASSIGNED) return FALSE; drive[0]++; } BOOL ok = GetDiskFreeSpace(drive+'\\', §orsPerCluster, &bytesPerSector, &numberOfFreeClusters, &totalNumberOfClusters); WNetCancelConnection(drive, TRUE); if (!ok) return FALSE; } if (needTotalAndFree) { free = numberOfFreeClusters*sectorsPerCluster*bytesPerSector; total = totalNumberOfClusters*sectorsPerCluster*bytesPerSector; } if (clusterSize == 0) clusterSize = bytesPerSector*sectorsPerCluster; return TRUE;#elif _WIN32_WCE < 300 USES_CONVERSION; ULARGE_INTEGER freeBytesAvailableToCaller; ULARGE_INTEGER totalNumberOfBytes; ULARGE_INTEGER totalNumberOfFreeBytes; if (GetDiskFreeSpaceEx(A2T(root), &freeBytesAvailableToCaller, &totalNumberOfBytes, &totalNumberOfFreeBytes)) { total = totalNumberOfBytes.QuadPart; free = totalNumberOfFreeBytes.QuadPart; clusterSize = 512; //X3 return TRUE; } return FALSE;#else return FALSE;#endif}///////////////////////////////////////////////////////////////////////////////// PFilePathstatic PString IllegalFilenameCharacters = "\\/:*?\"<>|" "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\0x10" "\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f";BOOL PFilePath::IsValid(char c){ return IllegalFilenameCharacters.Find(c) == P_MAX_INDEX;}BOOL PFilePath::IsValid(const PString & str){ return str != "." && str != ".." && str.FindOneOf(IllegalFilenameCharacters) == P_MAX_INDEX;}///////////////////////////////////////////////////////////////////////////////// PChannelPString PChannel::GetErrorText(Errors lastError, int osError){ if (osError == 0) { if (lastError == NoError) return PString(); static int const errors[NumNormalisedErrors] = { 0, ENOENT, EEXIST, ENOSPC, EACCES, EBUSY, EINVAL, ENOMEM, EBADF, EAGAIN, EINTR, WSAEMSGSIZE|PWIN32ErrorFlag, EIO, 0x1000000|PWIN32ErrorFlag }; osError = errors[lastError]; }#ifndef _WIN32_WCE if (osError > 0 && osError < _sys_nerr && _sys_errlist[osError][0] != '\0') return _sys_errlist[osError];#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -