diff --git a/config/alfresco/desktop/Alfresco.exe b/config/alfresco/desktop/Alfresco.exe index 94aee691ab..2bc8239ab1 100644 Binary files a/config/alfresco/desktop/Alfresco.exe and b/config/alfresco/desktop/Alfresco.exe differ diff --git a/source/cpp/CAlfrescoApp/CAlfrescoApp.cpp b/source/cpp/CAlfrescoApp/CAlfrescoApp.cpp index 2120081d24..94aa66b959 100644 --- a/source/cpp/CAlfrescoApp/CAlfrescoApp.cpp +++ b/source/cpp/CAlfrescoApp/CAlfrescoApp.cpp @@ -37,14 +37,14 @@ using namespace Alfresco; // CCAlfrescoAppApp -BEGIN_MESSAGE_MAP(CCAlfrescoAppApp, CWinApp) +BEGIN_MESSAGE_MAP(CAlfrescoApp, CWinApp) ON_COMMAND(ID_HELP, CWinApp::OnHelp) END_MESSAGE_MAP() -// CCAlfrescoAppApp construction +// CCAlfrescoApp construction -CCAlfrescoAppApp::CCAlfrescoAppApp() +CAlfrescoApp::CAlfrescoApp() { // TODO: add construction code here, // Place all significant initialization in InitInstance @@ -53,12 +53,12 @@ CCAlfrescoAppApp::CCAlfrescoAppApp() // The one and only CCAlfrescoAppApp object -CCAlfrescoAppApp theApp; +CAlfrescoApp theApp; // CCAlfrescoAppApp initialization -BOOL CCAlfrescoAppApp::InitInstance() +BOOL CAlfrescoApp::InitInstance() { // InitCommonControls() is required on Windows XP if an application // manifest specifies use of ComCtl32.dll version 6 or later to enable @@ -181,8 +181,8 @@ BOOL CCAlfrescoAppApp::InitInstance() * @param params DesktopParams& * @return bool */ -bool CCAlfrescoAppApp::buildDesktopParameters( AlfrescoInterface& alfresco, StringList& paths, AlfrescoActionInfo& actionInfo, - DesktopParams& params) { +bool CAlfrescoApp::buildDesktopParameters( AlfrescoInterface& alfresco, StringList& paths, AlfrescoActionInfo& actionInfo, + DesktopParams& params) { // If there are no paths then just return a success @@ -401,7 +401,7 @@ bool CCAlfrescoAppApp::buildDesktopParameters( AlfrescoInterface& alfresco, Stri * @param aborted bool& * @return bool */ -bool CCAlfrescoAppApp::copyFilesUsingShell(const String& fromFileFolder, const String& toFolder, bool& aborted) { +bool CAlfrescoApp::copyFilesUsingShell(const String& fromFileFolder, const String& toFolder, bool& aborted) { // Build the from/to paths, must be double null terminated @@ -456,7 +456,7 @@ bool CCAlfrescoAppApp::copyFilesUsingShell(const String& fromFileFolder, const S * @param actionInfo AlfrescoActionInfo& * @return bool */ -bool CCAlfrescoAppApp::runAction( AlfrescoInterface& alfresco, StringList& pathList, AlfrescoActionInfo& actionInfo) { +bool CAlfrescoApp::runAction( AlfrescoInterface& alfresco, StringList& pathList, AlfrescoActionInfo& actionInfo) { // Build the desktop action parameter list, perform any file copying of local files @@ -484,24 +484,9 @@ bool CCAlfrescoAppApp::runAction( AlfrescoInterface& alfresco, StringList& pathL if ( response.getStatus() == StsCommandLine) { - // Initialize the startup information - - STARTUPINFO startupInfo; - memset(&startupInfo, 0, sizeof(STARTUPINFO)); - // Launch a process using the command line - PROCESS_INFORMATION processInfo; - memset(&processInfo, 0, sizeof(PROCESS_INFORMATION)); - - if ( CreateProcess( response.getStatusMessage().data(), NULL, NULL, NULL, true, 0, NULL, NULL, - &startupInfo, &processInfo) == false) { - CString msg; - msg.FormatMessage( L"Failed to launch command line\n\n%1\n\nError %2!d!", response.getStatusMessage().data(), GetLastError()); - AfxMessageBox( msg, MB_OK | MB_ICONERROR); - } - else - sts = true; + sts = doCommandLine( alfresco, response.getStatusMessage()); } // Check if a web browser should be launched with a URL @@ -510,14 +495,7 @@ bool CCAlfrescoAppApp::runAction( AlfrescoInterface& alfresco, StringList& pathL // Use the Windows shell to open the URL - HINSTANCE shellSts = ShellExecute( NULL, NULL, response.getStatusMessage().data(), NULL, NULL, SW_SHOWNORMAL); - if (( int) shellSts < 32) { - CString msg; - msg.FormatMessage( L"Failed to launch URL\n\n%1", response.getStatusMessage().data()); - AfxMessageBox( msg, MB_OK | MB_ICONERROR); - } - else - sts = true; + sts = doURL( alfresco, response.getStatusMessage()); } // Error status @@ -572,3 +550,168 @@ bool CCAlfrescoAppApp::runAction( AlfrescoInterface& alfresco, StringList& pathL return sts; } + +/** + * Launch a command line + * + * @param alfresco AlfrescoInterface& + * @param cmdStr const String& + * @return bool + */ +bool CAlfrescoApp::doCommandLine( AlfrescoInterface& alfresco, const String& cmdStr) { + + // Check if the command line contains any environment variables/tokens + + String cmdLine = cmdStr; + int pos = cmdLine.indexOf( L'%'); + + if ( pos != -1) { + + // Command line contains environment variables or other tokens that must be replaced + + String newCmdLine = L""; + if (pos > 0) + newCmdLine = cmdLine.substring( 0, pos); + + wchar_t envBuf[256]; + size_t envLen; + + while ( pos != -1) { + + // Find the end of the current token + + int endPos = cmdLine.indexOf ( L'%', pos + 1); + + if ( endPos == -1) { + CString msg; + msg.FormatMessage( L"Bad token in command line\n\n%1", cmdLine.data()); + AfxMessageBox( msg, MB_OK | MB_ICONERROR); + + return false; + } + + // Extract the token + + String token = cmdLine.substring( pos + 1, endPos); + + // Replace the token with an environment variable value or other values + + if ( token.equals( L"AlfrescoDir")) { + + // Use the local path to the Alfresco folder that the application is running from + + newCmdLine.append( alfresco.getUNCPath()); + } + else { + + // Find the environment variable value + + envLen = sizeof( envBuf)/sizeof(wchar_t); + const wchar_t* pEnvName = token.data(); + + if ( _wgetenv_s( &envLen, envBuf, envLen, pEnvName) == 0) { + + // Append the environment variable value + + newCmdLine.append( envBuf); + } + else { + + // Error converting the environment variable + + CString msg; + msg.FormatMessage( L"Failed to convert environment variable\n\n%1\n\n%2", token.data(), cmdLine.data()); + AfxMessageBox( msg, MB_OK | MB_ICONERROR); + + return false; + } + } + + // Update the token search position + + pos = endPos + 1; + + if (( unsigned int) pos < cmdStr.length()) { + + // Search for the next token + + pos = cmdLine.indexOf( L'%', pos); + } + else { + + // End of string, finish the token search + + pos = -1; + } + + // Append the normal string between tokens + + if ( pos > (endPos + 1)) { + + // Get the between token sting + + String filler = cmdLine.substring( endPos + 1, pos); + newCmdLine.append( filler); + } + else if ( pos == -1) { + + // Append the remaining string + + String filler = cmdLine.substring( endPos + 1); + newCmdLine.append( filler); + } + } + + // Update the command line + + cmdLine = newCmdLine; + } + + // Initialize the startup information + + STARTUPINFO startupInfo; + memset(&startupInfo, 0, sizeof(STARTUPINFO)); + + // Launch a process using the command line + + PROCESS_INFORMATION processInfo; + memset(&processInfo, 0, sizeof(PROCESS_INFORMATION)); + + bool sts = false; + + if ( CreateProcess( NULL, (LPWSTR) cmdLine.data(), NULL, NULL, true, 0, NULL, NULL, + &startupInfo, &processInfo) == false) { + CString msg; + msg.FormatMessage( L"Failed to launch command line\n\n%1\n\nError %2!d!", cmdLine.data(), GetLastError()); + AfxMessageBox( msg, MB_OK | MB_ICONERROR); + } + else + sts = true; + + return sts; +} + +/** + * Browse to a URL + * + * @param alfresco AlfrescoInterface& + * @param url const String& + * @return bool + */ +bool CAlfrescoApp::doURL( AlfrescoInterface& alfresco, const String& url) { + + // Use the Windows shell to open the URL + + bool sts = false; + + HINSTANCE shellSts = ShellExecute( NULL, NULL, url.data(), NULL, NULL, SW_SHOWNORMAL); + if (( int) shellSts < 32) { + CString msg; + msg.FormatMessage( L"Failed to launch URL\n\n%1", url.data()); + AfxMessageBox( msg, MB_OK | MB_ICONERROR); + } + else + sts = true; + + return sts; +} diff --git a/source/cpp/CAlfrescoApp/CAlfrescoApp.h b/source/cpp/CAlfrescoApp/CAlfrescoApp.h index 39ac0c6018..590ac23244 100644 --- a/source/cpp/CAlfrescoApp/CAlfrescoApp.h +++ b/source/cpp/CAlfrescoApp/CAlfrescoApp.h @@ -30,14 +30,14 @@ using namespace Alfresco; -// CCAlfrescoAppApp: +// CAlfrescoApp: // See CAlfrescoApp.cpp for the implementation of this class // -class CCAlfrescoAppApp : public CWinApp +class CAlfrescoApp : public CWinApp { public: - CCAlfrescoAppApp(); + CAlfrescoApp(); // Overrides public: @@ -59,6 +59,11 @@ private: // Run the action bool runAction( AlfrescoInterface& alfresco, StringList& pathList, AlfrescoActionInfo& actionInfo); + + // Post-process actions, command line launch and browse to URL + + bool doCommandLine( AlfrescoInterface& alfresco, const String& cmdLine); + bool doURL( AlfrescoInterface& alfresco, const String& url); }; -extern CCAlfrescoAppApp theApp; \ No newline at end of file +extern CAlfrescoApp theApp; \ No newline at end of file diff --git a/source/cpp/CAlfrescoApp/source/util/String.cpp b/source/cpp/CAlfrescoApp/source/util/String.cpp index 27ddbe069d..3723818db3 100644 --- a/source/cpp/CAlfrescoApp/source/util/String.cpp +++ b/source/cpp/CAlfrescoApp/source/util/String.cpp @@ -676,7 +676,8 @@ void String::append ( const char* str) { * @param str const wchar_t* */ void String::append (const wchar_t* str) { - m_string += str; + while ( *str != 0) + m_string += *str++; } /** diff --git a/source/java/org/alfresco/filesys/smb/server/repo/desk/CheckInOutDesktopAction.java b/source/java/org/alfresco/filesys/smb/server/repo/desk/CheckInOutDesktopAction.java index 0f98e425e3..fe39a6b277 100644 --- a/source/java/org/alfresco/filesys/smb/server/repo/desk/CheckInOutDesktopAction.java +++ b/source/java/org/alfresco/filesys/smb/server/repo/desk/CheckInOutDesktopAction.java @@ -113,6 +113,11 @@ public class CheckInOutDesktopAction extends DesktopAction { } catch (Exception ex) { + // Dump the error + + if ( logger.isErrorEnabled()) + logger.error("Desktop action error", ex); + // Return an error status and message response.setStatus(StsError, "Checkin failed for " + target.getTarget() + ", " + ex.getMessage()); @@ -122,6 +127,19 @@ public class CheckInOutDesktopAction extends DesktopAction { { try { + // Check if the file is locked + + if ( getNodeService().hasAspect( target.getNode(), ContentModel.ASPECT_LOCKABLE)) { + + // Get the lock type + + String lockTypeStr = (String) getNodeService().getProperty( target.getNode(), ContentModel.PROP_LOCK_TYPE); + if ( lockTypeStr != null) { + response.setStatus(StsError, "Checkout failed, file is locked"); + return response; + } + } + // Check out the file NodeRef workingCopyNode = getCheckInOutService().checkout( target.getNode()); @@ -149,6 +167,11 @@ public class CheckInOutDesktopAction extends DesktopAction { } catch (Exception ex) { + // Dump the error + + if ( logger.isErrorEnabled()) + logger.error("Desktop action error", ex); + // Return an error status and message response.setStatus(StsError, "Failed to checkout " + target.getTarget() + ", " + ex.getMessage()); diff --git a/source/java/org/alfresco/filesys/smb/server/repo/desk/CmdLineDesktopAction.java b/source/java/org/alfresco/filesys/smb/server/repo/desk/CmdLineDesktopAction.java index 6744204fdf..42625ea6a2 100644 --- a/source/java/org/alfresco/filesys/smb/server/repo/desk/CmdLineDesktopAction.java +++ b/source/java/org/alfresco/filesys/smb/server/repo/desk/CmdLineDesktopAction.java @@ -47,6 +47,6 @@ public class CmdLineDesktopAction extends DesktopAction { // Return a URL in the status message - return new DesktopResponse(StsCommandLine, "C:\\Windows\\notepad.exe"); + return new DesktopResponse(StsCommandLine, "%SystemRoot%\\notepad.exe"); } }