StringTableEntry osGetTemporaryDirectory() { TCHAR buf[ 1024 ]; const U32 bufSize = sizeof( buf ) / sizeof( buf[ 0 ] ); DWORD len = GetTempPath( sizeof( buf ) / sizeof( buf[ 0 ] ), buf ); TempAlloc< TCHAR > temp; TCHAR* buffer = buf; if( len > bufSize - 1 ) { temp = TempAlloc< TCHAR >( len + 1 ); buffer = temp; GetTempPath( len + 1, buffer ); } // Remove the trailing slash buffer[len-1] = 0; #ifdef UNICODE TempAlloc< char > dirBuffer( len * 3 + 1 ); char* dir = dirBuffer; convertUTF16toUTF8( buffer, dir, dirBuffer.size ); #else char* dir = buf; #endif forwardslash(dir); return StringTable->insert(dir); }
// // Converts wchar_t type to UTF-8 string // UnicodeConversionResult convertWCHARtoUTF8(const wchar_t *& sourceStart, const wchar_t * sourceEnd, UTF8 *& targetStart, UTF8 * targetEnd, UnicodeConversionFlags flags) { Q_ASSERT(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4); if (sizeof(wchar_t) == 2) return convertUTF16toUTF8((const UTF16 *&)sourceStart, (UTF16 *)sourceEnd, targetStart, targetEnd, flags); else return convertUTF32toUTF8((const UTF32 *&)sourceStart, (UTF32 *)sourceEnd, targetStart, targetEnd, flags); }
S32 PASCAL WinMain( HINSTANCE hInstance, HINSTANCE, LPSTR lpszCmdLine, S32) { #if 0 // Run a unit test. StandardMainLoop::initCore(); UnitTesting::TestRun tr; tr.test("Platform", true); #else Vector<char *> argv( __FILE__, __LINE__ ); char moduleName[256]; #ifdef TORQUE_UNICODE { TCHAR buf[ 256 ]; GetModuleFileNameW( NULL, buf, sizeof( buf ) ); convertUTF16toUTF8( buf, moduleName, sizeof( moduleName ) ); } #else GetModuleFileNameA(NULL, moduleName, sizeof(moduleName)); #endif argv.push_back(moduleName); for (const char* word,*ptr = lpszCmdLine; *ptr; ) { // Eat white space for (; dIsspace(*ptr) && *ptr; ptr++) ; // Pick out the next word for (word = ptr; !dIsspace(*ptr) && *ptr; ptr++) ; // Add the word to the argument list. if (*word) { S32 len = ptr - word; char *arg = (char *) dMalloc(len + 1); dStrncpy(arg, word, len); arg[len] = 0; argv.push_back(arg); } } winState.appInstance = hInstance; S32 retVal = run(argv.size(), (const char **) argv.address()); for(U32 j = 1; j < argv.size(); j++) dFree(argv[j]); return retVal; #endif }
static void getExecutableInfo( StringTableEntry* path, StringTableEntry* exe ) { static StringTableEntry pathEntry = NULL; static StringTableEntry exeEntry = NULL; if( !pathEntry ) { if (!Platform::getWebDeployment()) { WCHAR cen_buf[ 2048 ]; GetModuleFileNameW( NULL, cen_buf, sizeof( cen_buf ) / sizeof( cen_buf[ 0 ] ) ); forwardslash( cen_buf ); WCHAR* delimiter = dStrrchr( cen_buf, '/' ); if( delimiter ) *delimiter = '\0'; char* pathBuf = convertUTF16toUTF8( cen_buf ); char* exeBuf = convertUTF16toUTF8( delimiter + 1 ); pathEntry = StringTable->insert( pathBuf ); exeEntry = StringTable->insert( exeBuf ); SAFE_DELETE_ARRAY( pathBuf ); SAFE_DELETE_ARRAY( exeBuf ); } else { char cdir[4096]; GetCurrentDirectoryA(4096, cdir); pathEntry = StringTable->insert(cdir); exeEntry = StringTable->insert("WebGameCtrl.exe"); } } if( path ) *path = pathEntry; if( exe ) *exe = exeEntry; }
StringTableEntry Platform::getCurrentDirectory() { TempAlloc< TCHAR > buf( 2048 ); GetCurrentDirectory( buf.size, buf ); forwardslash( buf ); #ifdef UNICODE char* utf8 = convertUTF16toUTF8( buf ); StringTableEntry result = StringTable->insert( utf8 ); SAFE_DELETE_ARRAY( utf8 ); return result; #else return StringTable->insert( buf ); #endif }
void GuiTextEditCtrl::setText( const UTF16* txt) { if(txt && txt[0] != 0) { UTF8* txt8 = convertUTF16toUTF8( txt ); Parent::setText( txt8 ); delete[] txt8; mTextBuffer.set( txt ); } else { Parent::setText(""); mTextBuffer.set(""); } mCursorPos = mTextBuffer.length(); }
StringTableEntry RegistryObject::getString(const char* pszSubKey, const char* pszValue) { HKEY hKey; LONG lRes; #ifdef UNICODE DWORD dwSize = 1024 * sizeof(UTF16); UTF16 pszSafeSubKey[1024]; UTF16 pszSafeValue[1024]; UTF16 pszSafeString[1024]; convertUTF8toUTF16(pszSubKey, pszSafeSubKey, sizeof(pszSafeSubKey)); convertUTF8toUTF16(pszValue, pszSafeValue, sizeof(pszSafeValue)); #else DWORD dwSize = 1024 * sizeof(UTF8); UTF8 pszSafeSubKey[1024]; UTF8 pszSafeValue[1024]; UTF8 pszSafeString[1024]; dStrcpy( pszSafeSubKey, pszSubKey ); dStrcpy( pszSafeValue, pszValue ); #endif lRes = ::RegOpenKeyEx(m_hKey, pszSafeSubKey, 0, KEY_READ, &hKey); if( lRes != ERROR_SUCCESS ) return StringTable->EmptyString; lRes = ::RegQueryValueEx(hKey, pszSafeValue, NULL, NULL, (BYTE*)pszSafeString, &dwSize); ::RegCloseKey(hKey); if( lRes != ERROR_SUCCESS ) return StringTable->EmptyString; char pszResultString[1024]; #ifdef UNICODE convertUTF16toUTF8(pszSafeString, pszResultString, sizeof(pszResultString)); #else dStrcpy( pszResultString, pszSafeString ); #endif return StringTable->insert(pszResultString); }
//----------------------------------------------------------------------------- UTF8* convertUTF16toUTF8( const UTF16* unistring) { PROFILE_SCOPE(convertUTF16toUTF8_create); // allocate plenty of memory. U32 nCodeunits, len = dStrlen(unistring) * 3 + 1; FrameTemp<UTF8> buf(len); // perform conversion nCodeunits = convertUTF16toUTF8( unistring, buf, len); // add 1 for the NULL terminator the converter promises it included. nCodeunits++; // allocate the return buffer, copy over, and return it. UTF8 *ret = new UTF8[nCodeunits]; dMemcpy(ret, buf, nCodeunits * sizeof(UTF8)); return ret; }
////-------------------------------------- /// Spawn the default Operating System web browser with a URL /// @param webAddress URL to pass to browser /// @return true if browser successfully spawned bool Platform::openWebBrowser( const char* webAddress ) { static bool sHaveKey = false; static wchar_t sWebKey[512]; char utf8WebKey[512]; { HKEY regKey; DWORD size = sizeof( sWebKey ); if ( RegOpenKeyEx( HKEY_CLASSES_ROOT, dT("\\http\\shell\\open\\command"), 0, KEY_QUERY_VALUE, ®Key ) != ERROR_SUCCESS ) { Con::errorf( ConsoleLogEntry::General, "Platform::openWebBrowser - Failed to open the HKCR\\http registry key!!!"); return( false ); } if ( RegQueryValueEx( regKey, dT(""), NULL, NULL, (U8 *)sWebKey, &size ) != ERROR_SUCCESS ) { Con::errorf( ConsoleLogEntry::General, "Platform::openWebBrowser - Failed to query the open command registry key!!!" ); return( false ); } RegCloseKey( regKey ); sHaveKey = true; convertUTF16toUTF8(sWebKey,utf8WebKey,512); #ifdef UNICODE char *p = dStrstr((const char *)utf8WebKey, "%1"); #else char *p = strstr( (const char *) sWebKey , "%1"); #endif if (p) *p = 0; } STARTUPINFO si; dMemset( &si, 0, sizeof( si ) ); si.cb = sizeof( si ); char buf[1024]; #ifdef UNICODE dSprintf( buf, sizeof( buf ), "%s %s", utf8WebKey, webAddress ); UTF16 b[1024]; convertUTF8toUTF16((UTF8 *)buf, b, sizeof(b)); #else dSprintf( buf, sizeof( buf ), "%s %s", sWebKey, webAddress ); #endif //Con::errorf( ConsoleLogEntry::General, "** Web browser command = %s **", buf ); PROCESS_INFORMATION pi; dMemset( &pi, 0, sizeof( pi ) ); CreateProcess( NULL, #ifdef UNICODE b, #else buf, #endif NULL, NULL, false, CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP, NULL, NULL, &si, &pi ); return( true ); }
S32 torque_winmain( HINSTANCE hInstance, HINSTANCE, LPSTR lpszCmdLine, S32) { Vector<char *> argv( __FILE__, __LINE__ ); char moduleName[256]; #ifdef TORQUE_UNICODE { TCHAR buf[ 256 ]; GetModuleFileNameW( NULL, buf, sizeof( buf ) ); convertUTF16toUTF8( buf, moduleName, sizeof( moduleName ) ); } #else GetModuleFileNameA(NULL, moduleName, sizeof(moduleName)); #endif argv.push_back(moduleName); for (const char* word,*ptr = lpszCmdLine; *ptr; ) { // Eat white space for (; dIsspace(*ptr) && *ptr; ptr++) ; // Test for quotes bool withinQuotes = dIsquote(*ptr); if (!withinQuotes) { // Pick out the next word for (word = ptr; !dIsspace(*ptr) && *ptr; ptr++) ; } else { // Advance past the first quote. We don't want to include it. ptr++; // Pick out the next quote for (word = ptr; !dIsquote(*ptr) && *ptr; ptr++) ; } // Add the word to the argument list. if (*word) { S32 len = ptr - word; char *arg = (char *) dMalloc(len + 1); dStrncpy(arg, word, len); arg[len] = 0; argv.push_back(arg); } // If we had a quote, skip past it for the next arg if (withinQuotes && *ptr) { ptr++; } } winState.appInstance = hInstance; S32 retVal = TorqueMain(argv.size(), (const char **) argv.address()); for(U32 j = 1; j < argv.size(); j++) dFree(argv[j]); return retVal; }
void PlatformFont::enumeratePlatformFonts( Vector< StringTableEntry >& fonts, UTF16* fontFamily ) { if( fontFamily ) { // Determine the font ID from the family name. ATSUFontID fontID; if( ATSUFindFontFromName( fontFamily, dStrlen( fontFamily ) * 2, kFontFamilyName, kFontMicrosoftPlatform, kFontNoScriptCode, kFontNoLanguageCode, &fontID ) != kATSUInvalidFontErr ) { // Get the number of fonts in the family. ItemCount numFonts; ATSUCountFontNames( fontID, &numFonts ); // Read out font names. U32 bufferSize = 512; char* buffer = ( char* ) dMalloc( bufferSize ); for( U32 i = 0; i < numFonts; ++ i ) { for( U32 n = 0; n < 2; ++ n ) { ByteCount actualNameLength; FontNameCode fontNameCode; FontPlatformCode fontPlatformCode; FontScriptCode fontScriptCode; FontLanguageCode fontLanguageCode; if( ATSUGetIndFontName( fontID, i, bufferSize - 2, buffer, &actualNameLength, &fontNameCode, &fontPlatformCode, &fontScriptCode, &fontLanguageCode ) == noErr ) { *( ( UTF16* ) &buffer[ actualNameLength ] ) = '\0'; char* utf8 = convertUTF16toUTF8( ( UTF16* ) buffer ); fonts.push_back( StringTable->insert( utf8 ) ); delete [] utf8; break; } // Allocate larger buffer. bufferSize = actualNameLength + 2; buffer = ( char* ) dRealloc( buffer, bufferSize ); } } dFree( buffer ); } } else { // Get the number of installed fonts. ItemCount numFonts; ATSUFontCount( &numFonts ); // Get all the font IDs. ATSUFontID* fontIDs = new ATSUFontID[ numFonts ]; if( ATSUGetFontIDs( fontIDs, numFonts, &numFonts ) == noErr ) { U32 bufferSize = 512; char* buffer = ( char* ) dMalloc( bufferSize ); // Read all family names. for( U32 i = 0; i < numFonts; ++ i ) { for( U32 n = 0; n < 2; ++ n ) { ByteCount actualNameLength; ItemCount fontIndex; OSStatus result = ATSUFindFontName( fontIDs[ i ], kFontFamilyName, kFontMicrosoftPlatform, kFontNoScriptCode, kFontNoLanguageCode, bufferSize - 2, buffer, &actualNameLength, &fontIndex ); if( result == kATSUNoFontNameErr ) break; else if( result == noErr ) { *( ( UTF16* ) &buffer[ actualNameLength ] ) = '\0'; char* utf8 = convertUTF16toUTF8( ( UTF16* ) buffer ); StringTableEntry name = StringTable->insert( utf8 ); delete [] utf8; // Avoid duplicates. bool duplicate = false; for( U32 i = 0, num = fonts.size(); i < num; ++ i ) if( fonts[ i ] == name ) { duplicate = true; break; } if( !duplicate ) fonts.push_back( name ); break; } // Allocate larger buffer. bufferSize = actualNameLength + 2; buffer = ( char* ) dRealloc( buffer, bufferSize ); } } dFree( buffer ); } delete [] fontIDs; } }
static bool recurseDumpPath(const char *path, const char *pattern, Vector<Platform::FileInfo> &fileVector, S32 recurseDepth ) { WIN32_FIND_DATA findData; TempAlloc< char > fullPath( dStrlen( path ) * 3 + MAX_PATH * 3 + 1 ); Platform::makeFullPathName( path, fullPath, fullPath.size ); U32 lenFullPath = dStrlen( fullPath ); TempAlloc< char > buf( lenFullPath + MAX_PATH * 3 + 2 ); dSprintf( buf, buf.size, "%s/%s", fullPath.ptr, pattern ); #ifdef UNICODE TempAlloc< WCHAR > searchBuf( buf.size ); convertUTF8toUTF16( buf, searchBuf, searchBuf.size ); WCHAR* search = searchBuf; #else char *search = buf; #endif backslash( search ); HANDLE handle = FindFirstFile(search, &findData); if (handle == INVALID_HANDLE_VALUE) return false; do { #ifdef UNICODE convertUTF16toUTF8( findData.cFileName, buf, buf.size ); char* fnbuf = buf; #else char *fnbuf = findData.cFileName; #endif if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { // make sure it is a directory if (findData.dwFileAttributes & (FILE_ATTRIBUTE_OFFLINE|FILE_ATTRIBUTE_SYSTEM) ) continue; // skip . and .. directories if (dStrcmp( findData.cFileName, TEXT( "." ) ) == 0 || dStrcmp( findData.cFileName, TEXT( ".." ) ) == 0) continue; // Skip excluded directores if(Platform::isExcludedDirectory(fnbuf)) continue; dSprintf( fullPath, fullPath.size, "%s/%s", path, fnbuf); char* child = fullPath; if( recurseDepth > 0 ) recurseDumpPath(child, pattern, fileVector, recurseDepth - 1); else if (recurseDepth == -1) recurseDumpPath(child, pattern, fileVector, -1); } else { // make sure it is the kind of file we're looking for if (findData.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY| FILE_ATTRIBUTE_OFFLINE| FILE_ATTRIBUTE_SYSTEM| FILE_ATTRIBUTE_TEMPORARY) ) continue; // add it to the list fileVector.increment(); Platform::FileInfo& rInfo = fileVector.last(); forwardslash( fnbuf ); rInfo.pFullPath = StringTable->insert(path); rInfo.pFileName = StringTable->insert(fnbuf); rInfo.fileSize = findData.nFileSizeLow; } }while(FindNextFile(handle, &findData)); FindClose(handle); return true; }
static bool recurseDumpDirectories(const char *basePath, const char *subPath, Vector<StringTableEntry> &directoryVector, S32 currentDepth, S32 recurseDepth, bool noBasePath) { TempAlloc< char > search( 1024 ); //----------------------------------------------------------------------------- // Compose our search string - Format : ([path]/[subpath]/*) //----------------------------------------------------------------------------- char trail = basePath[ dStrlen(basePath) - 1 ]; char subTrail = subPath ? subPath[ dStrlen(subPath) - 1 ] : '\0'; if( trail == '/' ) { // we have a sub path and it's not an empty string if( subPath && ( dStrncmp( subPath, "", 1 ) != 0 ) ) { if( subTrail == '/' ) dSprintf(search, search.size, "%s%s*", basePath,subPath ); else dSprintf(search, search.size, "%s%s/*", basePath,subPath ); } else dSprintf( search, search.size, "%s*", basePath ); } else { if( subPath && ( dStrncmp( subPath, "", 1 ) != 0 ) ) if( subTrail == '/' ) dSprintf(search, search.size, "%s%s*", basePath,subPath ); else dSprintf(search, search.size, "%s%s/*", basePath,subPath ); else dSprintf(search, search.size, "%s/*", basePath ); } #ifdef UNICODE TempAlloc< WCHAR > searchStr( dStrlen( search ) + 1 ); convertUTF8toUTF16( search, searchStr, searchStr.size ); #else char* searchStr = search; #endif backslash( searchStr ); //----------------------------------------------------------------------------- // See if we get any hits //----------------------------------------------------------------------------- WIN32_FIND_DATA findData; HANDLE handle = FindFirstFile(searchStr, &findData); if (handle == INVALID_HANDLE_VALUE) return false; //----------------------------------------------------------------------------- // add path to our return list ( provided it is valid ) //----------------------------------------------------------------------------- if( !Platform::isExcludedDirectory( subPath ) ) { if( noBasePath ) { // We have a path and it's not an empty string or an excluded directory if( ( subPath && ( dStrncmp( subPath, "", 1 ) != 0 ) ) ) directoryVector.push_back( StringTable->insert( subPath ) ); } else { if( ( subPath && ( dStrncmp( subPath, "", 1 ) != 0 ) ) ) { char szPath [ 1024 ]; dMemset( szPath, 0, 1024 ); if( trail != '/' ) dSprintf( szPath, 1024, "%s%s", basePath, subPath ); else dSprintf( szPath, 1024, "%s%s", basePath, &subPath[1] ); directoryVector.push_back( StringTable->insert( szPath ) ); } else directoryVector.push_back( StringTable->insert( basePath ) ); } } //----------------------------------------------------------------------------- // Iterate through and grab valid directories //----------------------------------------------------------------------------- #ifdef UNICODE TempAlloc< char > fileName( 1024 ); #endif do { if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { // skip . and .. directories if (dStrcmp(findData.cFileName, TEXT( "." )) == 0 || dStrcmp(findData.cFileName, TEXT( ".." )) == 0) continue; #ifdef UNICODE convertUTF16toUTF8( findData.cFileName, fileName, fileName.size ); #else char* fileName = findData.cFileName; #endif // skip excluded directories if( Platform::isExcludedDirectory( fileName ) ) continue; if( ( subPath && ( dStrncmp( subPath, "", 1 ) != 0 ) )) { if( subTrail == '/' ) dSprintf(search, search.size, "%s%s", subPath, fileName); else dSprintf(search, search.size, "%s/%s", subPath, fileName); char* child = search; if( currentDepth < recurseDepth || recurseDepth == -1 ) recurseDumpDirectories(basePath, child, directoryVector, currentDepth+1, recurseDepth, noBasePath ); } else { char* child; if( trail == '/' ) child = fileName; else { dSprintf(search, search.size, "/%s", fileName); child = search; } if( currentDepth < recurseDepth || recurseDepth == -1 ) recurseDumpDirectories(basePath, child, directoryVector, currentDepth+1, recurseDepth, noBasePath ); } } } while(FindNextFile(handle, &findData)); FindClose(handle); return true; }
bool Platform::hasSubDirectory(const char *pPath) { if( !pPath ) return false; char searchBuf[1024]; // Compose our search string - Format : ([path]/[subpath]/*) char trail = pPath[ dStrlen(pPath) - 1 ]; if( trail == '/' ) dStrcpy( searchBuf, pPath ); else dSprintf(searchBuf, 1024, "%s/*", pPath ); #ifdef UNICODE WCHAR buf[ 1024 ]; convertUTF8toUTF16( searchBuf, buf, sizeof( buf ) / sizeof( buf[ 0 ] ) ); WCHAR* search = buf; #else char* search = searchBuf; #endif backslash( search ); // See if we get any hits WIN32_FIND_DATA findData; HANDLE handle = FindFirstFile(search, &findData); if (handle == INVALID_HANDLE_VALUE) return false; bool result = false; do { if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { // skip . and .. directories if (dStrcmp(findData.cFileName, TEXT( "." ) ) == 0 || dStrcmp(findData.cFileName, TEXT( ".." ) ) == 0) continue; #ifdef UNICODE char fileName[ 1024 ]; convertUTF16toUTF8( findData.cFileName, fileName, sizeof( fileName ) / sizeof( fileName[ 0 ] ) ); #else char* fileName = findData.cFileName; #endif if( Platform::isExcludedDirectory( fileName ) ) continue; result = true; break; } } while(FindNextFile(handle, &findData)); FindClose(handle); Platform::clearExcludedDirectories(); return result; }
void Platform::getVolumeInformationList( Vector<VolumeInformation>& out_rVolumeInfoVector, bool bOnlyFixedDrives ) { Vector<const char*> drives; getVolumeNamesList( drives, bOnlyFixedDrives ); if( ! drives.empty() ) { Vector<StringTableEntry>::iterator i; for( i = drives.begin(); i != drives.end(); i++ ) { VolumeInformation info; TCHAR lpszVolumeName[ 256 ]; TCHAR lpszFileSystem[ 256 ]; DWORD dwSerial = 0; DWORD dwMaxComponentLength = 0; DWORD dwFileSystemFlags = 0; dMemset( lpszVolumeName, 0, sizeof( lpszVolumeName ) ); dMemset( lpszFileSystem, 0, sizeof( lpszFileSystem ) ); dMemset( &info, 0, sizeof( VolumeInformation ) ); // More volume information UINT uDriveType = GetDriveTypeA( (*i) ); if( uDriveType == DRIVE_UNKNOWN ) info.Type = DRIVETYPE_UNKNOWN; else if( uDriveType == DRIVE_REMOVABLE ) info.Type = DRIVETYPE_REMOVABLE; else if( uDriveType == DRIVE_FIXED ) info.Type = DRIVETYPE_FIXED; else if( uDriveType == DRIVE_CDROM ) info.Type = DRIVETYPE_CDROM; else if( uDriveType == DRIVE_RAMDISK ) info.Type = DRIVETYPE_RAMDISK; else if( uDriveType == DRIVE_REMOTE ) info.Type = DRIVETYPE_REMOTE; info.RootPath = StringTable->insert( (*i) ); // We don't retrieve drive volume info for removable drives, because it's loud :( if( info.Type != DRIVETYPE_REMOVABLE ) { #ifdef UNICODE WCHAR ibuf[ 3 ]; ibuf[ 0 ] = ( *i )[ 0 ]; ibuf[ 1 ] = ':'; ibuf[ 2 ] = '\0'; #else char* ibuf = *i; #endif // Standard volume information GetVolumeInformation( ibuf, lpszVolumeName, sizeof( lpszVolumeName ) / sizeof( lpszVolumeName[ 0 ] ), &dwSerial, &dwMaxComponentLength, &dwFileSystemFlags, lpszFileSystem, sizeof( lpszFileSystem ) / sizeof( lpszFileSystem[ 0 ] ) ); #ifdef UNICODE char buf[ sizeof( lpszFileSystem ) / sizeof( lpszFileSystem[ 0 ] ) * 3 + 1 ]; convertUTF16toUTF8( lpszFileSystem, buf, sizeof( buf ) / sizeof( buf[ 0 ] ) ); info.FileSystem = StringTable->insert( buf ); convertUTF16toUTF8( lpszVolumeName, buf, sizeof( buf ) / sizeof( buf[ 0 ] ) ); info.Name = StringTable->insert( buf ); #else info.FileSystem = StringTable->insert( lpszFileSystem ); info.Name = StringTable->insert( lpszVolumeName ); #endif info.SerialNumber = dwSerial; // Won't compile on something prior to XP. info.ReadOnly = dwFileSystemFlags & FILE_READ_ONLY_VOLUME; } out_rVolumeInfoVector.push_back( info ); // I opted not to get free disk space because of the overhead of the calculations required for it } } }