1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 #if defined(_MSC_VER) && (_MSC_VER >= 1400) 28 #pragma warning(disable:4740) 29 #endif 30 31 #include "macros.h" 32 33 #ifdef __cplusplus 34 #define local inline 35 #else 36 #define local static 37 #endif 38 39 local LPCWSTR SkipBlanks( LPCWSTR lpScan ) 40 { 41 while ( ' ' == *lpScan || '\t' == *lpScan ) 42 lpScan++; 43 44 return lpScan; 45 } 46 47 48 local LPCWSTR SkipArgument( LPCWSTR lpScan ) 49 { 50 BOOL fQuoted = FALSE; 51 LPCWSTR lpArgEnd = NULL; 52 53 do 54 { 55 switch ( *lpScan ) 56 { 57 case ' ': 58 case '\t': 59 if ( fQuoted ) 60 lpScan++; 61 else 62 lpArgEnd = lpScan; 63 break; 64 case '\"': 65 lpScan++; 66 fQuoted = !fQuoted; 67 break; 68 case '\0': 69 lpArgEnd = lpScan; 70 break; 71 default: 72 lpScan++; 73 break; 74 } 75 } while( *lpScan && !lpArgEnd ); 76 77 return lpScan; 78 } 79 80 81 IMPLEMENT_THUNK( shell32, WINDOWS, LPWSTR *, WINAPI, CommandLineToArgvW, ( LPCWSTR lpCmdLineW, int *pNumArgs ) ) 82 { 83 LPWSTR *lpArgvW = NULL; 84 85 if ( !lpCmdLineW || !*lpCmdLineW ) 86 { 87 CHAR szFileName[MAX_PATH]; 88 89 DWORD dwResult = GetModuleFileNameA( NULL, szFileName, MAX_PATH ); 90 91 if ( dwResult && dwResult < MAX_PATH ) 92 { 93 int cchNeeded = MultiByteToWideChar( CP_ACP, 0, szFileName, -1, NULL, 0 ); 94 95 lpArgvW = (LPWSTR *)GlobalAlloc( 0, cchNeeded * sizeof(WCHAR) + sizeof(LPWSTR) ); 96 97 if ( lpArgvW ) 98 { 99 lpArgvW[0] = (LPWSTR)(lpArgvW + 1); 100 101 MultiByteToWideChar( CP_ACP, 0, szFileName, -1, lpArgvW[0], cchNeeded ); 102 *pNumArgs = 1; 103 } 104 else 105 SetLastError( ERROR_OUTOFMEMORY ); 106 } 107 } 108 else 109 { 110 LPCWSTR lpScan = lpCmdLineW; 111 int nTokens = 0; 112 int cchNeeded = 0; 113 114 // Count arguments and required size 115 116 while ( *lpScan ) 117 { 118 lpScan = SkipBlanks( lpScan ); 119 if ( *lpScan ) 120 { 121 LPCWSTR lpArgEnd = SkipArgument( lpScan ); 122 123 nTokens++; 124 cchNeeded += lpArgEnd - lpScan + 1; 125 lpScan = lpArgEnd; 126 } 127 } 128 129 // Allocate space for one additional NULL pointer to terminate list 130 131 lpArgvW = (LPWSTR *)GlobalAlloc( 0, sizeof(LPWSTR) * (nTokens + 1) + sizeof(WCHAR) * cchNeeded ); 132 133 if ( lpArgvW ) 134 { 135 // Collect arguments 136 137 LPWSTR lpDestination = (LPWSTR)&lpArgvW[nTokens + 1]; 138 139 lpScan = lpCmdLineW; 140 nTokens = 0; 141 142 while ( *lpScan ) 143 { 144 lpScan = SkipBlanks( lpScan ); 145 if ( *lpScan ) 146 { 147 LPCWSTR lpArgEnd = SkipArgument( lpScan ); 148 149 lpArgvW[nTokens++] = lpDestination; 150 151 while ( lpScan < lpArgEnd ) 152 { 153 if ( '\"' != *lpScan ) 154 *lpDestination++ = *lpScan; 155 156 lpScan++; 157 } 158 *lpDestination++ = 0; 159 } 160 } 161 162 lpArgvW[nTokens] = NULL; 163 164 *pNumArgs = nTokens; 165 } 166 else 167 SetLastError( ERROR_OUTOFMEMORY ); 168 169 } 170 171 return lpArgvW; 172 }