1 /* 2 * Copyright 2000 Juergen Schmied 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 17 */ 18 19 #define WIN32_NO_STATUS 20 #define _INC_WINDOWS 21 #define NONAMELESSUNION 22 #define NONAMELESSSTRUCT 23 24 #include <windef.h> 25 #include <winbase.h> 26 #include <shlobj.h> 27 #include <shlwapi.h> 28 #include <undocshell.h> 29 #include <shlwapi_undoc.h> 30 #include <wine/unicode.h> 31 #include <wine/debug.h> 32 33 #include "shell32_main.h" 34 35 WINE_DEFAULT_DEBUG_CHANNEL(shell); 36 37 /************************* STRRET functions ****************************/ 38 39 static const char *debugstr_strret(STRRET *s) 40 { 41 switch (s->uType) 42 { 43 case STRRET_WSTR: 44 return "STRRET_WSTR"; 45 case STRRET_CSTR: 46 return "STRRET_CSTR"; 47 case STRRET_OFFSET: 48 return "STRRET_OFFSET"; 49 default: 50 return "STRRET_???"; 51 } 52 } 53 54 BOOL WINAPI StrRetToStrNA(LPSTR dest, DWORD len, LPSTRRET src, const ITEMIDLIST *pidl) 55 { 56 TRACE("dest=%p len=0x%x strret=%p(%s) pidl=%p\n", dest, len, src, debugstr_strret(src), pidl); 57 58 if (!dest) 59 return FALSE; 60 61 switch (src->uType) 62 { 63 case STRRET_WSTR: 64 WideCharToMultiByte(CP_ACP, 0, src->u.pOleStr, -1, dest, len, NULL, NULL); 65 CoTaskMemFree(src->u.pOleStr); 66 break; 67 case STRRET_CSTR: 68 lstrcpynA(dest, src->u.cStr, len); 69 break; 70 case STRRET_OFFSET: 71 lstrcpynA(dest, ((LPCSTR)&pidl->mkid)+src->u.uOffset, len); 72 break; 73 default: 74 FIXME("unknown type %u!\n", src->uType); 75 if (len) 76 *dest = '\0'; 77 return FALSE; 78 } 79 TRACE("-- %s\n", debugstr_a(dest) ); 80 return TRUE; 81 } 82 83 /************************************************************************/ 84 85 BOOL WINAPI StrRetToStrNW(LPWSTR dest, DWORD len, LPSTRRET src, const ITEMIDLIST *pidl) 86 { 87 TRACE("dest=%p len=0x%x strret=%p(%s) pidl=%p\n", dest, len, src, debugstr_strret(src), pidl); 88 89 if (!dest) 90 return FALSE; 91 92 switch (src->uType) 93 { 94 case STRRET_WSTR: 95 lstrcpynW(dest, src->u.pOleStr, len); 96 CoTaskMemFree(src->u.pOleStr); 97 break; 98 case STRRET_CSTR: 99 if (!MultiByteToWideChar(CP_ACP, 0, src->u.cStr, -1, dest, len) && len) 100 dest[len-1] = 0; 101 break; 102 case STRRET_OFFSET: 103 if (!MultiByteToWideChar(CP_ACP, 0, ((LPCSTR)&pidl->mkid)+src->u.uOffset, -1, dest, len) 104 && len) 105 dest[len-1] = 0; 106 break; 107 default: 108 FIXME("unknown type %u!\n", src->uType); 109 if (len) 110 *dest = '\0'; 111 return FALSE; 112 } 113 return TRUE; 114 } 115 116 117 /************************************************************************* 118 * StrRetToStrN [SHELL32.96] 119 * 120 * converts a STRRET to a normal string 121 * 122 * NOTES 123 * the pidl is for STRRET OFFSET 124 */ 125 BOOL WINAPI StrRetToStrNAW(LPVOID dest, DWORD len, LPSTRRET src, const ITEMIDLIST *pidl) 126 { 127 if(SHELL_OsIsUnicode()) 128 return StrRetToStrNW(dest, len, src, pidl); 129 else 130 return StrRetToStrNA(dest, len, src, pidl); 131 } 132 133 /************************* OLESTR functions ****************************/ 134 135 /************************************************************************ 136 * StrToOleStr [SHELL32.163] 137 * 138 */ 139 static int StrToOleStrA (LPWSTR lpWideCharStr, LPCSTR lpMultiByteString) 140 { 141 TRACE("(%p, %p %s)\n", 142 lpWideCharStr, lpMultiByteString, debugstr_a(lpMultiByteString)); 143 144 return MultiByteToWideChar(CP_ACP, 0, lpMultiByteString, -1, lpWideCharStr, MAX_PATH); 145 146 } 147 static int StrToOleStrW (LPWSTR lpWideCharStr, LPCWSTR lpWString) 148 { 149 TRACE("(%p, %p %s)\n", 150 lpWideCharStr, lpWString, debugstr_w(lpWString)); 151 152 strcpyW (lpWideCharStr, lpWString ); 153 return strlenW(lpWideCharStr); 154 } 155 156 BOOL WINAPI StrToOleStrAW (LPWSTR lpWideCharStr, LPCVOID lpString) 157 { 158 if (SHELL_OsIsUnicode()) 159 return StrToOleStrW (lpWideCharStr, lpString); 160 return StrToOleStrA (lpWideCharStr, lpString); 161 } 162 163 /************************************************************************* 164 * StrToOleStrN [SHELL32.79] 165 * lpMulti, nMulti, nWide [IN] 166 * lpWide [OUT] 167 */ 168 static BOOL StrToOleStrNA (LPWSTR lpWide, INT nWide, LPCSTR lpStrA, INT nStr) 169 { 170 TRACE("(%p, %x, %s, %x)\n", lpWide, nWide, debugstr_an(lpStrA,nStr), nStr); 171 return MultiByteToWideChar (CP_ACP, 0, lpStrA, nStr, lpWide, nWide); 172 } 173 static BOOL StrToOleStrNW (LPWSTR lpWide, INT nWide, LPCWSTR lpStrW, INT nStr) 174 { 175 TRACE("(%p, %x, %s, %x)\n", lpWide, nWide, debugstr_wn(lpStrW, nStr), nStr); 176 177 if (lstrcpynW (lpWide, lpStrW, nWide)) 178 { return lstrlenW (lpWide); 179 } 180 return FALSE; 181 } 182 183 BOOL WINAPI StrToOleStrNAW (LPWSTR lpWide, INT nWide, LPCVOID lpStr, INT nStr) 184 { 185 if (SHELL_OsIsUnicode()) 186 return StrToOleStrNW (lpWide, nWide, lpStr, nStr); 187 return StrToOleStrNA (lpWide, nWide, lpStr, nStr); 188 } 189 190 /************************************************************************* 191 * OleStrToStrN [SHELL32.78] 192 */ 193 static BOOL OleStrToStrNA (LPSTR lpStr, INT nStr, LPCWSTR lpOle, INT nOle) 194 { 195 TRACE("(%p, %x, %s, %x)\n", lpStr, nStr, debugstr_wn(lpOle,nOle), nOle); 196 return WideCharToMultiByte (CP_ACP, 0, lpOle, nOle, lpStr, nStr, NULL, NULL); 197 } 198 199 static BOOL OleStrToStrNW (LPWSTR lpwStr, INT nwStr, LPCWSTR lpOle, INT nOle) 200 { 201 TRACE("(%p, %x, %s, %x)\n", lpwStr, nwStr, debugstr_wn(lpOle,nOle), nOle); 202 203 if (lstrcpynW ( lpwStr, lpOle, nwStr)) 204 { return lstrlenW (lpwStr); 205 } 206 return FALSE; 207 } 208 209 BOOL WINAPI OleStrToStrNAW (LPVOID lpOut, INT nOut, LPCVOID lpIn, INT nIn) 210 { 211 if (SHELL_OsIsUnicode()) 212 return OleStrToStrNW (lpOut, nOut, lpIn, nIn); 213 return OleStrToStrNA (lpOut, nOut, lpIn, nIn); 214 } 215 216 217 /************************************************************************* 218 * CheckEscapesA [SHELL32.@] 219 * 220 * Checks a string for special characters which are not allowed in a path 221 * and encloses it in quotes if that is the case. 222 * 223 * PARAMS 224 * string [I/O] string to check and on return eventually quoted 225 * len [I] length of string 226 */ 227 VOID WINAPI CheckEscapesA( 228 LPSTR string, /* [I/O] string to check ??*/ 229 DWORD len) /* [I] is 0 */ 230 { 231 LPWSTR wString; 232 TRACE("(%s %d)\n", debugstr_a(string), len); 233 234 if (!string || !string[0]) 235 return; 236 237 wString = LocalAlloc(LPTR, len * sizeof(WCHAR)); 238 if (!wString) 239 return; 240 241 SHAnsiToUnicode(string, wString, len); 242 CheckEscapesW(wString, len); 243 SHUnicodeToAnsi(wString, string, len); 244 LocalFree(wString); 245 } 246 247 /************************************************************************* 248 * CheckEscapesW [SHELL32.@] 249 * 250 * See CheckEscapesA. 251 */ 252 VOID WINAPI CheckEscapesW( 253 LPWSTR string, 254 DWORD len) 255 { 256 DWORD size = lstrlenW(string); 257 LPWSTR s, d; 258 259 TRACE("(%s %d) stub\n", debugstr_w(string), len); 260 261 if (StrPBrkW(string, L" \",;^") && size + 2 <= len) 262 { 263 s = &string[size - 1]; 264 d = &string[size + 2]; 265 *d-- = 0; 266 *d-- = '"'; 267 for (;d > string;) 268 *d-- = *s--; 269 *d = '"'; 270 } 271 } 272