/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | foam-extend: Open Source CFD \\ / O peration | Version: 3.2 \\ / A nd | Web: http://www.foam-extend.org \\/ M anipulation | For copyright notice see file Copyright ------------------------------------------------------------------------------- License This file is part of foam-extend. foam-extend 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. foam-extend 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 foam-extend. If not, see . Description MS Windows specific functions \*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*\ Copyright : (C) 2011 Symscape Website : www.symscape.com \*---------------------------------------------------------------------------*/ #include "OSspecific.H" #include "MSwindows.H" #include "foamVersion.H" #include "fileName.H" #include "fileStat.H" #include #include #include #include // Windows system header files #include // _close #include #include // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // defineTypeNameAndDebug(Foam::MSwindows, 0); namespace Foam { // Don't abort under windows, causes abort dialog to // popup. Instead just exit with exitCode. static void sigAbortHandler(int exitCode) { ::exit(exitCode); } static bool installAbortHandler() { // If it didn't succeed there's not much we can do, // so don't check result. ::signal(SIGABRT, &sigAbortHandler); return true; } static bool const abortHandlerInstalled = installAbortHandler(); // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // //- Get last windows api error from GetLastError std::string MSwindows::getLastError() { // Based on an example at: // http://msdn2.microsoft.com/en-us/library/ms680582(VS.85).aspx LPVOID lpMsgBuf; LPVOID lpDisplayBuf; DWORD dw = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); lpDisplayBuf = LocalAlloc(LMEM_ZEROINIT, (lstrlen(static_cast(lpMsgBuf))+40)*sizeof(TCHAR)); sprintf(static_cast(lpDisplayBuf), "Error %d: %s", int(dw), static_cast(lpMsgBuf)); const std::string errorMessage = static_cast(lpDisplayBuf); LocalFree(lpMsgBuf); LocalFree(lpDisplayBuf); return errorMessage; } //-Declared here to avoid polluting MSwindows.H with windows.h namespace MSwindows { //- Get windows user name std::string getUserName(); //- Remove quotes, if any, from std::string void removeQuotes(std::string & arg); //- Convert windows directory slash (back-slash) to unix (forward-slash). //- Windows is fine with unix like directory slashes. //- Foam's file io (see src/OpenFOAM/db/IOstreams/Sstreams/OSwrite.C) //- uses back-slash as escape character and continuation, //- so not an option to have windows file paths with back-slashes void toUnixSlash(string & arg); //- Auto create and then delete array when this goes out of scope template class AutoArray { T* const array_; public: AutoArray(const unsigned long arrayLength); ~AutoArray(); //- Access array T* get(); }; // class AutoArray //- Directory contents iterator class DirectoryIterator { WIN32_FIND_DATA findData_; HANDLE findHandle_; fileName nextName_; bool hasMore_; public: DirectoryIterator(const fileName & directory); ~DirectoryIterator(); //- Initialization succeeded bool isValid() const; //- Has more? bool hasNext() const; //- Next item const fileName & next(); }; // class DirectoryIterator } // namespace MSwindows inline void MSwindows::removeQuotes(std::string & arg) { std::size_t pos; while (std::string::npos != (pos = arg.find('"'))) { arg.erase(pos, 1); } } inline void MSwindows::toUnixSlash(string & arg) { arg.replaceAll("\\", "/"); const std::string UNC("//"); // Preserve UNC i.e., \\machine-name\... if (0 == arg.find(UNC)) { arg.replace(UNC, "\\\\"); } } std::string MSwindows::getUserName() { const DWORD bufferSize = 256; TCHAR buffer[bufferSize]; DWORD actualBufferSize = bufferSize; std::string nameAsString; bool success = ::GetUserName(buffer, &actualBufferSize); if (success) { nameAsString = buffer; } else { if (ERROR_INSUFFICIENT_BUFFER == ::GetLastError() && 32768 > actualBufferSize) { AutoArray actualBuffer(actualBufferSize); ::GetUserName(actualBuffer.get(), &actualBufferSize); nameAsString = actualBuffer.get(); } } return nameAsString; } template inline MSwindows::AutoArray::AutoArray(const unsigned long arrayLength) : array_(new T[arrayLength]) {} template inline MSwindows::AutoArray::~AutoArray() { delete [] array_; } template inline T* MSwindows::AutoArray::get() { return array_; } inline bool MSwindows::DirectoryIterator::isValid() const { const bool valid = (INVALID_HANDLE_VALUE != findHandle_); return valid; } MSwindows::DirectoryIterator::DirectoryIterator(const fileName & directory) { const fileName directoryContents = directory/"*"; findHandle_ = ::FindFirstFile(directoryContents.c_str(), &findData_); hasMore_ = isValid(); } MSwindows::DirectoryIterator::~DirectoryIterator() { if (isValid()) { ::FindClose(findHandle_); } } inline bool MSwindows::DirectoryIterator::hasNext() const { assert(isValid()); return hasMore_; } inline const fileName & MSwindows::DirectoryIterator::next() { assert(hasNext()); nextName_ = findData_.cFileName; hasMore_ = ::FindNextFile(findHandle_, &findData_); return nextName_; } //PID_T pid() int pid() { const DWORD processId = ::GetCurrentProcessId(); return processId; } //PID_T ppid() pid_t ppid() { // No equivalent under windows. if (MSwindows::debug) { Info<< "ppid not supported under MSwindows" << endl; } return 0; } //PID_T pgid() pid_t pgid() { // No equivalent under windows. if (MSwindows::debug) { Info<< "pgid not supported under MSwindows" << endl; } return 0; } std::string toUnixPath(const std::string & path) { string unixPath(path); MSwindows::toUnixSlash(unixPath); MSwindows::removeQuotes(unixPath); return unixPath; } bool env(const word& envName) { const DWORD actualBufferSize = ::GetEnvironmentVariable(envName.c_str(), NULL, 0); const bool envExists = (0 < actualBufferSize); return envExists; } string getEnv(const word& envName) { std::string envAsString; const DWORD actualBufferSize = ::GetEnvironmentVariable(envName.c_str(), NULL, 0); if (0 < actualBufferSize) { MSwindows::AutoArray actualBuffer(actualBufferSize); ::GetEnvironmentVariable(envName.c_str(), actualBuffer.get(), actualBufferSize); envAsString = actualBuffer.get(); toUnixPath(envAsString); } return envAsString; } bool setEnv ( const word& envName, const string& value, const bool overwrite ) { const bool success = ::SetEnvironmentVariable(envName.c_str(), value.c_str()); return success; } word hostName() { const bool full = true; const DWORD bufferSize = MAX_COMPUTERNAME_LENGTH + 1; TCHAR buffer[bufferSize]; DWORD actualBufferSize = bufferSize; const bool success = ::GetComputerName(buffer, &actualBufferSize); const string computerName = success ? buffer : string::null; return computerName; } string domainName() { // Could use ::gethostname and ::gethostbyname like POSIX.C, but would // then need to link against ws_32. Prefer to minimize dependencies. return string::null; } word userName() { std::string name = getEnv("USERNAME"); if (name.empty()) { name = MSwindows::getUserName(); } return name; } bool isAdministrator() { // Not supported but assume worst case for Foam::dynamicCode::checkSecurity return true; } fileName home() { std::string homeDir = getEnv("HOME"); if (homeDir.empty()) { homeDir = getEnv("USERPROFILE"); } return homeDir; } fileName home(const word& userName) { return home(); } fileName cwd() { string currentDirectory; const DWORD actualBufferSize = ::GetCurrentDirectory(0, NULL); if (0 < actualBufferSize) { MSwindows::AutoArray actualBuffer(actualBufferSize); ::GetCurrentDirectory(actualBufferSize, actualBuffer.get()); currentDirectory = actualBuffer.get(); MSwindows::toUnixSlash(currentDirectory); } else { FatalErrorIn("cwd()") << "Couldn't get the current working directory" << exit(FatalError); } return currentDirectory; } bool chDir(const fileName& dir) { const bool success = ::SetCurrentDirectory(dir.c_str()); return success; } fileNameList findEtcFiles ( const fileName& name, bool mandatory, bool findFirst ) { fileNameList results; /* // Search for user files in // * ~/.OpenFOAM/VERSION // * ~/.OpenFOAM // fileName searchDir = home()/".OpenFOAM"; if (isDir(searchDir)) { fileName fullName = searchDir/FOAMversion/name; if (isFile(fullName)) { results.append(fullName); if (findFirst) { return results; } } fullName = searchDir/name; if (isFile(fullName)) { results.append(fullName); if (findFirst) { return results; } } } // Search for group (site) files in // * $WM_PROJECT_SITE/VERSION // * $WM_PROJECT_SITE // searchDir = getEnv("WM_PROJECT_SITE"); if (searchDir.size()) { if (isDir(searchDir)) { fileName fullName = searchDir/FOAMversion/name; if (isFile(fullName)) { results.append(fullName); if (findFirst) { return results; } } fullName = searchDir/name; if (isFile(fullName)) { results.append(fullName); if (findFirst) { return results; } } } } else { // OR search for group (site) files in // * $WM_PROJECT_INST_DIR/site/VERSION // * $WM_PROJECT_INST_DIR/site // searchDir = getEnv("WM_PROJECT_INST_DIR"); if (isDir(searchDir)) { fileName fullName = searchDir/"site"/FOAMversion/name; if (isFile(fullName)) { results.append(fullName); if (findFirst) { return results; } } fullName = searchDir/"site"/name; if (isFile(fullName)) { results.append(fullName); if (findFirst) { return results; } } } } // Search for other (shipped) files in // * $WM_PROJECT_DIR/etc // searchDir = getEnv("WM_PROJECT_DIR"); if (isDir(searchDir)) { fileName fullName = searchDir/"etc"/name; if (isFile(fullName)) { results.append(fullName); if (findFirst) { return results; } } } // Not found if (results.empty()) { // Abort if the file is mandatory, otherwise return null if (mandatory) { std::cerr << "--> FOAM FATAL ERROR in Foam::findEtcFiles() :" " could not find mandatory file\n '" << name.c_str() << "'\n\n" << std::endl; ::exit(1); } } */ // Return list of matching paths or empty list if none found return results; } fileName findEtcFile(const fileName& name, bool mandatory) { // Search most likely location first // Search installation files: // ~~~~~~~~~~~~~~~~~~~~~~~~~~ fileName searchDir = getEnv("WM_PROJECT_DIR"); if (isDir(searchDir)) { // Check for shipped OpenFOAM file in $WM_PROJECT_DIR/etc fileName fullName = searchDir/"etc"/name; if (isFile(fullName)) { return fullName; } } // Search user files: // ~~~~~~~~~~~~~~~~~~ searchDir = home()/".OpenFOAM"; if (isDir(searchDir)) { // Check for user file in ~/.OpenFOAM/VERSION fileName fullName = searchDir/FOAMversion/name; if (isFile(fullName)) { return fullName; } // Check for version-independent user file in ~/.OpenFOAM fullName = searchDir/name; if (isFile(fullName)) { return fullName; } } // Search site files: // ~~~~~~~~~~~~~~~~~~ searchDir = getEnv("WM_PROJECT_INST_DIR"); if (isDir(searchDir)) { // Check for site file in $WM_PROJECT_INST_DIR/site/VERSION fileName fullName = searchDir/"site"/FOAMversion/name; if (isFile(fullName)) { return fullName; } // Check for version-independent site file in $WM_PROJECT_INST_DIR/site fullName = searchDir/"site"/name; if (isFile(fullName)) { return fullName; } } // Not found // abort if the file is mandatory, otherwise return null if (mandatory) { cerr<< "--> FOAM FATAL ERROR in Foam::findEtcFile() :" " could not find mandatory file\n '" << name.c_str() << "'\n\n" << std::endl; ::exit(1); } // Return null-constructed fileName rather than fileName::null // to avoid cyclic dependencies in the construction of globals return fileName(); } bool mkDir(const fileName& pathName, const mode_t mode) { if (pathName.empty()) { return false; } bool success = ::CreateDirectory(pathName.c_str(), NULL); if (success) { chMod(pathName, mode); } else { const DWORD error = ::GetLastError(); switch (error) { case ERROR_ALREADY_EXISTS: { success = true; break; } case ERROR_PATH_NOT_FOUND: { // Part of the path does not exist so try to create it const fileName& parentName = pathName.path(); if (parentName.size() && mkDir(parentName, mode)) { success = mkDir(pathName, mode); } break; } } if (!success) { FatalErrorIn("mkDir(const fileName&, mode_t)") << "Couldn't create directory: " << pathName << " " << MSwindows::getLastError() << exit(FatalError); } } return success; } // Set the file mode bool chMod(const fileName& name, const mode_t m) { const int success = _chmod(name.c_str(), m); return success; } // Return the file mode mode_t mode(const fileName& name) { fileStat fileStatus(name); const mode_t m = fileStatus.isValid() ? fileStatus.status().st_mode : 0; return m; } // Return the file type: FILE or DIRECTORY fileName::Type type(const fileName& name) { fileName::Type fileType = fileName::UNDEFINED; const DWORD attrs = ::GetFileAttributes(name.c_str()); if (attrs != INVALID_FILE_ATTRIBUTES) { fileType = (attrs & FILE_ATTRIBUTE_DIRECTORY) ? fileName::DIRECTORY : fileName::FILE; } return fileType; } static bool isGzFile(const fileName& name) { std::string gzName(name); gzName += ".gz"; const DWORD attrs = ::GetFileAttributes(gzName.c_str()); const bool success = (attrs != INVALID_FILE_ATTRIBUTES); return success; } // Does the name exist in the filing system? bool exists(const fileName& name, const bool checkGzip) { const DWORD attrs = ::GetFileAttributes(name.c_str()); const bool success = (attrs != INVALID_FILE_ATTRIBUTES) || (checkGzip && isGzFile(name)); return success; } // Does the directory exist bool isDir(const fileName& name) { const DWORD attrs = ::GetFileAttributes(name.c_str()); bool success = (attrs != INVALID_FILE_ATTRIBUTES) && (attrs & FILE_ATTRIBUTE_DIRECTORY); return success; } // Does the file exist bool isFile(const fileName& name, const bool checkGzip) { const DWORD attrs = ::GetFileAttributes(name.c_str()); const bool success = ((attrs != INVALID_FILE_ATTRIBUTES) && !(attrs & FILE_ATTRIBUTE_DIRECTORY)) || (checkGzip && isGzFile(name)); return success; } // Return size of file off_t fileSize(const fileName& name) { fileStat fileStatus(name); const off_t fileSize = fileStatus.isValid() ? fileStatus.status().st_size : -1; return fileSize; } // Return time of last file modification time_t lastModified(const fileName& name) { fileStat fileStatus(name); const time_t modifiedTime = fileStatus.isValid() ? fileStatus.status().st_mtime : 0; return modifiedTime; } // Read a directory and return the entries as a string list fileNameList readDir ( const fileName& directory, const fileName::Type type, const bool filtergz ) { // Initial filename list size // also used as increment if initial size found to be insufficient const int maxNnames = 100; if (MSwindows::debug) { Info<< "readDir(const fileName&, const fileType, const bool filtergz)" << " : reading directory " << directory << endl; } // Setup empty string list MAXTVALUES long fileNameList dirEntries(maxNnames); // Temporary variables and counters label nEntries = 0; MSwindows::DirectoryIterator dirIt(directory); if (dirIt.isValid()) { while (dirIt.hasNext()) { const fileName & fName = dirIt.next(); // ignore files begining with ., i.e. '.', '..' and '.*' if (fName.size() > 0 && fName[size_t(0)] != '.') { word fileNameExt = fName.ext(); if ( (type == fileName::DIRECTORY) || ( type == fileName::FILE && fName[fName.size()-1] != '~' && fileNameExt != "bak" && fileNameExt != "BAK" && fileNameExt != "old" && fileNameExt != "save" ) ) { if ((directory/fName).type() == type) { if (nEntries >= dirEntries.size()) { dirEntries.setSize(dirEntries.size() + maxNnames); } if (filtergz && fileNameExt == "gz") { dirEntries[nEntries++] = fName.lessExt(); } else { dirEntries[nEntries++] = fName; } } } } } } else if (MSwindows::debug) { Info<< "readDir(const fileName&, const fileType, " "const bool filtergz) : cannot open directory " << directory << endl; } // Reset the length of the entries list dirEntries.setSize(nEntries); return dirEntries; } // Copy, recursively if necessary, the source top the destination bool cp(const fileName& src, const fileName& dest) { // Make sure source exists. if (!exists(src)) { return false; } fileName destFile(dest); // Check type of source file. if (src.type() == fileName::FILE) { // If dest is a directory, create the destination file name. if (destFile.type() == fileName::DIRECTORY) { destFile = destFile/src.name(); } // Make sure the destination directory exists. if (!isDir(destFile.path()) && !mkDir(destFile.path())) { return false; } // Open and check streams. // Use binary mode in case we read binary. // Causes windows reading to fail if we don't. std::ifstream srcStream(src.c_str(), ios_base::in|ios_base::binary); if (!srcStream) { return false; } // Use binary mode in case we write binary. // Causes windows reading to fail if we don't. std::ofstream destStream(destFile.c_str(), ios_base::out|ios_base::binary); if (!destStream) { return false; } // Copy character data. char ch; while (srcStream.get(ch)) { destStream.put(ch); } // Final check. if (!srcStream.eof() || !destStream) { return false; } } else if (src.type() == fileName::DIRECTORY) { // If dest is a directory, create the destination file name. if (destFile.type() == fileName::DIRECTORY) { destFile = destFile/src.component(src.components().size() -1); } // Make sure the destination directory extists. if (!isDir(destFile) && !mkDir(destFile)) { return false; } // Copy files fileNameList contents = readDir(src, fileName::FILE, false); forAll(contents, i) { if (MSwindows::debug) { Info<< "Copying : " << src/contents[i] << " to " << destFile/contents[i] << endl; } // File to file. cp(src/contents[i], destFile/contents[i]); } // Copy sub directories. fileNameList subdirs = readDir(src, fileName::DIRECTORY); forAll(subdirs, i) { if (MSwindows::debug) { Info<< "Copying : " << src/subdirs[i] << " to " << destFile << endl; } // Dir to Dir. cp(src/subdirs[i], destFile); } } return true; } // Create a softlink. destFile should not exist. Returns true if successful. bool ln(const fileName& src, const fileName& dest) { // Seems that prior to Vista softlinking was poorly supported. // Vista does a better job, but requires adminstrator privileges. // Skip for now. if (MSwindows::debug) { Info<< "MSwindows does not support ln - softlinking" << endl; } return false; } // Rename srcFile destFile bool mv(const fileName& srcFile, const fileName& destFile) { if (MSwindows::debug) { Info<< "Move : " << srcFile << " to " << destFile << endl; } const fileName destName = ((destFile.type() == fileName::DIRECTORY) && (srcFile.type() != fileName::DIRECTORY)) ? destFile/srcFile.name() : destFile; const bool success = (0 == std::rename(srcFile.c_str(), destName.c_str())); return success; } //- Rename to a corresponding backup file // If the backup file already exists, attempt with "01" .. "99" index bool mvBak(const fileName& src, const std::string& ext) { if (MSwindows::debug) { Info<< "mvBak : " << src << " to extension " << ext << endl; } if (exists(src, false)) { const int maxIndex = 99; char index[3]; for (int n = 0; n <= maxIndex; n++) { fileName dstName(src + "." + ext); if (n) { sprintf(index, "%02d", n); dstName += index; } // avoid overwriting existing files, except for the last // possible index where we have no choice if (!exists(dstName, false) || n == maxIndex) { return (0 == std::rename(src.c_str(), dstName.c_str())); } } } // fall-through: nothing to do return false; } // Remove a file returning true if successful otherwise false bool rm(const fileName& file) { if (MSwindows::debug) { Info<< "Removing : " << file << endl; } bool success = (0 == std::remove(file.c_str())); // If deleting plain file name failed try with .gz if (!success) { const std::string fileGz = file + ".gz"; success = (0 == std::remove(fileGz.c_str())); } return success; } // Remove a dirctory and it's contents bool rmDir(const fileName& directory) { if (MSwindows::debug) { Info<< "rmdir(const fileName&) : " << "removing directory " << directory << endl; } bool success = true; // Need to destroy DirectorIterator prior to // removing directory otherwise fails on Windows XP { MSwindows::DirectoryIterator dirIt(directory); while (success && dirIt.hasNext()) { const fileName & fName = dirIt.next(); if (fName != "." && fName != "..") { fileName path = directory/fName; if (path.type() == fileName::DIRECTORY) { success = rmDir(path); if (!success) { WarningIn("rmdir(const fileName&)") << "failed to remove directory " << fName << " while removing directory " << directory << endl; } } else { success = rm(path); if (!success) { WarningIn("rmdir(const fileName&)") << "failed to remove file " << fName << " while removing directory " << directory << endl; } } } } } if (success) { success = ::RemoveDirectory(directory.c_str()); if (!success) { WarningIn("rmdir(const fileName&)") << "failed to remove directory " << directory << endl; } } return success; } //- Sleep for the specified number of seconds unsigned int sleep(const unsigned int s) { const DWORD milliseconds = s * 1000; ::Sleep(milliseconds); return 0; } void fdClose(const int fd) { const int result = ::_close(fd); if (0 != result) { FatalErrorIn ( "Foam::fdClose(const int fd)" ) << "close error on " << fd << endl << abort(FatalError); } } //- Check if machine is up by pinging given port bool ping ( const word& destName, const label destPort, const label timeOut ) { // Appears that socket calls require adminstrator privileges. // Skip for now. if (MSwindows::debug) { Info<< "MSwindows does not support ping" << endl; } return false; } //- Check if machine is up by ping port 22 = ssh and 222 = rsh bool ping(const word& hostname, const label timeOut) { return ping(hostname, 222, timeOut) || ping(hostname, 22, timeOut); } int system(const string& command) { return std::system(command.c_str()); } // Explicitly track loaded libraries, rather than use // EnumerateLoadedModules64 and have to link against // Dbghelp.dll // Details at http://msdn.microsoft.com/en-us/library/ms679316(v=vs.85).aspx typedef std::map OfLoadedLibs; static OfLoadedLibs & getLoadedLibs() { static OfLoadedLibs loadedLibs; return loadedLibs; } //- Open shared library void* dlOpen(const fileName& libName, const bool check) { if (MSwindows::debug) { Info<< "dlOpen(const fileName&)" << " : LoadLibrary of " << libName << endl; } const char* dllExt = ".dll"; // Assume libName is of the form, lib.so string winLibName(libName); winLibName.replace(".so", dllExt); void* handle = ::LoadLibrary(winLibName.c_str()); if (NULL == handle) { // Assumes libName = name winLibName = "lib"; winLibName += libName; winLibName += dllExt; handle = ::LoadLibrary(winLibName.c_str()); } if (NULL != handle) { getLoadedLibs()[handle] = libName; } else if (check) { WarningIn("dlOpen(const fileName&, const bool)") << "dlopen error : " << MSwindows::getLastError() << endl; } if (MSwindows::debug) { Info<< "dlOpen(const fileName&)" << " : LoadLibrary of " << libName << " handle " << handle << endl; } return handle; } //- Close shared library bool dlClose(void* const handle) { if (MSwindows::debug) { Info<< "dlClose(void*)" << " : FreeLibrary of handle " << handle << endl; } const bool success = ::FreeLibrary(static_cast(handle)); if (success) { getLoadedLibs().erase(handle); } return success; } void* dlSym(void* handle, const std::string& symbol) { if (MSwindows::debug) { Info<< "dlSym(void*, const std::string&)" << " : GetProcAddress of " << symbol << endl; } // get address of symbol void* fun = (void*) ::GetProcAddress(static_cast(handle), symbol.c_str()); if (NULL == fun) { WarningIn("dlSym(void*, const std::string&)") << "Cannot lookup symbol " << symbol << " : " << MSwindows::getLastError() << endl; } return fun; } bool dlSymFound(void* handle, const std::string& symbol) { if (handle && !symbol.empty()) { if (MSwindows::debug) { Info<< "dlSymFound(void*, const std::string&)" << " : GetProcAddress of " << symbol << endl; } // get address of symbol void* fun = (void*) ::GetProcAddress(static_cast(handle), symbol.c_str()); return (NULL != fun); } else { return false; } } fileNameList dlLoaded() { fileNameList libs; int counter(0); OfLoadedLibs & loadedLibs = getLoadedLibs(); for ( OfLoadedLibs::const_iterator it = loadedLibs.begin(); it != loadedLibs.end(); ++it ) { libs.newElmt(counter++) = it->second; } if (MSwindows::debug) { Info<< "dlLoaded()" << " : determined loaded libraries :" << libs.size() << endl; } return libs; } void osRandomSeed(const label seed) { std::srand(seed); } label osRandomInteger() { return std::rand(); } scalar osRandomDouble() { return scalar(std::rand())/RAND_MAX; } } // namespace Foam // ************************************************************************* //