diff --git a/source/cpp/CAlfrescoApp/CAlfrescoApp.aps b/source/cpp/CAlfrescoApp/CAlfrescoApp.aps index 8e5c213a85..34c423008b 100644 Binary files a/source/cpp/CAlfrescoApp/CAlfrescoApp.aps and b/source/cpp/CAlfrescoApp/CAlfrescoApp.aps differ diff --git a/source/cpp/CAlfrescoApp/CAlfrescoApp.cpp b/source/cpp/CAlfrescoApp/CAlfrescoApp.cpp index d20ed61c55..4362c84821 100644 --- a/source/cpp/CAlfrescoApp/CAlfrescoApp.cpp +++ b/source/cpp/CAlfrescoApp/CAlfrescoApp.cpp @@ -18,13 +18,13 @@ #include "stdafx.h" #include "CAlfrescoApp.h" #include "CAlfrescoAppDlg.h" -#include "FileStatusDialog.h" #include #include "util\String.h" #include "util\DataBuffer.h" #include "util\FileName.h" +#include "util\Integer.h" #include @@ -82,6 +82,7 @@ BOOL CCAlfrescoAppApp::InitInstance() // Get the path to the folder containing the application String folderPath = appPath.substring(0, pos); + String exeName = appPath.substring(pos + 1); // Create the Alfresco interface @@ -90,27 +91,69 @@ BOOL CCAlfrescoAppApp::InitInstance() try { - // If there are no file paths on the command line then display a status page for the files - // in the Alfresco folder + // Get the action information - if ( __argc == 1) { + AlfrescoActionInfo actionInfo = alfresco.getActionInformation(exeName); - // Display status for the files in the Alfresco folder + // Check if the action should be confirmed - doFolderStatus( alfresco); + if ( actionInfo.hasPreProcessAction(PreConfirmAction)) { + + // Get the confirmation message + + String confirmMsg = actionInfo.getConfirmationMessage(); + if ( confirmMsg.length() == 0) + confirmMsg = L"Run action ?"; + + // Display a confirmation dialog + + if ( AfxMessageBox( confirmMsg, MB_OKCANCEL | MB_ICONQUESTION) == IDCANCEL) + return FALSE; } - else { - // Build a list of the file names + // Check if the action supports multiple paths, if not then call the action once for each supplied path - StringList fileList; + if ( actionInfo.hasAttribute(AttrMultiplePaths)) { + + // Build a list of paths from the command line arguments + + StringList pathList; for ( int i = 1; i < __argc; i++) - fileList.addString( String(__wargv[i])); + pathList.addString( String(__wargv[i])); - // Process the file list and check in or out each file + // Run the action - doCheckInOut( alfresco, fileList); + runAction( alfresco, pathList, actionInfo); + } + + // Check if the action supports file/folder targets + + else if ( actionInfo.hasAttribute( AttrAnyFilesFolders) == true) { + + // Pass one path at a time to the action + + for ( int i = 1; i < __argc; i++) { + + // Create a path list with a single path + + StringList pathList; + pathList.addString( String(__wargv[i])); + + // Run the action + + runAction( alfresco, pathList, actionInfo); + } + } + + // Action does not use targets, just run the action + + else { + + // Run the action + + StringList emptyList; + runAction( alfresco, emptyList, actionInfo); } } catch (Exception ex) { @@ -124,128 +167,36 @@ BOOL CCAlfrescoAppApp::InitInstance() return 1; } - // Run the main dialog -/** - CCAlfrescoAppDlg dlg; - m_pMainWnd = &dlg; - INT_PTR nResponse = dlg.DoModal(); - if (nResponse == IDOK) - { - // TODO: Place code here to handle when the dialog is - // dismissed with OK - } - else if (nResponse == IDCANCEL) - { - // TODO: Place code here to handle when the dialog is - // dismissed with Cancel - } -**/ + // Exit the application - // Since the dialog has been closed, return FALSE so that we exit the - // application, rather than start the application's message pump. return FALSE; } /** - * Display file status of the files in the target Alfresco folder - * - * @param AlfrescoInterface& alfresco - * @param const wchar_t* fileSpec - * @return bool - */ -bool CCAlfrescoAppApp::doFolderStatus( AlfrescoInterface& alfresco, const wchar_t* fileSpec) { - - // Get the base UNC path - - String uncPath = alfresco.getUNCPath(); - uncPath.append(PathSeperator); - - // Search the Alfresco folder - - WIN32_FIND_DATA findData; - String searchPath = uncPath; - searchPath.append( fileSpec); - - bool sts = false; - HANDLE fHandle = FindFirstFile( searchPath, &findData); - AlfrescoFileInfoList fileList; - - if ( fHandle != INVALID_HANDLE_VALUE) { - - // Loop until all files have been returned - - PTR_AlfrescoFileInfo pFileInfo; - sts = true; - - while ( fHandle != INVALID_HANDLE_VALUE) { - - // Get the file name, ignore the '.' and '..' files - - String fName = findData.cFileName; - - if ( fName.equals(L".") || fName.equals(L"..")) { - - // Get the next file/folder name in the search - - if ( FindNextFile( fHandle, &findData) == 0) - fHandle = INVALID_HANDLE_VALUE; - continue; - } - - // Get the file information for the current file folder - - pFileInfo = alfresco.getFileInformation( findData.cFileName); - - if ( pFileInfo.get() != NULL) { - - // Add the file to the list - - fileList.addInfo( pFileInfo); - } - - // Get the next file/folder name in the search - - if ( FindNextFile( fHandle, &findData) == 0) - fHandle = INVALID_HANDLE_VALUE; - } - } - - // Display the file status dialog if there are files to display - - if ( fileList.size() > 0) { - - // Display the file status dialog - - CFileStatusDialog dlg( fileList); - dlg.DoModal(); - } - else { - CString msg; - msg.FormatMessage( L"No files found in %1", uncPath.data()); - AfxMessageBox( msg, MB_OK | MB_ICONINFORMATION); - } - - // Return status - - return sts; -} - -/** - * Process the list of files and check in or out each file + * Process the command line arguments and build the parameter list for the desktop action * * @param alfresco AlfrescoInterface& - * @param files StringList& + * @param paths StringList& + * @param actionInfo AlfrescoActionInfo& + * @param params DesktopParams& + * @return bool */ -bool CCAlfrescoAppApp::doCheckInOut( AlfrescoInterface& alfresco, StringList& files) { +bool CCAlfrescoAppApp::buildDesktopParameters( AlfrescoInterface& alfresco, StringList& paths, AlfrescoActionInfo& actionInfo, + DesktopParams& params) { + + // If there are no paths then just return a success + + if ( paths.numberOfStrings() == 0) + return true; // Process the list of files and either check in the file if it is a working copy or check out // the file - for ( unsigned int i = 0; i < files.numberOfStrings(); i++) { + for ( unsigned int i = 0; i < paths.numberOfStrings(); i++) { // Get the current file name - String curFile = files.getStringAt( i); + String curFile = paths.getStringAt( i); // Check if the path is on an Alfresco mapped drive @@ -259,171 +210,181 @@ bool CCAlfrescoAppApp::doCheckInOut( AlfrescoInterface& alfresco, StringList& fi curFile = uncPath; } - // Check that the path is to a file + // Check if the path is to a file/folder, and whether it is a local path bool copyFile = false; - DWORD attr = GetFileAttributes( curFile); - if ( attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY) == 0) { + + if ( attr != INVALID_FILE_ATTRIBUTES) { + + // Check if the action supports the file/folder type + + bool isDir = (attr & FILE_ATTRIBUTE_DIRECTORY) != 0 ? true : false; + + if ( isDir && actionInfo.supportsFolders() == false) { + AfxMessageBox(L"Action does not support folders", MB_OK | MB_ICONSTOP); + return false; + } + else if ( actionInfo.supportsFiles() == false) { + AfxMessageBox(L"Action does not support files", MB_OK | MB_ICONSTOP); + return false; + } // Get the file name from the path StringList nameParts = FileName::splitPath( curFile); String curName = nameParts.getStringAt( 1); - // Get the Alfresco file status information - - PTR_AlfrescoFileInfo pFileInfo = alfresco.getFileInformation( curName); - // If the path is to a file that is not on the Alfresco share the file will need to be copied, // after checking the status of a matching file in the Alfresco folder if ( curFile.length() >= 3 && curFile.substring(1,3).equals( L":\\")) { - // Check if there is an existing file with the same name + // Check if the action supports local files - if ( pFileInfo.get() != NULL) { + if ( isDir == false && actionInfo.hasAttribute(AttrClientFiles) == false) { + AfxMessageBox(L"Action does not support local files", MB_OK | MB_ICONSTOP); + return false; + } + else if ( isDir == true && actionInfo.hasAttribute(AttrClientFolders) == false) { + AfxMessageBox(L"Action does not support local folders", MB_OK | MB_ICONSTOP); + return false; + } - // Check if the file is a working copy + // Check if there is an existing file in the Alfresco with the same name, check if the file is locked + + PTR_AlfrescoFileInfo fInfo = alfresco.getFileInformation( curName); + if ( fInfo.get() != NULL) { - if ( pFileInfo->isWorkingCopy()) { + // There is an existing file in the Alfresco folder with the same name, check if it is locked - // Local file matches a working copy file in the Alfresco folder - - CString msg; - msg.FormatMessage( L"Found matching working copy for local file %1", curName.data()); - AfxMessageBox( msg, MB_OK | MB_ICONINFORMATION); + if ( fInfo->getLockType() != LockNone) { + AfxMessageBox( L"Cannot copy file to Alfresco folder, destination file is locked", MB_OK | MB_ICONEXCLAMATION); + return false; } - else if ( pFileInfo->getLockType() != LockNone) { + else if ( actionInfo.hasPreProcessAction(PreLocalToWorkingCopy) == true && fInfo->isWorkingCopy() == false) { + AfxMessageBox( L"Cannot copy to Alfresco folder, destination must overwrite a working copy", MB_OK | MB_ICONEXCLAMATION); + return false; + } + } + else if ( actionInfo.hasPreProcessAction(PreLocalToWorkingCopy) == true) { - // File is locked, may be the original document + // Target folder does not contain a matching working copy of the local file + + CString msg; + msg.FormatMessage( L"No matching working copy for %1", curName.data()); + AfxMessageBox( msg, MB_OK | MB_ICONEXCLAMATION); + return false; + } + + // Copy the files/folders using the Windows shell + + bool copyAborted = false; + + if ( copyFilesUsingShell( curFile, alfresco.getUNCPath(), copyAborted) == false) { + + // Check if the copy failed or the user aborted the copy + + if ( copyAborted == false) { + + // File copy failed CString msg; - msg.FormatMessage( L"Destination file %1 is locked", curName.data()); + msg.FormatMessage( isDir ? L"Failed to copy folder %1" : L"Failed to copy file %1", curFile.data()); + AfxMessageBox( msg, MB_OK | MB_ICONSTOP); return false; } else { - // Indicate that we have copied a new file to the Alfresco share, do not check in/out + // User aborted the file copy - copyFile = true; + CString msg; + msg.FormatMessage( L"Copy aborted for %1", curFile.data()); + AfxMessageBox( msg, MB_OK | MB_ICONSTOP); + return false; } } - else { - // Indicate that we have copied a new file to the Alfresco share, do not check in/out + // Add a desktop target for the copied file - copyFile = true; - } - - // Build the from/to paths, must be double null terminated - - wchar_t fromPath[MAX_PATH + 1]; - wchar_t toPath[MAX_PATH + 1]; - - memset( fromPath, 0, sizeof( fromPath)); - memset( toPath, 0, sizeof( toPath)); - - wcscpy( fromPath, curFile.data()); - wcscpy( toPath, alfresco.getUNCPath()); - - // Copy the local file to the Alfresco folder - - SHFILEOPSTRUCT fileOpStruct; - memset( &fileOpStruct, 0, sizeof(SHFILEOPSTRUCT)); - - fileOpStruct.hwnd = HWND_DESKTOP; - fileOpStruct.wFunc = FO_COPY; - fileOpStruct.pFrom = fromPath; - fileOpStruct.pTo = toPath; - fileOpStruct.fFlags= 0; - fileOpStruct.fAnyOperationsAborted =false; - - // Copy the file to the Alfresco folder - - if ( SHFileOperation( &fileOpStruct) != 0) { - - // File copy failed - - CString msg; - msg.FormatMessage( L"Failed to copy file %1", curFile.data()); - AfxMessageBox( msg, MB_OK | MB_ICONSTOP); - return false; - } - else if ( fileOpStruct.fAnyOperationsAborted) { - - // User aborted the file copy - - CString msg; - msg.FormatMessage( L"Copy aborted for %1", curFile.data()); - AfxMessageBox( msg, MB_OK | MB_ICONSTOP); - return false; - } - - // Get the file information for the copied file - - pFileInfo = alfresco.getFileInformation( curName); + params.addTarget( new DesktopTarget(isDir ? TargetCopiedFolder : TargetCopiedFile, curName)); } + else { - // Check in or check out the file + // Path is a UNC path, check if the file/folder is in the same folder as the action - if ( pFileInfo.get() != NULL) { + DesktopTarget* pTarget = NULL; - // Check if the file should be checked in/out + if ( curFile.startsWith( alfresco.getUNCPath())) { - if ( copyFile == false) { + // Path is in the same folder as the application, or in a sub-folder - // Check if the file is a working copy, if so then check it in + String relPath = curFile.substring( alfresco.getUNCPath().length() + 1); - if ( pFileInfo->isWorkingCopy()) { + if ( relPath.indexOf( L"\\") == -1) { - // Check in the file + // Create a target using the file name only - doCheckIn( alfresco, pFileInfo); + pTarget = new DesktopTarget( isDir ? TargetFolder : TargetFile, relPath); } - else if ( pFileInfo->getLockType() == LockNone) { + } - // Check out the file + // If the target is not valid the file/folder is not in the same folder as the client-side application, + // copy the files/folders to the target folder or use the root relative path to the file/folder - doCheckOut( alfresco, pFileInfo); + if ( pTarget == NULL) { + + // Check if Alfresco files/folders should be copied to the target folder + + if ( actionInfo.hasPreProcessAction(PreCopyToTarget)) { + + // Copy the files/folders using the Windows shell + + bool copyAborted = false; + + if ( copyFilesUsingShell( curFile, alfresco.getUNCPath(), copyAborted) == false) { + + // Check if the copy failed or the user aborted the copy + + if ( copyAborted == false) { + + // File copy failed + + CString msg; + msg.FormatMessage( isDir ? L"Failed to copy folder %1" : L"Failed to copy file %1", curFile.data()); + + AfxMessageBox( msg, MB_OK | MB_ICONSTOP); + return false; + } + else { + + // User aborted the file copy + + CString msg; + msg.FormatMessage( L"Copy aborted for %1", curFile.data()); + AfxMessageBox( msg, MB_OK | MB_ICONSTOP); + return false; + } + } + + // Add a desktop target for the copied file + + pTarget= new DesktopTarget(isDir ? TargetCopiedFolder : TargetCopiedFile, curName); } else { - // File is locked, may already be checked out + // Get the root relative path to the file/folder - CString msg; - msg.FormatMessage( L"File %1 is locked", curFile.data()); - AfxMessageBox( msg, MB_OK | MB_ICONSTOP); + String rootRelPath = curFile.substring(alfresco.getRootPath().length()); + pTarget = new DesktopTarget( isDir ? TargetFolder : TargetFile, rootRelPath); } } - else { - // No existing file to link the copied file to - - CString msg; - msg.FormatMessage( L"Copied file %1 to Alfresco folder", curFile.data()); - AfxMessageBox( msg, MB_OK | MB_ICONINFORMATION); - } + // Add the desktop target + params.addTarget( pTarget); } - else { - CString msg; - msg.FormatMessage( L"Failed to get file status for %1", curFile.data()); - AfxMessageBox( msg, MB_OK | MB_ICONSTOP); - } - } - else { - - // Check the error status - - CString msg; - - if ( attr != INVALID_FILE_ATTRIBUTES) - msg.FormatMessage( L"Path %1 is a folder, ignored", curFile.data()); - else - msg.FormatMessage( L"File %1 does not exist", curFile.data()); - AfxMessageBox( msg, MB_OK | MB_ICONSTOP); } } @@ -433,74 +394,174 @@ bool CCAlfrescoAppApp::doCheckInOut( AlfrescoInterface& alfresco, StringList& fi } /** - * Check in the specified file + * Copy a file/folder using the Windows shell * - * @param alfresco AlfrescoInterface& - * @param pFileInfo PTR_AlfrescoFileInfo& + * @param fromFileFolder const String& + * @param toFolder const String& + * @param aborted bool& * @return bool */ -bool CCAlfrescoAppApp::doCheckIn( AlfrescoInterface& alfresco, PTR_AlfrescoFileInfo& pFileInfo) { +bool CCAlfrescoAppApp::copyFilesUsingShell(const String& fromFileFolder, const String& toFolder, bool& aborted) { - bool checkedIn = false; + // Build the from/to paths, must be double null terminated - try { + wchar_t fromPath[MAX_PATH + 1]; + wchar_t toPath[MAX_PATH + 1]; - // Check in the specified file + memset( fromPath, 0, sizeof( fromPath)); + memset( toPath, 0, sizeof( toPath)); - alfresco.checkIn( pFileInfo->getName()); + wcscpy( fromPath, fromFileFolder.data()); + wcscpy( toPath, toFolder.data()); - CString msg; - msg.FormatMessage( L"Checked in file %1", pFileInfo->getName().data()); - AfxMessageBox( msg, MB_OK | MB_ICONINFORMATION); + // Copy the local file to the Alfresco folder - // Indicate that the check in was successful + SHFILEOPSTRUCT fileOpStruct; + memset( &fileOpStruct, 0, sizeof(SHFILEOPSTRUCT)); - checkedIn = true; + fileOpStruct.hwnd = HWND_DESKTOP; + fileOpStruct.wFunc = FO_COPY; + fileOpStruct.pFrom = fromPath; + fileOpStruct.pTo = toPath; + fileOpStruct.fFlags= 0; + fileOpStruct.fAnyOperationsAborted =false; + + // Copy the file to the Alfresco folder + + bool sts = false; + + if ( SHFileOperation( &fileOpStruct) == 0) { + + // File copy successful + + sts = true; } - catch (Exception ex) { - CString msg; - msg.FormatMessage( L"Error checking in file %1\n\n%2", pFileInfo->getName().data(), ex.getMessage().data()); - AfxMessageBox( msg, MB_OK | MB_ICONSTOP); + else if ( fileOpStruct.fAnyOperationsAborted) { + + // User aborted the file copy + + aborted = true; } - // Return the check in status + // Return the copy status - return checkedIn; + return sts; } /** - * Check out the specified file + * Run an action * * @param alfresco AlfrescoInterface& - * @param pFileInfo PTR_AlfrescoFileInfo& + * @param pathList StringList& + * @param actionInfo AlfrescoActionInfo& * @return bool */ -bool CCAlfrescoAppApp::doCheckOut( AlfrescoInterface& alfresco, PTR_AlfrescoFileInfo& pFileInfo) { +bool CCAlfrescoAppApp::runAction( AlfrescoInterface& alfresco, StringList& pathList, AlfrescoActionInfo& actionInfo) { - bool checkedOut = false; + // Build the desktop action parameter list, perform any file copying of local files - try { + bool sts = false; + DesktopParams desktopParams; + + if ( buildDesktopParameters( alfresco, pathList, actionInfo, desktopParams)) { - // Check out the specified file + // Run the desktop action - String workingCopy; - alfresco.checkOut( pFileInfo->getName(), workingCopy); + DesktopResponse response = alfresco.runAction( actionInfo, desktopParams); - CString msg; - msg.FormatMessage( L"Checked out file %1 to %2", pFileInfo->getName().data(), workingCopy.data()); - AfxMessageBox( msg, MB_OK | MB_ICONINFORMATION); + // Check the response status - // Indicate that the check out was successful + if ( response.getStatus() != StsSuccess) { - checkedOut = true; - } - catch (Exception ex) { - CString msg; - msg.FormatMessage( L"Error checking out file %1\n\n%2", pFileInfo->getName().data(), ex.getMessage().data()); - AfxMessageBox( msg, MB_OK | MB_ICONSTOP); + // Check if the status indicates a command line should be launched + + 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; + } + + // Check if a web browser should be launched with a URL + + else if ( response.getStatus() == StsLaunchURL) { + + // 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; + } + + // Error status + + else { + + // Get the error message + + String errMsg; + + switch ( response.getStatus()) { + case StsFileNotFound: + errMsg = L"File not found"; + break; + case StsAccessDenied: + errMsg = L"Access denied"; + break; + case StsBadParameter: + errMsg = L"Bad parameter in request"; + break; + case StsNoSuchAction: + errMsg = L"No such action"; + break; + default: + errMsg = L"Error running action"; + break; + } + + // Display an error dialog + + CString msg; + + if ( response.hasStatusMessage()) + msg.FormatMessage( L"%1\n\n%2", errMsg.data(), response.getStatusMessage().data()); + else + msg = errMsg.data(); + + AfxMessageBox( msg, MB_OK | MB_ICONERROR); + } + } + else if ( response.hasStatusMessage()) { + + // Display the message returned by the action + + CString msg; + msg.FormatMessage( L"Action returned message\n\n%1", response.getStatusMessage().data()); + AfxMessageBox( msg, MB_OK | MB_ICONINFORMATION); + } } - // Return the check out status + // Return the action status - return checkedOut; + return sts; } diff --git a/source/cpp/CAlfrescoApp/CAlfrescoApp.h b/source/cpp/CAlfrescoApp/CAlfrescoApp.h index 2a5c21b646..39ac0c6018 100644 --- a/source/cpp/CAlfrescoApp/CAlfrescoApp.h +++ b/source/cpp/CAlfrescoApp/CAlfrescoApp.h @@ -26,6 +26,7 @@ // Includes #include "alfresco\Alfresco.hpp" +#include "alfresco\Desktop.hpp" using namespace Alfresco; @@ -49,10 +50,15 @@ public: private: // Main Alfresco interface functions - bool doFolderStatus( AlfrescoInterface& alfresco, const wchar_t* fileSpec = L"*.*"); - bool doCheckInOut( AlfrescoInterface& alfresco, StringList& files); - bool doCheckIn( AlfrescoInterface& alfresco, PTR_AlfrescoFileInfo& fileInfo); - bool doCheckOut( AlfrescoInterface& alfresco, PTR_AlfrescoFileInfo& fileInfo); + bool buildDesktopParameters( AlfrescoInterface& alfresco, StringList& paths, AlfrescoActionInfo& actionInfo, DesktopParams& params); + + // Copy files/folders using the Windows shell + + bool copyFilesUsingShell(const String& fromPath, const String& toPath, bool& aborted); + + // Run the action + + bool runAction( AlfrescoInterface& alfresco, StringList& pathList, AlfrescoActionInfo& actionInfo); }; extern CCAlfrescoAppApp theApp; \ No newline at end of file diff --git a/source/cpp/CAlfrescoApp/CAlfrescoApp.ncb b/source/cpp/CAlfrescoApp/CAlfrescoApp.ncb index 39edd3a847..04bbbb3bed 100644 Binary files a/source/cpp/CAlfrescoApp/CAlfrescoApp.ncb and b/source/cpp/CAlfrescoApp/CAlfrescoApp.ncb differ diff --git a/source/cpp/CAlfrescoApp/CAlfrescoApp.rc b/source/cpp/CAlfrescoApp/CAlfrescoApp.rc index b7dde5c0e6..ce5908d0ca 100644 --- a/source/cpp/CAlfrescoApp/CAlfrescoApp.rc +++ b/source/cpp/CAlfrescoApp/CAlfrescoApp.rc @@ -27,29 +27,25 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // IDD_ABOUTBOX DIALOGEX 0, 0, 235, 55 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | - WS_SYSMENU +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "About CAlfrescoApp" FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN ICON 128,IDC_STATIC,11,17,20,20 - LTEXT "CAlfrescoApp Version 1.0",IDC_STATIC,40,10,119,8, - SS_NOPREFIX + LTEXT "CAlfrescoApp Version 1.0",IDC_STATIC,40,10,119,8,SS_NOPREFIX LTEXT "Copyright (C) 2005",IDC_STATIC,40,25,119,8 DEFPUSHBUTTON "OK",IDOK,178,7,50,16,WS_GROUP END IDD_CALFRESCOAPP_DIALOG DIALOGEX 0, 0, 469, 156 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | - WS_CAPTION | WS_SYSMENU +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_APPWINDOW CAPTION "Alfresco Check In/Out" FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN PUSHBUTTON "OK",IDOK,209,130,50,13 LTEXT "Checked in 99 files",IDC_MSGTEXT,25,22,418,8 - LISTBOX IDC_FILELIST,23,38,424,83,LBS_SORT | - LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + LISTBOX IDC_FILELIST,23,38,424,83,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP END @@ -83,13 +79,13 @@ BEGIN BLOCK "040904e4" BEGIN VALUE "CompanyName", "Alfresco" - VALUE "FileDescription", "Alfresco Check In/Out" - VALUE "FileVersion", "1.0.0.1" + VALUE "FileDescription", "Alfresco Drag And Drop" + VALUE "FileVersion", "1.0.0.2" VALUE "InternalName", "CAlfrescoApp.exe" VALUE "LegalCopyright", "(c) Alfresco. All rights reserved." VALUE "OriginalFilename", "CAlfrescoApp.exe" VALUE "ProductName", "Alfresco" - VALUE "ProductVersion", "1.0.0.1" + VALUE "ProductVersion", "1.0.0.2" END END BLOCK "VarFileInfo" @@ -149,6 +145,40 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK #pragma code_page(1252) #endif //_WIN32 +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_FILESTATUS DIALOGEX 0, 0, 448, 332 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Alfresco File Status" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,391,311,50,14 + CONTROL "",IDC_FILELIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,7,434,299 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_FILESTATUS, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 441 + TOPMARGIN, 7 + BOTTOMMARGIN, 325 + END +END +#endif // APSTUDIO_INVOKED + + #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // @@ -193,42 +223,6 @@ END // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. IDI_ICON1 ICON "alfresco.ico" - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_FILESTATUS DIALOGEX 0, 0, 448, 332 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | - WS_SYSMENU -CAPTION "Alfresco File Status" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - DEFPUSHBUTTON "OK",IDOK,391,311,50,14 - CONTROL "",IDC_FILELIST,"SysListView32",LVS_REPORT | - LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,7,434,299 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_FILESTATUS, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 441 - TOPMARGIN, 7 - BOTTOMMARGIN, 325 - END -END -#endif // APSTUDIO_INVOKED - #endif // English (U.K.) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/source/cpp/CAlfrescoApp/CAlfrescoApp.sln b/source/cpp/CAlfrescoApp/CAlfrescoApp.sln index 655f0d3159..a7e2ec537a 100644 --- a/source/cpp/CAlfrescoApp/CAlfrescoApp.sln +++ b/source/cpp/CAlfrescoApp/CAlfrescoApp.sln @@ -1,21 +1,19 @@ -Microsoft Visual Studio Solution File, Format Version 8.00 +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CAlfrescoApp", "CAlfrescoApp.vcproj", "{055DCC85-2D1A-4594-B2BE-ED292D2BF26D}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection EndProject Global - GlobalSection(SolutionConfiguration) = preSolution - Debug = Debug - Release = Release + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 EndGlobalSection - GlobalSection(ProjectConfiguration) = postSolution - {055DCC85-2D1A-4594-B2BE-ED292D2BF26D}.Debug.ActiveCfg = Debug|Win32 - {055DCC85-2D1A-4594-B2BE-ED292D2BF26D}.Debug.Build.0 = Debug|Win32 - {055DCC85-2D1A-4594-B2BE-ED292D2BF26D}.Release.ActiveCfg = Release|Win32 - {055DCC85-2D1A-4594-B2BE-ED292D2BF26D}.Release.Build.0 = Release|Win32 + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {055DCC85-2D1A-4594-B2BE-ED292D2BF26D}.Debug|Win32.ActiveCfg = Debug|Win32 + {055DCC85-2D1A-4594-B2BE-ED292D2BF26D}.Debug|Win32.Build.0 = Debug|Win32 + {055DCC85-2D1A-4594-B2BE-ED292D2BF26D}.Release|Win32.ActiveCfg = Release|Win32 + {055DCC85-2D1A-4594-B2BE-ED292D2BF26D}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - EndGlobalSection - GlobalSection(ExtensibilityAddIns) = postSolution + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE EndGlobalSection EndGlobal diff --git a/source/cpp/CAlfrescoApp/CAlfrescoApp.suo b/source/cpp/CAlfrescoApp/CAlfrescoApp.suo index 75201f26f0..80b78368a5 100644 Binary files a/source/cpp/CAlfrescoApp/CAlfrescoApp.suo and b/source/cpp/CAlfrescoApp/CAlfrescoApp.suo differ diff --git a/source/cpp/CAlfrescoApp/CAlfrescoApp.vcproj b/source/cpp/CAlfrescoApp/CAlfrescoApp.vcproj index 371ce42ead..2561157e99 100644 --- a/source/cpp/CAlfrescoApp/CAlfrescoApp.vcproj +++ b/source/cpp/CAlfrescoApp/CAlfrescoApp.vcproj @@ -1,127 +1,191 @@ + Keyword="MFCProj" + > + Name="Win32" + /> + + + CharacterSet="1" + > + + + + + + Detect64BitPortabilityProblems="true" + DebugInformationFormat="4" + /> + Name="VCManagedResourceCompilerTool" + /> + + + TargetMachine="1" + /> + Name="VCALinkTool" + /> + Name="VCManifestTool" + /> + Name="VCXDCMakeTool" + /> + Name="VCBscMakeTool" + /> + Name="VCFxCopTool" + /> + Name="VCAppVerifierTool" + /> + Name="VCWebDeploymentTool" + /> - - + Name="VCPostBuildEventTool" + /> + CharacterSet="1" + > + + + + + + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + Name="VCManagedResourceCompilerTool" + /> + + + TargetMachine="1" + /> + Name="VCALinkTool" + /> + Name="VCManifestTool" + /> + Name="VCXDCMakeTool" + /> + Name="VCBscMakeTool" + /> + Name="VCFxCopTool" + /> + Name="VCAppVerifierTool" + /> + Name="VCWebDeploymentTool" + /> - - + Name="VCPostBuildEventTool" + /> @@ -130,165 +194,227 @@ + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + RelativePath=".\CAlfrescoApp.cpp" + > + RelativePath=".\CAlfrescoAppDlg.cpp" + > - - + RelativePath=".\stdafx.cpp" + > + Name="Debug|Win32" + > + UsePrecompiledHeader="1" + /> + Name="Release|Win32" + > + UsePrecompiledHeader="1" + /> + > + RelativePath=".\source\util\ByteArray.cpp" + > + RelativePath=".\source\util\DataBuffer.cpp" + > + RelativePath=".\source\util\DataPacker.cpp" + > + RelativePath=".\source\util\Exception.cpp" + > + RelativePath=".\source\util\FileName.cpp" + > + RelativePath=".\source\util\Integer.cpp" + > + RelativePath=".\source\util\Long.cpp" + > + RelativePath=".\source\util\String.cpp" + > + RelativePath=".\source\util\System.cpp" + > + > + RelativePath=".\source\alfresco\Alfresco.cpp" + > + + + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + RelativePath=".\CAlfrescoApp.h" + > + RelativePath=".\CAlfrescoAppDlg.h" + > + RelativePath=".\Resource.h" + > - - + RelativePath=".\stdafx.h" + > + > + RelativePath=".\includes\util\ByteArray.h" + > + RelativePath=".\includes\util\DataBuffer.h" + > + RelativePath=".\includes\util\DataPacker.h" + > + RelativePath=".\includes\util\Exception.h" + > + RelativePath=".\includes\util\FileName.h" + > + RelativePath=".\includes\util\Integer.h" + > + RelativePath=".\includes\util\JavaTypes.h" + > + RelativePath=".\includes\util\Long.h" + > + RelativePath=".\includes\util\String.h" + > + RelativePath=".\includes\util\System.h" + > + RelativePath=".\includes\util\Types.h" + > + > + RelativePath=".\includes\alfresco\Alfresco.hpp" + > + + + UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}" + > + RelativePath=".\alfresco.ico" + > + RelativePath=".\res\CAlfrescoApp.ico" + > + RelativePath=".\CAlfrescoApp.rc" + > + RelativePath=".\res\CAlfrescoApp.rc2" + > + DeploymentContent="true" + > + RelativePath=".\res\CAlfrescoApp.manifest" + > + + + + + + + RelativePath=".\ReadMe.txt" + > + Value="CAlfrescoApp.rc" + /> diff --git a/source/cpp/CAlfrescoApp/FileStatusDialog.cpp b/source/cpp/CAlfrescoApp/FileStatusDialog.cpp deleted file mode 100644 index cddeaf4344..0000000000 --- a/source/cpp/CAlfrescoApp/FileStatusDialog.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2005-2006 Alfresco, Inc. - * - * Licensed under the Mozilla Public License version 1.1 - * with a permitted attribution clause. You may obtain a - * copy of the License at - * - * http://www.alfresco.org/legal/license.txt - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the specific - * language governing permissions and limitations under the - * License. - */ - -#include "stdafx.h" -#include "CAlfrescoApp.h" -#include "FileStatusDialog.h" - -#include "util\Long.h" - -// CFileStatusDialog dialog - -IMPLEMENT_DYNAMIC(CFileStatusDialog, CDialog) -CFileStatusDialog::CFileStatusDialog(AlfrescoFileInfoList& fileList, CWnd* pParent /*=NULL*/) - : CDialog(CFileStatusDialog::IDD, pParent), - m_fileList( fileList) -{ -} - -CFileStatusDialog::~CFileStatusDialog() -{ -} - -void CFileStatusDialog::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - DDX_Control(pDX, IDC_FILELIST, m_listCtrl); -} - - -BEGIN_MESSAGE_MAP(CFileStatusDialog, CDialog) -END_MESSAGE_MAP() - -/** - * Initialize the dialog - */ -BOOL CFileStatusDialog::OnInitDialog() { - - // Call the base class - - CDialog::OnInitDialog(); - - // Add headers to the list control - - m_listCtrl.InsertColumn( 0, L"Name", LVCFMT_LEFT, 200); - m_listCtrl.InsertColumn( 1, L"Mime-type", LVCFMT_LEFT, 140); - m_listCtrl.InsertColumn( 2, L"Size", LVCFMT_RIGHT, 80); - m_listCtrl.InsertColumn( 3, L"Status", LVCFMT_LEFT, 100); - m_listCtrl.InsertColumn( 4, L"Owner", LVCFMT_LEFT, 100); - - // Add the list view data - - for ( unsigned int i = 0; i < m_fileList.size(); i++) { - - // Get the current file information - - const AlfrescoFileInfo* pInfo = m_fileList.getInfoAt( i); - - // Add the item to the list view - - if ( pInfo != NULL) { - - // Insert a new item in the view - - int nIndex = m_listCtrl.InsertItem( 0, pInfo->getName()); - - if ( pInfo->isType() == TypeFile) { - - // Display the mime-type and content length - - m_listCtrl.SetItemText( nIndex, 1, pInfo->getContentType()); - m_listCtrl.SetItemText( nIndex, 2, Long::toString( pInfo->getContentLength())); - - String status; - String owner; - - if ( pInfo->isWorkingCopy()) { - status = L"Work"; - } - else if ( pInfo->getLockType() != LockNone) { - status = L"Locked"; - owner = pInfo->getLockOwner(); - } - - m_listCtrl.SetItemText( nIndex, 3, status); - m_listCtrl.SetItemText( nIndex, 4, owner); - } - } - } - - // Clear the file info list - - m_fileList.clear(); - - return FALSE; -} - -// CFileStatusDialog message handlers diff --git a/source/cpp/CAlfrescoApp/FileStatusDialog.h b/source/cpp/CAlfrescoApp/FileStatusDialog.h deleted file mode 100644 index 3864e1c1dd..0000000000 --- a/source/cpp/CAlfrescoApp/FileStatusDialog.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2005-2006 Alfresco, Inc. - * - * Licensed under the Mozilla Public License version 1.1 - * with a permitted attribution clause. You may obtain a - * copy of the License at - * - * http://www.alfresco.org/legal/license.txt - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, - * either express or implied. See the License for the specific - * language governing permissions and limitations under the - * License. - */ - -#pragma once -#include "afxcmn.h" - -#include "alfresco\Alfresco.hpp" - -// CFileStatusDialog dialog - -class CFileStatusDialog : public CDialog -{ - DECLARE_DYNAMIC(CFileStatusDialog) - -public: - CFileStatusDialog( AlfrescoFileInfoList& fileList, CWnd* pParent = NULL); // standard constructor - virtual ~CFileStatusDialog(); - -// Dialog Data - enum { IDD = IDD_FILESTATUS }; - - // Initialize the dialog - - BOOL OnInitDialog(); - -protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - - DECLARE_MESSAGE_MAP() - CListCtrl m_listCtrl; - -protected: - // File information list - - AlfrescoFileInfoList& m_fileList; -}; diff --git a/source/cpp/CAlfrescoApp/FileStatusView.cpp b/source/cpp/CAlfrescoApp/FileStatusView.cpp deleted file mode 100644 index 2b552204ce..0000000000 --- a/source/cpp/CAlfrescoApp/FileStatusView.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// FileStatusView.cpp : implementation file -// - -#include "stdafx.h" -#include "CAlfrescoApp.h" -#include "FileStatusView.h" - - -// CFileStatusView - -IMPLEMENT_DYNCREATE(CFileStatusView, CListView) - -CFileStatusView::CFileStatusView() -{ -} - -CFileStatusView::~CFileStatusView() -{ -} - -BEGIN_MESSAGE_MAP(CFileStatusView, CListView) -END_MESSAGE_MAP() - - -// CFileStatusView diagnostics - -#ifdef _DEBUG -void CFileStatusView::AssertValid() const -{ - CListView::AssertValid(); -} - -void CFileStatusView::Dump(CDumpContext& dc) const -{ - CListView::Dump(dc); -} -#endif //_DEBUG - - -// CFileStatusView message handlers diff --git a/source/cpp/CAlfrescoApp/FileStatusView.h b/source/cpp/CAlfrescoApp/FileStatusView.h deleted file mode 100644 index 066f367e55..0000000000 --- a/source/cpp/CAlfrescoApp/FileStatusView.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - - -// CFileStatusView view - -class CFileStatusView : public CListView -{ - DECLARE_DYNCREATE(CFileStatusView) - -protected: - CFileStatusView(); // protected constructor used by dynamic creation - virtual ~CFileStatusView(); - -public: -#ifdef _DEBUG - virtual void AssertValid() const; - virtual void Dump(CDumpContext& dc) const; -#endif - -protected: - DECLARE_MESSAGE_MAP() -}; - - diff --git a/source/cpp/CAlfrescoApp/includes/alfresco/Alfresco.hpp b/source/cpp/CAlfrescoApp/includes/alfresco/Alfresco.hpp index 49d076414b..0bce50c321 100644 --- a/source/cpp/CAlfrescoApp/includes/alfresco/Alfresco.hpp +++ b/source/cpp/CAlfrescoApp/includes/alfresco/Alfresco.hpp @@ -25,17 +25,22 @@ #include #include + #include "util\Exception.h" #include "util\String.h" #include "util\DataBuffer.h" +#include "alfresco\Desktop.hpp" + // Classes defined in this header file namespace Alfresco { class AlfrescoInterface; class AlfrescoFileInfo; class AlfrescoFileInfoList; + class AlfrescoActionInfo; typedef std::auto_ptr PTR_AlfrescoFileInfo; + typedef std::auto_ptr PTR_AlfrescoActionInfo; } // Constants @@ -44,10 +49,12 @@ namespace Alfresco { // Alfresco I/O control codes - #define FSCTL_ALFRESCO_PROBE CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) - #define FSCTL_ALFRESCO_FILESTS CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS) - #define FSCTL_ALFRESCO_CHECKOUT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x802, METHOD_BUFFERED, FILE_WRITE_DATA) - #define FSCTL_ALFRESCO_CHECKIN CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x803, METHOD_BUFFERED, FILE_WRITE_DATA) + #define FSCTL_ALFRESCO_PROBE CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) + #define FSCTL_ALFRESCO_FILESTS CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS) + // Version 1 FSCTL_ALFRESCO_CHECKOUT - 0x802 + // Version 1 FSCTL_ALFRESCO_CHECKIN - 0x803 + #define FSCTL_ALFRESCO_GETACTIONINFO CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x804, METHOD_BUFFERED, FILE_WRITE_DATA) + #define FSCTL_ALFRESCO_RUNACTION CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 0x805, METHOD_BUFFERED, FILE_WRITE_DATA) // Request signature bytes @@ -68,6 +75,9 @@ namespace Alfresco { #define StsAccessDenied 3 #define StsBadParameter 4 #define StsNotWorkingCopy 5 + #define StsNoSuchAction 6 + #define StsLaunchURL 7 + #define StsCommandLine 8 // Boolean field values @@ -86,6 +96,26 @@ namespace Alfresco { #define LockNone 0 #define LockRead 1 #define LockWrite 2 + + // Desktop action attributes + + #define AttrTargetFiles 0x0001 + #define AttrTargetFolders 0x0002 + #define AttrClientFiles 0x0004 + #define AttrClientFolders 0x0008 + #define AttrAlfrescoFiles 0x0010 + #define AttrAlfrescoFolders 0x0020 + #define AttrMultiplePaths 0x0040 + + #define AttrAnyFiles (AttrTargetFiles + AttrClientFiles + AttrAlfrescoFiles) + #define AttrAnyFolders (AttrTargetFolders + AttrClientFolders + AttrAlfrescoFolders) + #define AttrAnyFilesFolders (AttrAnyFiles + AttrAnyFolders) + + // Desktop action pre-processing actions + + #define PreCopyToTarget 0x0001 + #define PreConfirmAction 0x0002 + #define PreLocalToWorkingCopy 0x0004 } // Define Alfresco interface exceptions @@ -122,17 +152,21 @@ public: bool isAlfrescoFolder( void); + // Return the protocol version of the server + + inline const unsigned int isProtocolVersion( void) const { return m_protocolVersion; } + // Return the Alfresco file information for a file/folder within the current folder PTR_AlfrescoFileInfo getFileInformation(const wchar_t* fileName); - // Check in a working copy file + // Get action information, map the executable name to a server action - void checkIn( const wchar_t* fileName, bool keepCheckedOut = false); + AlfrescoActionInfo getActionInformation(const wchar_t* exeName); - // Check out a file + // Run a desktop action and return the server response - void checkOut( const wchar_t* fileName, String& workingCopy); + DesktopResponse runAction(AlfrescoActionInfo& action, DesktopParams& params); private: // Send an I/O control request, receive and validate the response @@ -160,6 +194,9 @@ private: HANDLE m_handle; + // Protocol version + + unsigned int m_protocolVersion; }; /** @@ -292,4 +329,82 @@ private: std::vector m_list; }; +/** + * Alfresco Action Info Class + */ +class Alfresco::AlfrescoActionInfo { +public: + // Default constructor + + AlfrescoActionInfo(void); + + // Class constructor + + AlfrescoActionInfo( const String& name, const unsigned int attr, const unsigned int preActions); + + // Return the action name, pseudo file name + + inline const String& getName(void) const { return m_name; } + inline const String& getPseudoName(void) const { return m_pseudoName; } + + // Return the action attributes, action pre-processing flags + + inline unsigned int getAttributes(void) const { return m_attributes; } + inline unsigned int getPreProcessActions(void) const { return m_clientPreActions; } + + // Check if the action has the specifed attribute/pre-processing action + + inline bool hasAttribute(const unsigned int attr) const { return (m_attributes & attr) != 0 ? true : false; } + inline bool hasPreProcessAction(const unsigned int pre) const { return (m_clientPreActions & pre) != 0 ? true : false; } + + // Check if the confirmation message is valid, return the confirmation message + + inline bool hasConfirmationMessage(void) const { return m_confirmMsg.length() > 0 ? true : false; } + inline const String& getConfirmationMessage(void) const { return m_confirmMsg; } + + // Check if the action supports file or folder paths + + inline bool supportsFiles(void) const { return hasAttribute(AttrTargetFiles+AttrClientFiles+AttrAlfrescoFiles); } + inline bool supportsFolders(void) const { return hasAttribute(AttrTargetFolders+AttrClientFolders+AttrAlfrescoFolders); } + + // Set the action name, pseudo name, set the confirmation message + + inline void setName(const String& name) { m_name = name; } + inline void setPseudoName(const String& pseudo) { m_pseudoName = pseudo; } + inline void setConfirmationMessage(const String& msg) { m_confirmMsg = msg; } + + // Set the action attributes and pre-processing actions + + inline void setAttributes(const unsigned int attr) { m_attributes = attr; } + inline void setPreProcessActions(const unsigned int pre) { m_clientPreActions = pre; } + + // Return the action information as a string + + const String toString(void) const; + + // Assignment operator + + AlfrescoActionInfo& operator=( const AlfrescoActionInfo& actionInfo); + +private: + // Instance variables + // + // Action name + + String m_name; + + // Pseudo file name + + String m_pseudoName; + + // Action attributes and pre-processing flags + + unsigned int m_attributes; + unsigned int m_clientPreActions; + + // Action confirmation message + + String m_confirmMsg; +}; + #endif diff --git a/source/cpp/CAlfrescoApp/source/alfresco/Alfresco.cpp b/source/cpp/CAlfrescoApp/source/alfresco/Alfresco.cpp index ae0cbe6f7f..31f08bcf3e 100644 --- a/source/cpp/CAlfrescoApp/source/alfresco/Alfresco.cpp +++ b/source/cpp/CAlfrescoApp/source/alfresco/Alfresco.cpp @@ -40,6 +40,10 @@ AlfrescoInterface::AlfrescoInterface(String& path) { m_handle = INVALID_HANDLE_VALUE; + // Default the protocol version + + m_protocolVersion = 1; + // Check if the path is to a mapped drive String alfPath = path; @@ -136,8 +140,17 @@ bool AlfrescoInterface::isAlfrescoFolder( void) { bool alfFolder = false; try { + + // Check if the remote server is an Alfresco CIFS server + sendIOControl( FSCTL_ALFRESCO_PROBE, reqbuf, respbuf); alfFolder = true; + + // Get the protocol version, if available + + respbuf.getInt(); // status + if ( respbuf.getAvailableLength() >= 4) + m_protocolVersion = respbuf.getInt(); } catch ( Exception ex) { } @@ -229,102 +242,102 @@ PTR_AlfrescoFileInfo AlfrescoInterface::getFileInformation( const wchar_t* fileN } /** - * Check in a working copy file - * - * @param fileName const wchar_t* - * @param keepCheckedOut bool - */ -void AlfrescoInterface::checkIn( const wchar_t* fileName, bool keepCheckedOut) { +* Return Alfresco action information for the specified executable +* +* @param fileName const wchar_t* +* @return AlfrescoActionInfo +*/ +AlfrescoActionInfo AlfrescoInterface::getActionInformation( const wchar_t* exeName) { // Check if the folder handle is valid if ( m_handle == INVALID_HANDLE_VALUE) throw BadInterfaceException(); - // Build the file information I/O control request + // Build the action information I/O control request DataBuffer reqbuf( 256); - DataBuffer respbuf( 128); + DataBuffer respbuf( 512); reqbuf.putFixedString( IOSignature, IOSignatureLen); - reqbuf.putString( fileName); - reqbuf.putInt( keepCheckedOut ? True : False); + reqbuf.putString( exeName); - sendIOControl( FSCTL_ALFRESCO_CHECKIN, reqbuf, respbuf); + sendIOControl( FSCTL_ALFRESCO_GETACTIONINFO, reqbuf, respbuf); - // Get the status code + // Unpack the request status - unsigned int stsCode = respbuf.getInt(); - if ( stsCode == StsSuccess) - return; - else { + AlfrescoActionInfo actionInfo; - // Get the error message, if available + unsigned int reqSts = respbuf.getInt(); + if ( reqSts == StsSuccess) { - String errMsg; + // Unpack the action name, attributes and pre-action flags - if ( respbuf.getAvailableLength() > 0) - errMsg = respbuf.getString(); - else { - errMsg = "Error code "; - errMsg.append( Integer::toString( stsCode)); - } + String name = respbuf.getString(); + unsigned int attr = respbuf.getInt(); + unsigned int preActions = respbuf.getInt(); + String confirmMsg = respbuf.getString(); - // Throw an exception + // Create the action information - throw Exception( errMsg); + actionInfo.setName(name); + actionInfo.setAttributes(attr); + actionInfo.setPreProcessActions(preActions); + actionInfo.setPseudoName( exeName); + actionInfo.setConfirmationMessage( confirmMsg); } + + // Return the action information + + return actionInfo; } /** - * Check out a file and return the working copy file name + * Run a desktop action * - * @param fileName const wchar_t* - * @param workingCopy String& + * @param action AlfrescoActionInfo& + * @param params DesktopParams& + * @return DesktopResponse */ -void AlfrescoInterface::checkOut( const wchar_t* fileName, String& workingCopy) { +DesktopResponse AlfrescoInterface::runAction(AlfrescoActionInfo& action, DesktopParams& params) { // Check if the folder handle is valid if ( m_handle == INVALID_HANDLE_VALUE) throw BadInterfaceException(); - // Build the file information I/O control request + // Build the run action I/O control request - DataBuffer reqbuf( 256); + DataBuffer reqbuf( 1024); DataBuffer respbuf( 256); reqbuf.putFixedString( IOSignature, IOSignatureLen); - reqbuf.putString( fileName); + reqbuf.putString( action.getName()); + reqbuf.putInt((unsigned int)params.numberOfTargets()); - sendIOControl( FSCTL_ALFRESCO_CHECKOUT, reqbuf, respbuf); + for ( unsigned int i = 0; i < params.numberOfTargets(); i++) { - // Get the status code + // Pack the current target details - unsigned int stsCode = respbuf.getInt(); - if ( stsCode == StsSuccess) { + const DesktopTarget* pTarget = params.getTarget(i); - // Get the working copy file name - - workingCopy = respbuf.getString(); + reqbuf.putInt(pTarget->isType()); + reqbuf.putString(pTarget->getTarget()); } - else { - // Get the error message, if available + // Send the run action request - String errMsg; + sendIOControl( FSCTL_ALFRESCO_RUNACTION, reqbuf, respbuf); - if ( respbuf.getAvailableLength() > 0) - errMsg = respbuf.getString(); - else { - errMsg = "Error code "; - errMsg.append( Integer::toString( stsCode)); - } + // Unpack the run action response - // Throw an exception + unsigned int actionSts = respbuf.getInt(); + String actionMsg = respbuf.getString(); - throw Exception( errMsg); - } + // Return the desktop response + + DesktopResponse response(actionSts, actionMsg); + return response; } /** @@ -439,3 +452,67 @@ bool AlfrescoFileInfo::operator<( const AlfrescoFileInfo& finfo) { return true; return false; } + +/** + * Default constructor + */ +AlfrescoActionInfo::AlfrescoActionInfo(void) { + m_attributes = 0; + m_clientPreActions = 0; +} + +/** + * Class constructor + * + * @param name const String& + * @param attr const unsigned int + * @param preActions const unsigned int + */ +AlfrescoActionInfo::AlfrescoActionInfo( const String& name, const unsigned int attr, const unsigned int preActions) { + m_name = name; + m_attributes = attr; + m_clientPreActions = preActions; +} + +/** + * Return the action information as a string + * + * @return const String + */ +const String AlfrescoActionInfo::toString(void) const { + String str = L"["; + + str.append(getName()); + str.append(L":"); + str.append(getPseudoName()); + str.append(L":Attr=0x"); + str.append(Integer::toHexString(getAttributes())); + str.append(L":preActions=0x"); + str.append(Integer::toHexString(getPreProcessActions())); + + if ( hasConfirmationMessage()) { + str.append(L":Conf="); + str.append(getConfirmationMessage()); + } + str.append(L"]"); + + return str; +} + +/** + * Assignment operator + * + * @param actionInfo const AlfrescoActionInfo& + * @return AlfrescoActionInfo& + */ +AlfrescoActionInfo& AlfrescoActionInfo::operator=( const AlfrescoActionInfo& actionInfo) { + setName(actionInfo.getName()); + setPseudoName(actionInfo.getPseudoName()); + + setAttributes(actionInfo.getAttributes()); + setPreProcessActions(actionInfo.getPreProcessActions()); + + setConfirmationMessage(actionInfo.getConfirmationMessage()); + + return *this; +} diff --git a/source/cpp/CAlfrescoApp/source/util/Integer.cpp b/source/cpp/CAlfrescoApp/source/util/Integer.cpp index 4013f6f57d..9259296a1d 100644 --- a/source/cpp/CAlfrescoApp/source/util/Integer.cpp +++ b/source/cpp/CAlfrescoApp/source/util/Integer.cpp @@ -27,7 +27,7 @@ using namespace Alfresco; */ String Integer::toHexString( const unsigned int ival) { char buf[32]; - itoa(ival, buf, 16); + _itoa(ival, buf, 16); return String(buf); } @@ -52,7 +52,7 @@ String Integer::toHexString( BUFPTR ptr) { */ String Integer::toString( unsigned int ival, unsigned int radix) { char buf[32]; - itoa(ival, buf, radix); + _itoa(ival, buf, radix); return String(buf); } diff --git a/source/cpp/CAlfrescoApp/source/util/String.cpp b/source/cpp/CAlfrescoApp/source/util/String.cpp index 148cdcb65d..27ddbe069d 100644 --- a/source/cpp/CAlfrescoApp/source/util/String.cpp +++ b/source/cpp/CAlfrescoApp/source/util/String.cpp @@ -695,7 +695,7 @@ void String::append (const String& str) { */ void String::append (const unsigned int ival) { wchar_t buf[32]; - swprintf( buf, L"%u", ival); + swprintf( buf, 32, L"%u", ival); m_string += buf; } @@ -707,7 +707,7 @@ void String::append (const unsigned int ival) { */ void String::append (const unsigned long lval) { wchar_t buf[32]; - swprintf( buf, L"%lu", lval); + swprintf( buf, 32, L"%lu", lval); m_string += buf; } @@ -719,7 +719,7 @@ void String::append (const unsigned long lval) { */ void String::append (const LONG64 l64val) { wchar_t buf[32]; - swprintf( buf, L"%I64u", l64val); + swprintf( buf, 32, L"%I64u", l64val); m_string += buf; }