Fixed a few more headers dependency issues.
[wine] / dlls / shell32 / shellstring.c
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18
19 #include <string.h>
20 #include <stdarg.h>
21 #include <stdio.h>
22 #include <ctype.h>
23 #include <stdlib.h>
24
25 #define NONAMELESSUNION
26 #define NONAMELESSSTRUCT
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winnls.h"
30 #include "winerror.h"
31 #include "wingdi.h"
32 #include "winuser.h"
33 #include "winreg.h"
34
35 #include "shlobj.h"
36 #include "shellapi.h"
37 #include "shlwapi.h"
38 #include "shell32_main.h"
39 #include "undocshell.h"
40 #include "wine/unicode.h"
41 #include "wine/debug.h"
42
43 WINE_DEFAULT_DEBUG_CHANNEL(shell);
44
45 /************************* STRRET functions ****************************/
46
47 /*
48  * ***** NOTE *****
49  *  These routines are identical to StrRetToBuf[AW] in dlls/shlwapi/string.c.
50  *  They were duplicated here because not every version of Shlwapi.dll exports
51  *  StrRetToBuf[AW]. If you change one routine, change them both. YOU HAVE BEEN
52  *  WARNED.
53  * ***** NOTE *****
54  */
55
56 HRESULT WINAPI StrRetToStrNA (LPVOID dest, DWORD len, LPSTRRET src, const ITEMIDLIST *pidl)
57 {
58         TRACE("dest=%p len=0x%lx strret=%p(%s) pidl=%p\n",
59             dest,len,src,
60             (src->uType == STRRET_WSTR) ? "STRRET_WSTR" :
61             (src->uType == STRRET_CSTR) ? "STRRET_CSTR" :
62             (src->uType == STRRET_OFFSET) ? "STRRET_OFFSET" : "STRRET_???",
63             pidl);
64
65         switch (src->uType)
66         {
67           case STRRET_WSTR:
68             WideCharToMultiByte(CP_ACP, 0, src->u.pOleStr, -1, (LPSTR)dest, len, NULL, NULL);
69             CoTaskMemFree(src->u.pOleStr);
70             break;
71
72           case STRRET_CSTR:
73             lstrcpynA((LPSTR)dest, src->u.cStr, len);
74             break;
75
76           case STRRET_OFFSET:
77             lstrcpynA((LPSTR)dest, ((LPCSTR)&pidl->mkid)+src->u.uOffset, len);
78             break;
79
80           default:
81             FIXME("unknown type!\n");
82             if (len) *(LPSTR)dest = '\0';
83             return(FALSE);
84         }
85         TRACE("-- %s\n", debugstr_a(dest) );
86         return S_OK;
87 }
88
89 /************************************************************************/
90
91 HRESULT WINAPI StrRetToStrNW (LPVOID dest, DWORD len, LPSTRRET src, const ITEMIDLIST *pidl)
92 {
93         TRACE("dest=%p len=0x%lx strret=%p(%s) pidl=%p\n",
94             dest,len,src,
95             (src->uType == STRRET_WSTR) ? "STRRET_WSTR" :
96             (src->uType == STRRET_CSTR) ? "STRRET_CSTR" :
97             (src->uType == STRRET_OFFSET) ? "STRRET_OFFSET" : "STRRET_???",
98             pidl);
99
100         switch (src->uType)
101         {
102           case STRRET_WSTR:
103             lstrcpynW((LPWSTR)dest, src->u.pOleStr, len);
104             CoTaskMemFree(src->u.pOleStr);
105             break;
106
107           case STRRET_CSTR:
108             if (!MultiByteToWideChar( CP_ACP, 0, src->u.cStr, -1, dest, len ) && len)
109                   ((LPWSTR)dest)[len-1] = 0;
110             break;
111
112           case STRRET_OFFSET:
113             if (!MultiByteToWideChar( CP_ACP, 0, ((LPCSTR)&pidl->mkid)+src->u.uOffset, -1, dest, len ) && len)
114                   ((LPWSTR)dest)[len-1] = 0;
115             break;
116
117           default:
118             FIXME("unknown type!\n");
119             if (len) *(LPWSTR)dest = '\0';
120             return(FALSE);
121         }
122         return S_OK;
123 }
124
125
126 /*************************************************************************
127  * StrRetToStrN                         [SHELL32.96]
128  *
129  * converts a STRRET to a normal string
130  *
131  * NOTES
132  *  the pidl is for STRRET OFFSET
133  */
134 HRESULT WINAPI StrRetToStrNAW (LPVOID dest, DWORD len, LPSTRRET src, const ITEMIDLIST *pidl)
135 {
136         if(SHELL_OsIsUnicode())
137           return StrRetToStrNW (dest, len, src, pidl);
138         return StrRetToStrNA (dest, len, src, pidl);
139 }
140
141 /************************* OLESTR functions ****************************/
142
143 /************************************************************************
144  *      StrToOleStr                     [SHELL32.163]
145  *
146  */
147 int WINAPI StrToOleStrA (LPWSTR lpWideCharStr, LPCSTR lpMultiByteString)
148 {
149         TRACE("(%p, %p %s)\n",
150         lpWideCharStr, lpMultiByteString, debugstr_a(lpMultiByteString));
151
152         return MultiByteToWideChar(0, 0, lpMultiByteString, -1, lpWideCharStr, MAX_PATH);
153
154 }
155 int WINAPI StrToOleStrW (LPWSTR lpWideCharStr, LPCWSTR lpWString)
156 {
157         TRACE("(%p, %p %s)\n",
158         lpWideCharStr, lpWString, debugstr_w(lpWString));
159
160         strcpyW (lpWideCharStr, lpWString );
161         return strlenW(lpWideCharStr);
162 }
163
164 BOOL WINAPI StrToOleStrAW (LPWSTR lpWideCharStr, LPCVOID lpString)
165 {
166         if (SHELL_OsIsUnicode())
167           return StrToOleStrW (lpWideCharStr, lpString);
168         return StrToOleStrA (lpWideCharStr, lpString);
169 }
170
171 /*************************************************************************
172  * StrToOleStrN                                 [SHELL32.79]
173  *  lpMulti, nMulti, nWide [IN]
174  *  lpWide [OUT]
175  */
176 BOOL WINAPI StrToOleStrNA (LPWSTR lpWide, INT nWide, LPCSTR lpStrA, INT nStr)
177 {
178         TRACE("(%p, %x, %s, %x)\n", lpWide, nWide, debugstr_an(lpStrA,nStr), nStr);
179         return MultiByteToWideChar (0, 0, lpStrA, nStr, lpWide, nWide);
180 }
181 BOOL WINAPI StrToOleStrNW (LPWSTR lpWide, INT nWide, LPCWSTR lpStrW, INT nStr)
182 {
183         TRACE("(%p, %x, %s, %x)\n", lpWide, nWide, debugstr_wn(lpStrW, nStr), nStr);
184
185         if (lstrcpynW (lpWide, lpStrW, nWide))
186         { return lstrlenW (lpWide);
187         }
188         return 0;
189 }
190
191 BOOL WINAPI StrToOleStrNAW (LPWSTR lpWide, INT nWide, LPCVOID lpStr, INT nStr)
192 {
193         if (SHELL_OsIsUnicode())
194           return StrToOleStrNW (lpWide, nWide, lpStr, nStr);
195         return StrToOleStrNA (lpWide, nWide, lpStr, nStr);
196 }
197
198 /*************************************************************************
199  * OleStrToStrN                                 [SHELL32.78]
200  */
201 BOOL WINAPI OleStrToStrNA (LPSTR lpStr, INT nStr, LPCWSTR lpOle, INT nOle)
202 {
203         TRACE("(%p, %x, %s, %x)\n", lpStr, nStr, debugstr_wn(lpOle,nOle), nOle);
204         return WideCharToMultiByte (0, 0, lpOle, nOle, lpStr, nStr, NULL, NULL);
205 }
206
207 BOOL WINAPI OleStrToStrNW (LPWSTR lpwStr, INT nwStr, LPCWSTR lpOle, INT nOle)
208 {
209         TRACE("(%p, %x, %s, %x)\n", lpwStr, nwStr, debugstr_wn(lpOle,nOle), nOle);
210
211         if (lstrcpynW ( lpwStr, lpOle, nwStr))
212         { return lstrlenW (lpwStr);
213         }
214         return 0;
215 }
216
217 BOOL WINAPI OleStrToStrNAW (LPVOID lpOut, INT nOut, LPCVOID lpIn, INT nIn)
218 {
219         if (SHELL_OsIsUnicode())
220           return OleStrToStrNW (lpOut, nOut, lpIn, nIn);
221         return OleStrToStrNA (lpOut, nOut, lpIn, nIn);
222 }
223
224
225 /*************************************************************************
226  * CheckEscapesA             [SHELL32.@]
227  *
228  * Checks a string for special characters which are not allowed in a path
229  * and encloses it in quotes if that is the case.
230  *
231  * PARAMS
232  *  string     [I/O] string to check and on return eventually quoted
233  *  len        [I]   length of string
234  *
235  * RETURNS
236  *  length of actual string
237  *
238  * NOTES
239  *  Not really sure if this function returns actually a value at all. 
240  */
241 DWORD WINAPI CheckEscapesA(
242         LPSTR   string,         /* [I/O]   string to check ??*/
243         DWORD   len)            /* [I]      is 0 */
244 {
245         LPWSTR wString;
246         DWORD ret = 0;
247
248         TRACE("(%s %ld)\n", debugstr_a(string), len);
249         wString = (LPWSTR)LocalAlloc(LPTR, len * sizeof(WCHAR));
250         if (wString)
251         {
252           MultiByteToWideChar(CP_ACP, 0, string, len, wString, len);
253           ret = CheckEscapesW(wString, len);
254           WideCharToMultiByte(CP_ACP, 0, wString, len, string, len, NULL, NULL);
255           LocalFree(wString);
256         }
257         return ret;
258 }
259
260 static const WCHAR strEscapedChars[] = {' ','"',',',';','^',0};
261
262 /*************************************************************************
263  * CheckEscapesW             [SHELL32.@]
264  *
265  * see CheckEscapesA
266  */
267 DWORD WINAPI CheckEscapesW(
268         LPWSTR  string,
269         DWORD   len)
270 {
271         DWORD size = lstrlenW(string);
272         LPWSTR s, d;
273
274         TRACE("(%s %ld) stub\n", debugstr_w(string), len);
275
276         if (StrPBrkW(string, strEscapedChars) && size + 2 <= len)
277         {
278           s = &string[size - 1];
279           d = &string[size + 2];
280           *d-- = 0;
281           *d-- = '"';
282           for (;d > string;)
283             *d-- = *s--;
284           *d = '"';
285           return size + 2;
286         }
287         return size;
288 }