From 32380e3c407c42b2de6013279fecd9179c0c3753 Mon Sep 17 00:00:00 2001 From: tomoto335 Date: Mon, 7 Jan 2013 00:34:13 -0800 Subject: [PATCH 1/8] Fix the directory separator issue of xnOSGetDirName() Problem: - Windows version of xnOSGetDirName() returns the directory name followed by a directory separator, which was (seemingly) different from Linux version's behavior. This difference could be a problem when you tried to write a portable code. Solution: - Windows version of xnOSGetDirName() now returns the directory name without the directory separator, which should be the same as Linux version. - Another helper functions, xnOSStripDirSep() and xnOSIsDirSep(), are introduced to implement this in a clean and portable way. Description of changes: - XnWin32Files.cpp: Added a code to strip the directory separator in xnOSGetDirName(). - XnOS.h: Utility functions to handle the directory separators are added (xnOSStripDirSep, xnOSIsDirSep) - XnLibWin32.h, XnOSLinux-x86.h: String constant XN_FILE_DIR_SEPS is added to support both "\" and "/" in Windows. This is helpful for the application programmers to write a portable code by consistently using "/" in any platforms. Note for Linux: Tested on Windows only. --- .../XnLib/Include/Linux-x86/XnOSLinux-x86.h | 1 + .../PSCommon/XnLib/Include/Win32/XnLibWin32.h | 1 + ThirdParty/PSCommon/XnLib/Include/XnOS.h | 9 +++++++++ .../PSCommon/XnLib/Source/Win32/XnWin32Files.cpp | 1 + ThirdParty/PSCommon/XnLib/Source/XnFiles.cpp | 14 ++++++++++++++ 5 files changed, 26 insertions(+) diff --git a/ThirdParty/PSCommon/XnLib/Include/Linux-x86/XnOSLinux-x86.h b/ThirdParty/PSCommon/XnLib/Include/Linux-x86/XnOSLinux-x86.h index f8d1ecd0..7a8c2459 100644 --- a/ThirdParty/PSCommon/XnLib/Include/Linux-x86/XnOSLinux-x86.h +++ b/ThirdParty/PSCommon/XnLib/Include/Linux-x86/XnOSLinux-x86.h @@ -48,6 +48,7 @@ typedef XnInt XN_FILE_HANDLE; /** The file directory separator. */ #define XN_FILE_DIR_SEP "/" +#define XN_FILE_DIR_SEPS "/" /** The file extension separator. */ #define XN_FILE_EXT_SEP "." diff --git a/ThirdParty/PSCommon/XnLib/Include/Win32/XnLibWin32.h b/ThirdParty/PSCommon/XnLib/Include/Win32/XnLibWin32.h index 6c17a941..452163ed 100644 --- a/ThirdParty/PSCommon/XnLib/Include/Win32/XnLibWin32.h +++ b/ThirdParty/PSCommon/XnLib/Include/Win32/XnLibWin32.h @@ -37,6 +37,7 @@ typedef HANDLE XN_FILE_HANDLE; /** The file directory separator. */ #define XN_FILE_DIR_SEP "\\" +#define XN_FILE_DIR_SEPS "\\/" // Win32 accepts '/' also /** The file extension separator. */ #define XN_FILE_EXT_SEP "." diff --git a/ThirdParty/PSCommon/XnLib/Include/XnOS.h b/ThirdParty/PSCommon/XnLib/Include/XnOS.h index a6e7e9f5..2b8fd539 100644 --- a/ThirdParty/PSCommon/XnLib/Include/XnOS.h +++ b/ThirdParty/PSCommon/XnLib/Include/XnOS.h @@ -463,6 +463,15 @@ XN_C_API XnStatus XN_C_DECL xnOSGetFileName(const XnChar* cpFilePath, XnChar* cp XN_C_API XnStatus XN_C_DECL xnOSGetFullPathName(const XnChar* strFilePath, XnChar* strFullPath, XnUInt32 nBufferSize); XN_C_API XnStatus XN_C_DECL xnOSGetCurrentDir(XnChar* cpDirName, const XnUInt32 nBufferSize); XN_C_API XnStatus XN_C_DECL xnOSSetCurrentDir(const XnChar* cpDirName); +/** + * Strips the directory separator at the end of the specified path by directly modifying the given string. + * Always returns XN_STATUS_OK. + */ +XN_C_API XnStatus XN_C_DECL xnOSStripDirSep(XnChar* strDirName); +/** + * Checks if the specified character works as a directory separator. + */ +XN_C_API XnBool XN_C_DECL xnOSIsDirSep(XnChar c); XN_C_API XnStatus XN_C_DECL xnOSDeleteFile(const XnChar* cpFileName); XN_C_API XnStatus XN_C_DECL xnOSDeleteEmptyDirectory(const XnChar* strDirName); XN_C_API XnStatus XN_C_DECL xnOSDeleteDirectoryTree(const XnChar* strDirName); diff --git a/ThirdParty/PSCommon/XnLib/Source/Win32/XnWin32Files.cpp b/ThirdParty/PSCommon/XnLib/Source/Win32/XnWin32Files.cpp index 2cda2be0..96ede886 100644 --- a/ThirdParty/PSCommon/XnLib/Source/Win32/XnWin32Files.cpp +++ b/ThirdParty/PSCommon/XnLib/Source/Win32/XnWin32Files.cpp @@ -704,6 +704,7 @@ XN_C_API XnStatus xnOSGetDirName(const XnChar* cpFilePath, XnChar* cpDirName, co } pFileName[0] = '\0'; + xnOSStripDirSep(strFullPath); strcpy(cpDirName, strFullPath); return XN_STATUS_OK; diff --git a/ThirdParty/PSCommon/XnLib/Source/XnFiles.cpp b/ThirdParty/PSCommon/XnLib/Source/XnFiles.cpp index 684f61dc..d6d5b983 100644 --- a/ThirdParty/PSCommon/XnLib/Source/XnFiles.cpp +++ b/ThirdParty/PSCommon/XnLib/Source/XnFiles.cpp @@ -106,3 +106,17 @@ XN_C_API XnStatus xnOSAppendFile(const XnChar* cpFileName, const void* pBuffer, // All is good... return (XN_STATUS_OK); } + +XN_C_API XnStatus xnOSStripDirSep(XnChar* strDirName) +{ + XnUInt32 len = xnOSStrLen(strDirName); + if (len > 0 && xnOSIsDirSep(strDirName[len-1])) { + strDirName[len-1] = '\0'; + } + return XN_STATUS_OK; +} + +XN_C_API XnBool xnOSIsDirSep(XnChar c) +{ + return strchr(XN_FILE_DIR_SEPS, c) != NULL; +} From 512913caa60a86b89041a96c2f07152c99c2af81 Mon Sep 17 00:00:00 2001 From: tomoto335 Date: Mon, 7 Jan 2013 00:47:16 -0800 Subject: [PATCH 2/8] Resolve driver and OpenNI.ini path based on OpenNI2.dll directory Fix 1: Drivers' path is now resolved based on OpenNI2.dll's directory. Problem: - The drivers' path ("OpenNI2/Drivers" by default) is resolved based on the current directory, which could be a problem because it would restrict the application to be runnable only in a specific directory. See the OpenNI community at http://community.openni.org/openni/topics/search_path_for_redist_files where I originally pointed out this issue. Solution: - Now the drivers' path is resolved based on OpenNI2.dll's directory. By default, /OpenNI2/Drivers is used. If the custom path is specified by OpenNI.ini (by Repository property in Drivers section), it will be resolved based on OpenNI2.dll's directory if it is relative, or used as it is when it is absolute. - To specify the custom path, the application can use "/" as the separater even in Windows so that the application can use the same OpenNI.ini regardless of the platform. - The path resolution by the environment variable (OPENNI2_DRIVERS_PATH) is kept untouched to preserve the current behavior, but I would suggest removing it because it could be no longer useful but might break the consistency between the DLL and the drivers. Description of changes: - OniContext.cpp: The drivers' path is resolved based on OpenNI2.dll's directory instead of using the string constant. - XnOS.h, XnWin32SharedLibrary.cpp, XnLinuxSharedLibs.cpp: Function to get the DLL's path is added (xnOSGetModulePathForProcAddress). See "Note for Linux" also. - XnOS.h, XnFiles.cpp, XnWin32Files.cpp, XnLinuxFiles.cpp: Utility functions to handle file paths are added (xnOSAppendFilePath, xnOSIsAbsoluteFilePath). See "Note for Linux" also. - Config/OpenNI.ini: Comment is added to explain how to specify the drivers' path in detail. Note for Linux: - This fix has not been compiled or tested on Linux, but intended not to break anything existing at least. - xnOSGetModulePathForProcAddress() in XnLinuxSharedLibs.cpp needs to be implemented. It should be easily done by using dladdr(). For now, it has the dummy implementation that should not break existing behavior. - xnOSIsAbsoluteFilePath() in XnLinuxFiles.cpp is implemented but not tested. Fix 2: OpenNI.ini is now read from OpenNI2.dll's directory. Problem: - OpenNI.ini is read from the current directory, which could be a problem by the same reason as Fix 1. Solution: - Now OpenNI.ini is read from the same directory as OpenNI2.dll. - If there is OpenNI.ini in the current directory, it overrides OpenNI.ini in OpenNI2.dll's directory. This feature is kept to preserve the current behavior, but I would suggest removing it because the application's behavior should be independent from the current directory unless the application itself was so designed. Description of changes: - OniContext.cpp: OpenNI.ini's path is resolved based on OpenNI2.dll's directory instead of using the string constant. Fix 3: Improvement of the log configuration timing. Problem: - Some logs are not outputted because the log configuration in OpenNI.ini is read too late. Solution: - Complete log configuration before any log outputs as long as possible. Description of changes: - OniContext.cpp: The order of log configuration and log output was slightly exchanged. --- Config/OpenNI.ini | 6 + Source/Core/OniContext.cpp | 114 ++++++++++++++---- ThirdParty/PSCommon/XnLib/Include/XnOS.h | 22 ++++ .../XnLib/Source/Linux/XnLinuxFiles.cpp | 5 + .../XnLib/Source/Linux/XnLinuxSharedLibs.cpp | 9 ++ .../XnLib/Source/Win32/XnWin32Files.cpp | 6 + .../Source/Win32/XnWin32SharedLibrary.cpp | 16 +++ ThirdParty/PSCommon/XnLib/Source/XnFiles.cpp | 15 +++ 8 files changed, 169 insertions(+), 24 deletions(-) diff --git a/Config/OpenNI.ini b/Config/OpenNI.ini index a443fcb8..3375b84d 100644 --- a/Config/OpenNI.ini +++ b/Config/OpenNI.ini @@ -6,3 +6,9 @@ LogToFile=0 [Device] ;Override="" + +[Drivers] +; Location of the drivers specified by a relative path based on OpenNI's shared library or an absolute path. +; Path separator "/" can be used to be portable for any platforms. +; Default - OpenNI2/Drivers +;Repository=OpenNI2/Drivers diff --git a/Source/Core/OniContext.cpp b/Source/Core/OniContext.cpp index dab82203..e3930666 100644 --- a/Source/Core/OniContext.cpp +++ b/Source/Core/OniContext.cpp @@ -22,13 +22,13 @@ #include "OniStreamFrameHolder.h" #include -static const char* ONI_CONFIGURATION_FILE = XN_FILE_LOCAL_DIR "OpenNI.ini"; +static const char* ONI_CONFIGURATION_FILE = "OpenNI.ini"; #if (XN_PLATFORM == XN_PLATFORM_WIN32) && (_M_X64) static const char* ONI_ENV_VAR_DRIVERS_REPOSITORY = "OPENNI2_DRIVERS_PATH64"; #else static const char* ONI_ENV_VAR_DRIVERS_REPOSITORY = "OPENNI2_DRIVERS_PATH"; #endif -static const char* ONI_DEFAULT_DRIVERS_REPOSITORY = XN_FILE_LOCAL_DIR "OpenNI2" XN_FILE_DIR_SEP "Drivers"; +static const char* ONI_DEFAULT_DRIVERS_REPOSITORY = "OpenNI2" XN_FILE_DIR_SEP "Drivers"; ONI_NAMESPACE_IMPLEMENTATION_BEGIN @@ -44,6 +44,9 @@ Context::~Context() s_valid = FALSE; } +// Dummy function used only for taking its address for the sake of xnOSGetModulePathForProcAddress. +static void dummyFunctionToTakeAddress() {} + OniStatus Context::initialize() { XnBool repositoryOverridden = FALSE; @@ -58,6 +61,21 @@ OniStatus Context::initialize() XnStatus rc; + XnChar modulePath[XN_FILE_MAX_PATH]; + rc = xnOSGetModulePathForProcAddress(&dummyFunctionToTakeAddress, modulePath); + if (rc != XN_STATUS_OK) { + m_errorLogger.Append("Couldn't get the OpenNI shared library module's path: %s", xnGetStatusString(rc)); + return OniStatusFromXnStatus(rc); + } + + XnChar baseDir[XN_FILE_MAX_PATH]; + rc = xnOSGetDirName(modulePath, baseDir, XN_FILE_MAX_PATH); + if (rc != XN_STATUS_OK) { + // Very unlikely to happen, but just in case. + m_errorLogger.Append("Couldn't get the OpenNI shared library module's directory: %s", xnGetStatusString(rc)); + return OniStatusFromXnStatus(rc); + } + rc = m_newFrameAvailableEvent.Create(FALSE); if (rc != XN_STATUS_OK) { @@ -69,68 +87,116 @@ OniStatus Context::initialize() // Read configuration file + XnChar oniConfigurationFile[XN_FILE_MAX_PATH]; XnBool configurationFileExists = FALSE; - rc = xnOSDoesFileExist(ONI_CONFIGURATION_FILE, &configurationFileExists); + + // Need review: + // I (Tomoto) think it is not necessary to search the current directory for OpenNI.ini + // because it could be counter-intuitive rather than beneficial that the current directory + // might affect on the OpenNI behavior. + // I left it only for the backward compatibility, but probably we'd better remove it. + + // Check the current directory first. + xnOSStrCopy(oniConfigurationFile, XN_FILE_LOCAL_DIR, XN_FILE_MAX_PATH); + xnOSAppendFilePath(oniConfigurationFile, ONI_CONFIGURATION_FILE, XN_FILE_MAX_PATH); + xnOSDoesFileExist(oniConfigurationFile, &configurationFileExists); + + // Check the module directory next. + if (!configurationFileExists) { + xnOSStrCopy(oniConfigurationFile, baseDir, XN_FILE_MAX_PATH); + rc = xnOSAppendFilePath(oniConfigurationFile, ONI_CONFIGURATION_FILE, XN_FILE_MAX_PATH); + if (rc == XN_STATUS_OK) { + xnOSDoesFileExist(oniConfigurationFile, &configurationFileExists); + } + } + if (configurationFileExists) { - rc = xnOSReadStringFromINI(ONI_CONFIGURATION_FILE, "Device", "Override", m_overrideDevice, XN_FILE_MAX_PATH); - if (rc != XN_STATUS_OK) - { - xnLogVerbose(XN_LOG_MASK_ALL, "No override device in configuration file"); - } + // First, we should process the log related configuration as early as possible. XnInt32 nValue; - rc = xnOSReadIntFromINI(ONI_CONFIGURATION_FILE, "Log", "Verbosity", &nValue); + rc = xnOSReadIntFromINI(oniConfigurationFile, "Log", "Verbosity", &nValue); if (rc == XN_STATUS_OK) { xnLogSetMaskMinSeverity(XN_LOG_MASK_ALL, (XnLogSeverity)nValue); } - rc = xnOSReadIntFromINI(ONI_CONFIGURATION_FILE, "Log", "LogToConsole", &nValue); + rc = xnOSReadIntFromINI(oniConfigurationFile, "Log", "LogToConsole", &nValue); if (rc == XN_STATUS_OK) { xnLogSetConsoleOutput(nValue == 1); } - rc = xnOSReadIntFromINI(ONI_CONFIGURATION_FILE, "Log", "LogToFile", &nValue); + rc = xnOSReadIntFromINI(oniConfigurationFile, "Log", "LogToFile", &nValue); if (rc == XN_STATUS_OK) { xnLogSetFileOutput(nValue == 1); } - rc = xnOSReadStringFromINI(ONI_CONFIGURATION_FILE, "Drivers", "Repository", repositoryFromINI, XN_FILE_MAX_PATH); + + // Then, process the other device configurations. + + rc = xnOSReadStringFromINI(oniConfigurationFile, "Device", "Override", m_overrideDevice, XN_FILE_MAX_PATH); + if (rc != XN_STATUS_OK) + { + xnLogVerbose(XN_LOG_MASK_ALL, "No override device in configuration file"); + } + + rc = xnOSReadStringFromINI(oniConfigurationFile, "Drivers", "Repository", repositoryFromINI, XN_FILE_MAX_PATH); if (rc == XN_STATUS_OK) { repositoryOverridden = TRUE; } + + xnLogVerbose(XN_LOG_MASK_ALL, "Configuration has been read from '%s'", oniConfigurationFile); } else { - xnLogVerbose(XN_LOG_MASK_ALL, "Couldn't find configuration file '%s'", ONI_CONFIGURATION_FILE); + xnLogVerbose(XN_LOG_MASK_ALL, "Couldn't find configuration file '%s'", oniConfigurationFile); } xnLogVerbose(XN_LOG_MASK_ALL, "OpenNI %s", ONI_VERSION_STRING); - // Use path specified in ini file + XnChar driverPath[XN_FILE_MAX_PATH]; + + // Use driver path specified in ini file if (repositoryOverridden) { - xnLogVerbose(XN_LOG_MASK_ALL, "Using '%s' as driver path, as configured in file '%s'", ONI_CONFIGURATION_FILE); - rc = loadLibraries(repositoryFromINI); + // Resolve the path based on the module's directory. + xnOSStrCopy(driverPath, baseDir, XN_FILE_MAX_PATH); + rc = xnOSAppendFilePath(driverPath, repositoryFromINI, XN_FILE_MAX_PATH); + if (rc != XN_STATUS_OK) { + m_errorLogger.Append("The specified driver path '%s' in the configuration file '%s' makes the path too long", repositoryFromINI, oniConfigurationFile); + return OniStatusFromXnStatus(rc); + } + xnLogVerbose(XN_LOG_MASK_ALL, "Using '%s' as driver path, as configured in file '%s'", driverPath, oniConfigurationFile); + rc = loadLibraries(driverPath); return OniStatusFromXnStatus(rc); } - xnLogVerbose(XN_LOG_MASK_ALL, "Using '%s' as driver path", ONI_DEFAULT_DRIVERS_REPOSITORY); - // Use default path - rc = loadLibraries(ONI_DEFAULT_DRIVERS_REPOSITORY); + // Use default driver path, resolved based on the module's directory + xnOSStrCopy(driverPath, baseDir, XN_FILE_MAX_PATH); + rc = xnOSAppendFilePath(driverPath, ONI_DEFAULT_DRIVERS_REPOSITORY, XN_FILE_MAX_PATH); + if (rc != XN_STATUS_OK) { + m_errorLogger.Append("The driver path is too long"); + return OniStatusFromXnStatus(rc); + } + + xnLogVerbose(XN_LOG_MASK_ALL, "Using '%s' as driver path", driverPath); + rc = loadLibraries(driverPath); if (rc != XN_STATUS_OK) { + // Need review: + // I (Tomoto) think it is not necessary to search the drivers based on the environment variable. + // It could be just confusing by introducing the inconsistency between OpenNI DLL and drivers. + // I left it only for the backward compatibility, but probably we'd better remove it. + // Can't find through default - try environment variable - xnLogVerbose(XN_LOG_MASK_ALL, "Can't load drivers from default directory '%s'.", ONI_DEFAULT_DRIVERS_REPOSITORY); + xnLogVerbose(XN_LOG_MASK_ALL, "Can't load drivers from default directory '%s'.", driverPath); - char dirName[XN_FILE_MAX_PATH]; - XnStatus envrc = xnOSGetEnvironmentVariable(ONI_ENV_VAR_DRIVERS_REPOSITORY, dirName, XN_FILE_MAX_PATH); + XnStatus envrc = xnOSGetEnvironmentVariable(ONI_ENV_VAR_DRIVERS_REPOSITORY, driverPath, XN_FILE_MAX_PATH); if (envrc == XN_STATUS_OK) { - xnLogVerbose(XN_LOG_MASK_ALL, "Using '%s' as driver path, as configured by environment variable '%s'", dirName, ONI_ENV_VAR_DRIVERS_REPOSITORY); - rc = loadLibraries(dirName); + xnLogVerbose(XN_LOG_MASK_ALL, "Using '%s' as driver path, as configured by environment variable '%s'", driverPath, ONI_ENV_VAR_DRIVERS_REPOSITORY); + rc = loadLibraries(driverPath); } } diff --git a/ThirdParty/PSCommon/XnLib/Include/XnOS.h b/ThirdParty/PSCommon/XnLib/Include/XnOS.h index 2b8fd539..87ae1c66 100644 --- a/ThirdParty/PSCommon/XnLib/Include/XnOS.h +++ b/ThirdParty/PSCommon/XnLib/Include/XnOS.h @@ -472,6 +472,20 @@ XN_C_API XnStatus XN_C_DECL xnOSStripDirSep(XnChar* strDirName); * Checks if the specified character works as a directory separator. */ XN_C_API XnBool XN_C_DECL xnOSIsDirSep(XnChar c); +/** + * Appends the specified path component(s) to the specified path buffer. + * Directory separator is applied if necessary. + * If the path component to append is an absolute path, the resulted path is completely altered with it. + * + * @param strDestPath [in] Buffer that stores the original path to be operated. + * @param strPathComponentToAppend [in] Path component(s) to append. Can be absolute or relative. + * @param nBufferSize [in] Size of strDestPath. + */ +XN_C_API XnStatus XN_C_DECL xnOSAppendFilePath(XnChar* strDestPath, const XnChar* strPathComponentToAppend, const XnUInt32 nBufferSize); +/** + * Returns true if the specified path is absolute. + */ +XN_C_API XnBool XN_C_DECL xnOSIsAbsoluteFilePath(const XnChar* strFilePath); XN_C_API XnStatus XN_C_DECL xnOSDeleteFile(const XnChar* cpFileName); XN_C_API XnStatus XN_C_DECL xnOSDeleteEmptyDirectory(const XnChar* strDirName); XN_C_API XnStatus XN_C_DECL xnOSDeleteDirectoryTree(const XnChar* strDirName); @@ -491,6 +505,14 @@ XN_C_API XnStatus XN_C_DECL xnOSLoadLibrary(const XnChar* cpFileName, XN_LIB_HAN XN_C_API XnStatus XN_C_DECL xnOSFreeLibrary(const XN_LIB_HANDLE LibHandle); XN_C_API XnStatus XN_C_DECL xnOSGetProcAddress(const XN_LIB_HANDLE LibHandle, const XnChar* cpProcName, XnFarProc* pProcAddr); +/** + * Returns the absolute path of the module that includes the specified proc address. + * + * @param procAddr [in] Proc address contained by the target module. + * @param strModulePath [in] Buffer to receive the absolute path of the module. Must have the size of XN_FILE_MAX_PATH at least. + */ +XN_C_API XnStatus XN_C_DECL xnOSGetModulePathForProcAddress(void* procAddr, XnChar *strModulePath); + struct timespec; // Time diff --git a/ThirdParty/PSCommon/XnLib/Source/Linux/XnLinuxFiles.cpp b/ThirdParty/PSCommon/XnLib/Source/Linux/XnLinuxFiles.cpp index 72a01332..a0db2752 100644 --- a/ThirdParty/PSCommon/XnLib/Source/Linux/XnLinuxFiles.cpp +++ b/ThirdParty/PSCommon/XnLib/Source/Linux/XnLinuxFiles.cpp @@ -681,3 +681,8 @@ XN_C_API XnStatus xnOSDoesDirectoryExist(const XnChar* cpDirName, XnBool* pbResu return (XN_STATUS_OK); } +// Need review: NOT TESTED YET +XN_C_API XnBool xnOSIsAbsoluteFilePath(const XnChar* strFilePath) +{ + return xnOSIsDirSep(strFilePath[0]); +} diff --git a/ThirdParty/PSCommon/XnLib/Source/Linux/XnLinuxSharedLibs.cpp b/ThirdParty/PSCommon/XnLib/Source/Linux/XnLinuxSharedLibs.cpp index 9d34886e..108cde4c 100644 --- a/ThirdParty/PSCommon/XnLib/Source/Linux/XnLinuxSharedLibs.cpp +++ b/ThirdParty/PSCommon/XnLib/Source/Linux/XnLinuxSharedLibs.cpp @@ -81,3 +81,12 @@ XN_C_API XnStatus xnOSGetProcAddress(const XN_LIB_HANDLE LibHandle, const XnChar // All is good... return (XN_STATUS_OK); } + +// Need review: NOT IMPLEMENTED YET +XN_C_API XnStatus xnOSGetModulePathForProcAddress(void* procAddr, XnChar *strModulePath) +{ + // PLEASE IMPLEMENT. Probably you can use dladdr() function. + // Here's a dummy implementation that should not break existing things at least. + strcpy(strModulePath, "./dummy"); + return XN_STATUS_OK; +} diff --git a/ThirdParty/PSCommon/XnLib/Source/Win32/XnWin32Files.cpp b/ThirdParty/PSCommon/XnLib/Source/Win32/XnWin32Files.cpp index 96ede886..ceafcd6b 100644 --- a/ThirdParty/PSCommon/XnLib/Source/Win32/XnWin32Files.cpp +++ b/ThirdParty/PSCommon/XnLib/Source/Win32/XnWin32Files.cpp @@ -747,3 +747,9 @@ XN_C_API XnStatus xnOSGetFullPathName(const XnChar* strFilePath, XnChar* strFull return XN_STATUS_OK; } + +XN_C_API XnBool xnOSIsAbsoluteFilePath(const XnChar* strFilePath) +{ + // If the path starts with , it is absolute. + return xnOSStrLen(strFilePath) >= 3 && isalpha(strFilePath[0]) && strFilePath[1] == ':' && xnOSIsDirSep(strFilePath[2]); +} diff --git a/ThirdParty/PSCommon/XnLib/Source/Win32/XnWin32SharedLibrary.cpp b/ThirdParty/PSCommon/XnLib/Source/Win32/XnWin32SharedLibrary.cpp index 9b327455..8a928146 100644 --- a/ThirdParty/PSCommon/XnLib/Source/Win32/XnWin32SharedLibrary.cpp +++ b/ThirdParty/PSCommon/XnLib/Source/Win32/XnWin32SharedLibrary.cpp @@ -82,3 +82,19 @@ XN_C_API XnStatus xnOSGetProcAddress(const XN_LIB_HANDLE LibHandle, const XnChar // All is good... return (XN_STATUS_OK); } + +XN_C_API XnStatus xnOSGetModulePathForProcAddress(void* procAddr, XnChar *strModulePath) +{ + HMODULE hModule; + BOOL rc = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)procAddr, &hModule); + if (!rc) { + return XN_STATUS_ERROR; + } + + DWORD len = GetModuleFileName(hModule, strModulePath, XN_FILE_MAX_PATH); + if (len == 0) { + return XN_STATUS_ERROR; + } + + return XN_STATUS_OK; +} diff --git a/ThirdParty/PSCommon/XnLib/Source/XnFiles.cpp b/ThirdParty/PSCommon/XnLib/Source/XnFiles.cpp index d6d5b983..70b6e2b7 100644 --- a/ThirdParty/PSCommon/XnLib/Source/XnFiles.cpp +++ b/ThirdParty/PSCommon/XnLib/Source/XnFiles.cpp @@ -120,3 +120,18 @@ XN_C_API XnBool xnOSIsDirSep(XnChar c) { return strchr(XN_FILE_DIR_SEPS, c) != NULL; } + +XN_C_API XnStatus XN_C_DECL xnOSAppendFilePath(XnChar* strDestPath, const XnChar* strPathComponentToAppend, const XnUInt32 nBufferSize) +{ + XnStatus rc; + if (xnOSIsAbsoluteFilePath(strPathComponentToAppend)) { + // If the path to append is absolute, use it entirely. + XN_VALIDATE_STR_COPY(strDestPath, strPathComponentToAppend, nBufferSize, rc); + } else { + // If the path to append is relative, append it after applyling the separator as needed. + xnOSStripDirSep(strDestPath); + XN_VALIDATE_STR_APPEND(strDestPath, XN_FILE_DIR_SEP, nBufferSize, rc); + XN_VALIDATE_STR_APPEND(strDestPath, strPathComponentToAppend, nBufferSize, rc); + } + return XN_STATUS_OK; +} From 262088484922663fb4ad22a6b46d29088699ff83 Mon Sep 17 00:00:00 2001 From: tomoto335 Date: Mon, 7 Jan 2013 01:03:25 -0800 Subject: [PATCH 3/8] [Optional] Simplify driver and OpenNI.ini path resolution As described in the previous commit, resolving the driver path based on environment variable (OPENNI2_DRIVERS_PATH) and reading OpenNI.ini from the current directory could be only confusing if we started to resolve it based on OpenNI2.dll's directory. If you agree, please use this commit to remove these features. It will make the behavior and the code much simpler and more explainable. --- Source/Core/OniContext.cpp | 68 ++++++++------------------------------ 1 file changed, 13 insertions(+), 55 deletions(-) diff --git a/Source/Core/OniContext.cpp b/Source/Core/OniContext.cpp index e3930666..2d91a461 100644 --- a/Source/Core/OniContext.cpp +++ b/Source/Core/OniContext.cpp @@ -23,11 +23,6 @@ #include static const char* ONI_CONFIGURATION_FILE = "OpenNI.ini"; -#if (XN_PLATFORM == XN_PLATFORM_WIN32) && (_M_X64) -static const char* ONI_ENV_VAR_DRIVERS_REPOSITORY = "OPENNI2_DRIVERS_PATH64"; -#else -static const char* ONI_ENV_VAR_DRIVERS_REPOSITORY = "OPENNI2_DRIVERS_PATH"; -#endif static const char* ONI_DEFAULT_DRIVERS_REPOSITORY = "OpenNI2" XN_FILE_DIR_SEP "Drivers"; ONI_NAMESPACE_IMPLEMENTATION_BEGIN @@ -90,24 +85,11 @@ OniStatus Context::initialize() XnChar oniConfigurationFile[XN_FILE_MAX_PATH]; XnBool configurationFileExists = FALSE; - // Need review: - // I (Tomoto) think it is not necessary to search the current directory for OpenNI.ini - // because it could be counter-intuitive rather than beneficial that the current directory - // might affect on the OpenNI behavior. - // I left it only for the backward compatibility, but probably we'd better remove it. - - // Check the current directory first. - xnOSStrCopy(oniConfigurationFile, XN_FILE_LOCAL_DIR, XN_FILE_MAX_PATH); - xnOSAppendFilePath(oniConfigurationFile, ONI_CONFIGURATION_FILE, XN_FILE_MAX_PATH); - xnOSDoesFileExist(oniConfigurationFile, &configurationFileExists); - - // Check the module directory next. - if (!configurationFileExists) { - xnOSStrCopy(oniConfigurationFile, baseDir, XN_FILE_MAX_PATH); - rc = xnOSAppendFilePath(oniConfigurationFile, ONI_CONFIGURATION_FILE, XN_FILE_MAX_PATH); - if (rc == XN_STATUS_OK) { - xnOSDoesFileExist(oniConfigurationFile, &configurationFileExists); - } + // Search the module directory for OpenNI.ini. + xnOSStrCopy(oniConfigurationFile, baseDir, XN_FILE_MAX_PATH); + rc = xnOSAppendFilePath(oniConfigurationFile, ONI_CONFIGURATION_FILE, XN_FILE_MAX_PATH); + if (rc == XN_STATUS_OK) { + xnOSDoesFileExist(oniConfigurationFile, &configurationFileExists); } if (configurationFileExists) @@ -155,50 +137,26 @@ OniStatus Context::initialize() xnLogVerbose(XN_LOG_MASK_ALL, "OpenNI %s", ONI_VERSION_STRING); + // Resolve the drive path based on the module's directory. XnChar driverPath[XN_FILE_MAX_PATH]; + xnOSStrCopy(driverPath, baseDir, XN_FILE_MAX_PATH); - // Use driver path specified in ini file if (repositoryOverridden) { - // Resolve the path based on the module's directory. - xnOSStrCopy(driverPath, baseDir, XN_FILE_MAX_PATH); + xnLogVerbose(XN_LOG_MASK_ALL, "Extending the driver path by '%s', as configured in file '%s'", repositoryFromINI, oniConfigurationFile); rc = xnOSAppendFilePath(driverPath, repositoryFromINI, XN_FILE_MAX_PATH); - if (rc != XN_STATUS_OK) { - m_errorLogger.Append("The specified driver path '%s' in the configuration file '%s' makes the path too long", repositoryFromINI, oniConfigurationFile); - return OniStatusFromXnStatus(rc); - } - xnLogVerbose(XN_LOG_MASK_ALL, "Using '%s' as driver path, as configured in file '%s'", driverPath, oniConfigurationFile); - rc = loadLibraries(driverPath); - return OniStatusFromXnStatus(rc); + } else { + rc = xnOSAppendFilePath(driverPath, ONI_DEFAULT_DRIVERS_REPOSITORY, XN_FILE_MAX_PATH); } - // Use default driver path, resolved based on the module's directory - xnOSStrCopy(driverPath, baseDir, XN_FILE_MAX_PATH); - rc = xnOSAppendFilePath(driverPath, ONI_DEFAULT_DRIVERS_REPOSITORY, XN_FILE_MAX_PATH); - if (rc != XN_STATUS_OK) { - m_errorLogger.Append("The driver path is too long"); + if (rc != XN_STATUS_OK) + { + m_errorLogger.Append("The driver path gets too long"); return OniStatusFromXnStatus(rc); } xnLogVerbose(XN_LOG_MASK_ALL, "Using '%s' as driver path", driverPath); rc = loadLibraries(driverPath); - if (rc != XN_STATUS_OK) - { - // Need review: - // I (Tomoto) think it is not necessary to search the drivers based on the environment variable. - // It could be just confusing by introducing the inconsistency between OpenNI DLL and drivers. - // I left it only for the backward compatibility, but probably we'd better remove it. - - // Can't find through default - try environment variable - xnLogVerbose(XN_LOG_MASK_ALL, "Can't load drivers from default directory '%s'.", driverPath); - - XnStatus envrc = xnOSGetEnvironmentVariable(ONI_ENV_VAR_DRIVERS_REPOSITORY, driverPath, XN_FILE_MAX_PATH); - if (envrc == XN_STATUS_OK) - { - xnLogVerbose(XN_LOG_MASK_ALL, "Using '%s' as driver path, as configured by environment variable '%s'", driverPath, ONI_ENV_VAR_DRIVERS_REPOSITORY); - rc = loadLibraries(driverPath); - } - } if (rc == XN_STATUS_OK) { From 6cdf6a7ebcde34f6e00cd201371a167c4aec52e9 Mon Sep 17 00:00:00 2001 From: tomoto335 Date: Mon, 7 Jan 2013 03:27:09 -0800 Subject: [PATCH 4/8] Resolve PS1080.ini path based on PS1080.dll's directory Problem: - PS1080.ini is read from the current directory, which could be a problem because (1) it would restrict the application to be runnable only in a designated directory and (2) the current directory would be messed up by these driver dependent files. See the OpenNI community at http://community.openni.org/openni/topics/search_path_for_redist_files where I originally pointed out this issue. Solution: - Now PS1080.ini is read from the same location as PS1080.dll. Description of changes: - XnSensor.cpp: ResolveGlobalConfigFileName() is modified to resolve the config file's path based on the DLL's directory when the strConfigDir is specified as NULL, and now XnSensor's constructor uses it to initialize m_strGlobalConfigFile. - XnSensor.h: Comment is added for ResolveGlobalConfigFileName(). - Config/PS1080.ini: Moved to Config/OpenNI2/Drivers/PS1080.ini. Note: - Please test the installer (Redist.py) if it deploys PS1080.ini as intended, i.e. along with PS1080.dll. --- Config/{ => OpenNI2/Drivers}/PS1080.ini | 0 Source/Drivers/PS1080/Sensor/XnSensor.cpp | 22 ++++++++++++++++++---- Source/Drivers/PS1080/Sensor/XnSensor.h | 5 +++++ 3 files changed, 23 insertions(+), 4 deletions(-) rename Config/{ => OpenNI2/Drivers}/PS1080.ini (100%) diff --git a/Config/PS1080.ini b/Config/OpenNI2/Drivers/PS1080.ini similarity index 100% rename from Config/PS1080.ini rename to Config/OpenNI2/Drivers/PS1080.ini diff --git a/Source/Drivers/PS1080/Sensor/XnSensor.cpp b/Source/Drivers/PS1080/Sensor/XnSensor.cpp index 4f0362e7..430c3d4f 100644 --- a/Source/Drivers/PS1080/Sensor/XnSensor.cpp +++ b/Source/Drivers/PS1080/Sensor/XnSensor.cpp @@ -39,7 +39,7 @@ #define XN_SENSOR_FRAME_SYNC_MAX_DIFF 3 #define XN_SENSOR_DEFAULT_CLOSE_STREAMS_ON_SHUTDOWN TRUE #define XN_SENSOR_DEFAULT_HOST_TIMESTAMPS FALSE -#define XN_GLOBAL_CONFIG_FILE_NAME "./PS1080.ini" +#define XN_GLOBAL_CONFIG_FILE_NAME "PS1080.ini" #define FRAME_SYNC_MAX_FRAME_TIME_DIFF 3000 @@ -100,7 +100,7 @@ XnSensor::XnSensor(XnBool bResetOnStartup /* = TRUE */, XnBool bLeanInit /* = FA { // reset all data xnOSMemSet(&m_DevicePrivateData, 0, sizeof(XnDevicePrivateData)); - xnOSStrCopy(m_strGlobalConfigFile, XN_GLOBAL_CONFIG_FILE_NAME, sizeof(m_strGlobalConfigFile)); + ResolveGlobalConfigFileName(m_strGlobalConfigFile, sizeof(m_strGlobalConfigFile), NULL); m_ResetSensorOnStartup.UpdateSetCallbackToDefault(); m_LeanInit.UpdateSetCallbackToDefault(); @@ -573,8 +573,22 @@ XnStatus XnSensor::ValidateSensorID(XnChar* csSensorID) XnStatus XnSensor::ResolveGlobalConfigFileName(XnChar* strConfigFile, XnUInt32 nBufSize, const XnChar* strConfigDir) { - XnUInt32 nWritten = 0; - return xnOSStrFormat(strConfigFile, nBufSize, &nWritten, "%s%s%s", strConfigDir, XN_FILE_DIR_SEP, XN_GLOBAL_CONFIG_FILE_NAME); + // If strConfigDir is NULL, tries to resolve the config file based on the driver's directory + XnChar baseDir[XN_FILE_MAX_PATH]; + if (strConfigDir == NULL) { + if (xnOSGetModulePathForProcAddress(ResolveGlobalConfigFileName, baseDir) == XN_STATUS_OK && + xnOSGetDirName(baseDir, baseDir, XN_FILE_MAX_PATH) == XN_STATUS_OK) { + // Successfully obtained the driver's path + strConfigDir = baseDir; + } else { + // Something wrong happened. Use the current directory as the fallback. + strConfigDir = "."; + } + } + + XnStatus rc; + XN_VALIDATE_STR_COPY(strConfigFile, strConfigDir, nBufSize, rc); + return xnOSAppendFilePath(strConfigFile, XN_GLOBAL_CONFIG_FILE_NAME, nBufSize); } XnStatus XnSensor::SetGlobalConfigFile(const XnChar* strConfigFile) diff --git a/Source/Drivers/PS1080/Sensor/XnSensor.h b/Source/Drivers/PS1080/Sensor/XnSensor.h index 88fa43c7..996b6998 100644 --- a/Source/Drivers/PS1080/Sensor/XnSensor.h +++ b/Source/Drivers/PS1080/Sensor/XnSensor.h @@ -74,7 +74,12 @@ class XnSensor : public XnDeviceBase inline XnStatus GetErrorState() { return (XnStatus)m_ErrorState.GetValue(); } XnStatus SetErrorState(XnStatus errorState); + /** + * Resolves the config file's path. + * Specify NULL to strConfigDir to resolve it based on the driver's directory. + */ static XnStatus ResolveGlobalConfigFileName(XnChar* strConfigFile, XnUInt32 nBufSize, const XnChar* strConfigDir); + XnStatus SetGlobalConfigFile(const XnChar* strConfigFile); XnStatus ConfigureModuleFromGlobalFile(const XnChar* strModule, const XnChar* strSection = NULL); From 86efc7a1232f9b11f4df7c7b5eb039dc7e20ccf0 Mon Sep 17 00:00:00 2001 From: tomoto335 Date: Tue, 8 Jan 2013 02:59:38 -0800 Subject: [PATCH 5/8] Linux implementation of DLL-based path resolution. - OniContext.cpp, XnSensor.cpp: Cast is applied to function pointer to avoid gcc compilation errors. (Thanks to Benn for contribution) - XnLinuxSharedLibs.cpp: xnOSGetModulePathForProcAddress() is implemented. xnOSLoadLibrary() is also fixed to let dladdr() return the desired information. --- Source/Core/OniContext.cpp | 2 +- Source/Drivers/PS1080/Sensor/XnSensor.cpp | 2 +- .../XnLib/Source/Linux/XnLinuxSharedLibs.cpp | 25 ++++++++++++++----- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/Source/Core/OniContext.cpp b/Source/Core/OniContext.cpp index 2d91a461..c9712168 100644 --- a/Source/Core/OniContext.cpp +++ b/Source/Core/OniContext.cpp @@ -57,7 +57,7 @@ OniStatus Context::initialize() XnStatus rc; XnChar modulePath[XN_FILE_MAX_PATH]; - rc = xnOSGetModulePathForProcAddress(&dummyFunctionToTakeAddress, modulePath); + rc = xnOSGetModulePathForProcAddress(reinterpret_cast(&dummyFunctionToTakeAddress), modulePath); if (rc != XN_STATUS_OK) { m_errorLogger.Append("Couldn't get the OpenNI shared library module's path: %s", xnGetStatusString(rc)); return OniStatusFromXnStatus(rc); diff --git a/Source/Drivers/PS1080/Sensor/XnSensor.cpp b/Source/Drivers/PS1080/Sensor/XnSensor.cpp index 430c3d4f..e507612e 100644 --- a/Source/Drivers/PS1080/Sensor/XnSensor.cpp +++ b/Source/Drivers/PS1080/Sensor/XnSensor.cpp @@ -576,7 +576,7 @@ XnStatus XnSensor::ResolveGlobalConfigFileName(XnChar* strConfigFile, XnUInt32 n // If strConfigDir is NULL, tries to resolve the config file based on the driver's directory XnChar baseDir[XN_FILE_MAX_PATH]; if (strConfigDir == NULL) { - if (xnOSGetModulePathForProcAddress(ResolveGlobalConfigFileName, baseDir) == XN_STATUS_OK && + if (xnOSGetModulePathForProcAddress(reinterpret_cast(&XnSensor::ResolveGlobalConfigFileName), baseDir) == XN_STATUS_OK && xnOSGetDirName(baseDir, baseDir, XN_FILE_MAX_PATH) == XN_STATUS_OK) { // Successfully obtained the driver's path strConfigDir = baseDir; diff --git a/ThirdParty/PSCommon/XnLib/Source/Linux/XnLinuxSharedLibs.cpp b/ThirdParty/PSCommon/XnLib/Source/Linux/XnLinuxSharedLibs.cpp index 108cde4c..54d82190 100644 --- a/ThirdParty/PSCommon/XnLib/Source/Linux/XnLinuxSharedLibs.cpp +++ b/ThirdParty/PSCommon/XnLib/Source/Linux/XnLinuxSharedLibs.cpp @@ -34,8 +34,19 @@ XN_C_API XnStatus xnOSLoadLibrary(const XnChar* cpFileName, XN_LIB_HANDLE* pLibH XN_VALIDATE_INPUT_PTR(cpFileName); XN_VALIDATE_OUTPUT_PTR(pLibHandle); + // Resolve the file name to the absolute path. This is necessary because + // we need to get the absolute path of this library by dladdr() later. + // Note dladdr() seems to return the path specified to dlopen() "as it is". + XnChar* strAbsoluteFileName = realpath(cpFileName, NULL); + if (strAbsoluteFileName == NULL) { + // error + xnLogWarning(XN_MASK_OS, "Failed to get absolute path for lib: %s\n", cpFileName); + return XN_STATUS_OS_CANT_LOAD_LIB; + } + // Load the requested shared library via the OS - *pLibHandle = dlopen(cpFileName, RTLD_NOW); + *pLibHandle = dlopen(strAbsoluteFileName, RTLD_NOW); + free(strAbsoluteFileName); // Don't forget to free the memory allocated by realpath(). // Make sure it succeeded (return value is not NULL). If not return an error.... if (*pLibHandle == NULL) @@ -82,11 +93,13 @@ XN_C_API XnStatus xnOSGetProcAddress(const XN_LIB_HANDLE LibHandle, const XnChar return (XN_STATUS_OK); } -// Need review: NOT IMPLEMENTED YET XN_C_API XnStatus xnOSGetModulePathForProcAddress(void* procAddr, XnChar *strModulePath) { - // PLEASE IMPLEMENT. Probably you can use dladdr() function. - // Here's a dummy implementation that should not break existing things at least. - strcpy(strModulePath, "./dummy"); - return XN_STATUS_OK; + Dl_info info; + if (!dladdr(procAddr, &info)) { + xnLogWarning(XN_MASK_OS, "Failed to get the dl info: %s\n", dlerror()); + return XN_STATUS_ERROR; + } + + return xnOSStrCopy(strModulePath, info.dli_fname, XN_FILE_MAX_PATH); } From 919ce4cc6c18aa4d05214fa9748fe6690c9d34f6 Mon Sep 17 00:00:00 2001 From: tomoto Date: Tue, 15 Jan 2013 02:57:04 -0800 Subject: [PATCH 6/8] Fixed a minor bug where xnOSIsDirSep returns a wrong answer (true) when \0 is passed. --- ThirdParty/PSCommon/XnLib/Source/XnFiles.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ThirdParty/PSCommon/XnLib/Source/XnFiles.cpp b/ThirdParty/PSCommon/XnLib/Source/XnFiles.cpp index 70b6e2b7..f9c7cf40 100644 --- a/ThirdParty/PSCommon/XnLib/Source/XnFiles.cpp +++ b/ThirdParty/PSCommon/XnLib/Source/XnFiles.cpp @@ -118,7 +118,7 @@ XN_C_API XnStatus xnOSStripDirSep(XnChar* strDirName) XN_C_API XnBool xnOSIsDirSep(XnChar c) { - return strchr(XN_FILE_DIR_SEPS, c) != NULL; + return (c != '\0') && (strchr(XN_FILE_DIR_SEPS, c) != NULL); } XN_C_API XnStatus XN_C_DECL xnOSAppendFilePath(XnChar* strDestPath, const XnChar* strPathComponentToAppend, const XnUInt32 nBufferSize) From b22a8669ef00f61dacadf8d9b40705f97efcb0d0 Mon Sep 17 00:00:00 2001 From: tomoto335 Date: Tue, 15 Jan 2013 03:39:56 -0800 Subject: [PATCH 7/8] Fixed the format as per the coding style guide. --- Source/Core/OniContext.cpp | 57 ++++++++++--------- Source/Drivers/PS1080/Sensor/XnSensor.cpp | 16 ++++-- .../XnLib/Source/Linux/XnLinuxFiles.cpp | 1 - .../XnLib/Source/Linux/XnLinuxSharedLibs.cpp | 6 +- .../Source/Win32/XnWin32SharedLibrary.cpp | 6 +- ThirdParty/PSCommon/XnLib/Source/XnFiles.cpp | 10 +++- 6 files changed, 56 insertions(+), 40 deletions(-) diff --git a/Source/Core/OniContext.cpp b/Source/Core/OniContext.cpp index c9712168..1eb13b6d 100644 --- a/Source/Core/OniContext.cpp +++ b/Source/Core/OniContext.cpp @@ -56,16 +56,18 @@ OniStatus Context::initialize() XnStatus rc; - XnChar modulePath[XN_FILE_MAX_PATH]; - rc = xnOSGetModulePathForProcAddress(reinterpret_cast(&dummyFunctionToTakeAddress), modulePath); - if (rc != XN_STATUS_OK) { + XnChar strModulePath[XN_FILE_MAX_PATH]; + rc = xnOSGetModulePathForProcAddress(reinterpret_cast(&dummyFunctionToTakeAddress), strModulePath); + if (rc != XN_STATUS_OK) + { m_errorLogger.Append("Couldn't get the OpenNI shared library module's path: %s", xnGetStatusString(rc)); return OniStatusFromXnStatus(rc); } - XnChar baseDir[XN_FILE_MAX_PATH]; - rc = xnOSGetDirName(modulePath, baseDir, XN_FILE_MAX_PATH); - if (rc != XN_STATUS_OK) { + XnChar strBaseDir[XN_FILE_MAX_PATH]; + rc = xnOSGetDirName(strModulePath, strBaseDir, XN_FILE_MAX_PATH); + if (rc != XN_STATUS_OK) + { // Very unlikely to happen, but just in case. m_errorLogger.Append("Couldn't get the OpenNI shared library module's directory: %s", xnGetStatusString(rc)); return OniStatusFromXnStatus(rc); @@ -82,14 +84,15 @@ OniStatus Context::initialize() // Read configuration file - XnChar oniConfigurationFile[XN_FILE_MAX_PATH]; + XnChar strOniConfigurationFile[XN_FILE_MAX_PATH]; XnBool configurationFileExists = FALSE; // Search the module directory for OpenNI.ini. - xnOSStrCopy(oniConfigurationFile, baseDir, XN_FILE_MAX_PATH); - rc = xnOSAppendFilePath(oniConfigurationFile, ONI_CONFIGURATION_FILE, XN_FILE_MAX_PATH); - if (rc == XN_STATUS_OK) { - xnOSDoesFileExist(oniConfigurationFile, &configurationFileExists); + xnOSStrCopy(strOniConfigurationFile, strBaseDir, XN_FILE_MAX_PATH); + rc = xnOSAppendFilePath(strOniConfigurationFile, ONI_CONFIGURATION_FILE, XN_FILE_MAX_PATH); + if (rc == XN_STATUS_OK) + { + xnOSDoesFileExist(strOniConfigurationFile, &configurationFileExists); } if (configurationFileExists) @@ -97,18 +100,18 @@ OniStatus Context::initialize() // First, we should process the log related configuration as early as possible. XnInt32 nValue; - rc = xnOSReadIntFromINI(oniConfigurationFile, "Log", "Verbosity", &nValue); + rc = xnOSReadIntFromINI(strOniConfigurationFile, "Log", "Verbosity", &nValue); if (rc == XN_STATUS_OK) { xnLogSetMaskMinSeverity(XN_LOG_MASK_ALL, (XnLogSeverity)nValue); } - rc = xnOSReadIntFromINI(oniConfigurationFile, "Log", "LogToConsole", &nValue); + rc = xnOSReadIntFromINI(strOniConfigurationFile, "Log", "LogToConsole", &nValue); if (rc == XN_STATUS_OK) { xnLogSetConsoleOutput(nValue == 1); } - rc = xnOSReadIntFromINI(oniConfigurationFile, "Log", "LogToFile", &nValue); + rc = xnOSReadIntFromINI(strOniConfigurationFile, "Log", "LogToFile", &nValue); if (rc == XN_STATUS_OK) { xnLogSetFileOutput(nValue == 1); @@ -116,37 +119,39 @@ OniStatus Context::initialize() // Then, process the other device configurations. - rc = xnOSReadStringFromINI(oniConfigurationFile, "Device", "Override", m_overrideDevice, XN_FILE_MAX_PATH); + rc = xnOSReadStringFromINI(strOniConfigurationFile, "Device", "Override", m_overrideDevice, XN_FILE_MAX_PATH); if (rc != XN_STATUS_OK) { xnLogVerbose(XN_LOG_MASK_ALL, "No override device in configuration file"); } - rc = xnOSReadStringFromINI(oniConfigurationFile, "Drivers", "Repository", repositoryFromINI, XN_FILE_MAX_PATH); + rc = xnOSReadStringFromINI(strOniConfigurationFile, "Drivers", "Repository", repositoryFromINI, XN_FILE_MAX_PATH); if (rc == XN_STATUS_OK) { repositoryOverridden = TRUE; } - xnLogVerbose(XN_LOG_MASK_ALL, "Configuration has been read from '%s'", oniConfigurationFile); + xnLogVerbose(XN_LOG_MASK_ALL, "Configuration has been read from '%s'", strOniConfigurationFile); } else { - xnLogVerbose(XN_LOG_MASK_ALL, "Couldn't find configuration file '%s'", oniConfigurationFile); + xnLogVerbose(XN_LOG_MASK_ALL, "Couldn't find configuration file '%s'", strOniConfigurationFile); } xnLogVerbose(XN_LOG_MASK_ALL, "OpenNI %s", ONI_VERSION_STRING); // Resolve the drive path based on the module's directory. - XnChar driverPath[XN_FILE_MAX_PATH]; - xnOSStrCopy(driverPath, baseDir, XN_FILE_MAX_PATH); + XnChar strDriverPath[XN_FILE_MAX_PATH]; + xnOSStrCopy(strDriverPath, strBaseDir, XN_FILE_MAX_PATH); if (repositoryOverridden) { - xnLogVerbose(XN_LOG_MASK_ALL, "Extending the driver path by '%s', as configured in file '%s'", repositoryFromINI, oniConfigurationFile); - rc = xnOSAppendFilePath(driverPath, repositoryFromINI, XN_FILE_MAX_PATH); - } else { - rc = xnOSAppendFilePath(driverPath, ONI_DEFAULT_DRIVERS_REPOSITORY, XN_FILE_MAX_PATH); + xnLogVerbose(XN_LOG_MASK_ALL, "Extending the driver path by '%s', as configured in file '%s'", repositoryFromINI, strOniConfigurationFile); + rc = xnOSAppendFilePath(strDriverPath, repositoryFromINI, XN_FILE_MAX_PATH); + } + else + { + rc = xnOSAppendFilePath(strDriverPath, ONI_DEFAULT_DRIVERS_REPOSITORY, XN_FILE_MAX_PATH); } if (rc != XN_STATUS_OK) @@ -155,8 +160,8 @@ OniStatus Context::initialize() return OniStatusFromXnStatus(rc); } - xnLogVerbose(XN_LOG_MASK_ALL, "Using '%s' as driver path", driverPath); - rc = loadLibraries(driverPath); + xnLogVerbose(XN_LOG_MASK_ALL, "Using '%s' as driver path", strDriverPath); + rc = loadLibraries(strDriverPath); if (rc == XN_STATUS_OK) { diff --git a/Source/Drivers/PS1080/Sensor/XnSensor.cpp b/Source/Drivers/PS1080/Sensor/XnSensor.cpp index e507612e..b277b949 100644 --- a/Source/Drivers/PS1080/Sensor/XnSensor.cpp +++ b/Source/Drivers/PS1080/Sensor/XnSensor.cpp @@ -574,13 +574,17 @@ XnStatus XnSensor::ValidateSensorID(XnChar* csSensorID) XnStatus XnSensor::ResolveGlobalConfigFileName(XnChar* strConfigFile, XnUInt32 nBufSize, const XnChar* strConfigDir) { // If strConfigDir is NULL, tries to resolve the config file based on the driver's directory - XnChar baseDir[XN_FILE_MAX_PATH]; - if (strConfigDir == NULL) { - if (xnOSGetModulePathForProcAddress(reinterpret_cast(&XnSensor::ResolveGlobalConfigFileName), baseDir) == XN_STATUS_OK && - xnOSGetDirName(baseDir, baseDir, XN_FILE_MAX_PATH) == XN_STATUS_OK) { + XnChar strBaseDir[XN_FILE_MAX_PATH]; + if (strConfigDir == NULL) + { + if (xnOSGetModulePathForProcAddress(reinterpret_cast(&XnSensor::ResolveGlobalConfigFileName), strBaseDir) == XN_STATUS_OK && + xnOSGetDirName(strBaseDir, strBaseDir, XN_FILE_MAX_PATH) == XN_STATUS_OK) + { // Successfully obtained the driver's path - strConfigDir = baseDir; - } else { + strConfigDir = strBaseDir; + } + else + { // Something wrong happened. Use the current directory as the fallback. strConfigDir = "."; } diff --git a/ThirdParty/PSCommon/XnLib/Source/Linux/XnLinuxFiles.cpp b/ThirdParty/PSCommon/XnLib/Source/Linux/XnLinuxFiles.cpp index a0db2752..bc986f3f 100644 --- a/ThirdParty/PSCommon/XnLib/Source/Linux/XnLinuxFiles.cpp +++ b/ThirdParty/PSCommon/XnLib/Source/Linux/XnLinuxFiles.cpp @@ -681,7 +681,6 @@ XN_C_API XnStatus xnOSDoesDirectoryExist(const XnChar* cpDirName, XnBool* pbResu return (XN_STATUS_OK); } -// Need review: NOT TESTED YET XN_C_API XnBool xnOSIsAbsoluteFilePath(const XnChar* strFilePath) { return xnOSIsDirSep(strFilePath[0]); diff --git a/ThirdParty/PSCommon/XnLib/Source/Linux/XnLinuxSharedLibs.cpp b/ThirdParty/PSCommon/XnLib/Source/Linux/XnLinuxSharedLibs.cpp index 54d82190..f6c653d5 100644 --- a/ThirdParty/PSCommon/XnLib/Source/Linux/XnLinuxSharedLibs.cpp +++ b/ThirdParty/PSCommon/XnLib/Source/Linux/XnLinuxSharedLibs.cpp @@ -38,7 +38,8 @@ XN_C_API XnStatus xnOSLoadLibrary(const XnChar* cpFileName, XN_LIB_HANDLE* pLibH // we need to get the absolute path of this library by dladdr() later. // Note dladdr() seems to return the path specified to dlopen() "as it is". XnChar* strAbsoluteFileName = realpath(cpFileName, NULL); - if (strAbsoluteFileName == NULL) { + if (strAbsoluteFileName == NULL) + { // error xnLogWarning(XN_MASK_OS, "Failed to get absolute path for lib: %s\n", cpFileName); return XN_STATUS_OS_CANT_LOAD_LIB; @@ -96,7 +97,8 @@ XN_C_API XnStatus xnOSGetProcAddress(const XN_LIB_HANDLE LibHandle, const XnChar XN_C_API XnStatus xnOSGetModulePathForProcAddress(void* procAddr, XnChar *strModulePath) { Dl_info info; - if (!dladdr(procAddr, &info)) { + if (!dladdr(procAddr, &info)) + { xnLogWarning(XN_MASK_OS, "Failed to get the dl info: %s\n", dlerror()); return XN_STATUS_ERROR; } diff --git a/ThirdParty/PSCommon/XnLib/Source/Win32/XnWin32SharedLibrary.cpp b/ThirdParty/PSCommon/XnLib/Source/Win32/XnWin32SharedLibrary.cpp index 8a928146..5fb64e2a 100644 --- a/ThirdParty/PSCommon/XnLib/Source/Win32/XnWin32SharedLibrary.cpp +++ b/ThirdParty/PSCommon/XnLib/Source/Win32/XnWin32SharedLibrary.cpp @@ -87,12 +87,14 @@ XN_C_API XnStatus xnOSGetModulePathForProcAddress(void* procAddr, XnChar *strMod { HMODULE hModule; BOOL rc = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)procAddr, &hModule); - if (!rc) { + if (!rc) + { return XN_STATUS_ERROR; } DWORD len = GetModuleFileName(hModule, strModulePath, XN_FILE_MAX_PATH); - if (len == 0) { + if (len == 0) + { return XN_STATUS_ERROR; } diff --git a/ThirdParty/PSCommon/XnLib/Source/XnFiles.cpp b/ThirdParty/PSCommon/XnLib/Source/XnFiles.cpp index f9c7cf40..1df52784 100644 --- a/ThirdParty/PSCommon/XnLib/Source/XnFiles.cpp +++ b/ThirdParty/PSCommon/XnLib/Source/XnFiles.cpp @@ -110,7 +110,8 @@ XN_C_API XnStatus xnOSAppendFile(const XnChar* cpFileName, const void* pBuffer, XN_C_API XnStatus xnOSStripDirSep(XnChar* strDirName) { XnUInt32 len = xnOSStrLen(strDirName); - if (len > 0 && xnOSIsDirSep(strDirName[len-1])) { + if (len > 0 && xnOSIsDirSep(strDirName[len-1])) + { strDirName[len-1] = '\0'; } return XN_STATUS_OK; @@ -124,10 +125,13 @@ XN_C_API XnBool xnOSIsDirSep(XnChar c) XN_C_API XnStatus XN_C_DECL xnOSAppendFilePath(XnChar* strDestPath, const XnChar* strPathComponentToAppend, const XnUInt32 nBufferSize) { XnStatus rc; - if (xnOSIsAbsoluteFilePath(strPathComponentToAppend)) { + if (xnOSIsAbsoluteFilePath(strPathComponentToAppend)) + { // If the path to append is absolute, use it entirely. XN_VALIDATE_STR_COPY(strDestPath, strPathComponentToAppend, nBufferSize, rc); - } else { + } + else + { // If the path to append is relative, append it after applyling the separator as needed. xnOSStripDirSep(strDestPath); XN_VALIDATE_STR_APPEND(strDestPath, XN_FILE_DIR_SEP, nBufferSize, rc); From d8379f45f0963d9e6cc4ba373e3287b0a3a048c1 Mon Sep 17 00:00:00 2001 From: tomoto335 Date: Tue, 15 Jan 2013 06:19:26 -0800 Subject: [PATCH 8/8] Fix Linux distribution packager. --- Redist/Redist.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Redist/Redist.py b/Redist/Redist.py index ff01f42c..5c96ef1a 100755 --- a/Redist/Redist.py +++ b/Redist/Redist.py @@ -94,9 +94,12 @@ def compileAll(self): def copyOpenNI(self, where): # Copy config content to Redist - for r, d, f in os.walk('Config'): - for file in f: - shutil.copy(r+'/'+file, where) + for f in os.listdir('Config'): + p = 'Config/' + f; + if os.path.isdir(p): + shutil.copytree(p, where+'/'+f); + else: + shutil.copy(p, where+'/'+f); return