include: Use the public VM_COUNTERS and VM_COUNTERS_EX structure definitions.
[wine.git] / dlls / setupapi / dirid.c
blobd1bffe9d01e31516285932f8700d2b0b8a0a9279
1 /*
2 * Directory id handling
4 * Copyright 2002 Alexandre Julliard for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winreg.h"
26 #include "winternl.h"
27 #include "winerror.h"
28 #include "wingdi.h"
29 #include "winuser.h"
30 #include "winnls.h"
31 #include "winspool.h"
32 #include "setupapi.h"
33 #include "shlobj.h"
34 #include "setupapi_private.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
39 #define MAX_SYSTEM_DIRID DIRID_PRINTPROCESSOR
40 #define MIN_CSIDL_DIRID 0x4000
41 #define MAX_CSIDL_DIRID 0x403f
43 struct user_dirid
45 int id;
46 WCHAR *str;
49 static int nb_user_dirids; /* number of user dirids in use */
50 static int alloc_user_dirids; /* number of allocated user dirids */
51 static struct user_dirid *user_dirids;
52 static const WCHAR *system_dirids[MAX_SYSTEM_DIRID+1];
53 static const WCHAR *csidl_dirids[MAX_CSIDL_DIRID-MIN_CSIDL_DIRID+1];
55 /* retrieve the string for unknown dirids */
56 static const WCHAR *get_unknown_dirid(void)
58 static WCHAR *unknown_dirid;
59 static const WCHAR unknown_str[] = {'\\','u','n','k','n','o','w','n',0};
61 if (!unknown_dirid)
63 UINT len = GetSystemDirectoryW( NULL, 0 ) + lstrlenW(unknown_str);
64 if (!(unknown_dirid = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return NULL;
65 GetSystemDirectoryW( unknown_dirid, len );
66 lstrcatW( unknown_dirid, unknown_str );
68 return unknown_dirid;
71 static const WCHAR *get_csidl_dir(DWORD csidl);
73 /* create the string for a system dirid */
74 static const WCHAR *create_system_dirid( int dirid )
76 static const WCHAR Null[] = {0};
77 static const WCHAR C_Root[] = {'C',':','\\',0};
78 static const WCHAR Drivers[] = {'\\','d','r','i','v','e','r','s',0};
79 static const WCHAR Inf[] = {'\\','i','n','f',0};
80 static const WCHAR Help[] = {'\\','h','e','l','p',0};
81 static const WCHAR Fonts[] = {'\\','f','o','n','t','s',0};
82 static const WCHAR Viewers[] = {'\\','v','i','e','w','e','r','s',0};
83 static const WCHAR System[] = {'\\','s','y','s','t','e','m',0};
84 static const WCHAR Spool[] = {'\\','s','p','o','o','l',0};
85 static const WCHAR UserProfile[] = {'U','S','E','R','P','R','O','F','I','L','E',0};
87 WCHAR buffer[MAX_PATH+32], *str;
88 int len;
89 DWORD needed;
91 switch(dirid)
93 case DIRID_NULL:
94 return Null;
95 case DIRID_WINDOWS:
96 GetWindowsDirectoryW( buffer, MAX_PATH );
97 break;
98 case DIRID_SYSTEM:
99 GetSystemDirectoryW( buffer, MAX_PATH );
100 break;
101 case DIRID_DRIVERS:
102 GetSystemDirectoryW( buffer, MAX_PATH );
103 lstrcatW( buffer, Drivers );
104 break;
105 case DIRID_INF:
106 GetWindowsDirectoryW( buffer, MAX_PATH );
107 lstrcatW( buffer, Inf );
108 break;
109 case DIRID_HELP:
110 GetWindowsDirectoryW( buffer, MAX_PATH );
111 lstrcatW( buffer, Help );
112 break;
113 case DIRID_FONTS:
114 GetWindowsDirectoryW( buffer, MAX_PATH );
115 lstrcatW( buffer, Fonts );
116 break;
117 case DIRID_VIEWERS:
118 GetSystemDirectoryW( buffer, MAX_PATH );
119 lstrcatW( buffer, Viewers );
120 break;
121 case DIRID_APPS:
122 return C_Root; /* FIXME */
123 case DIRID_SHARED:
124 GetWindowsDirectoryW( buffer, MAX_PATH );
125 break;
126 case DIRID_BOOT:
127 return C_Root; /* FIXME */
128 case DIRID_SYSTEM16:
129 GetWindowsDirectoryW( buffer, MAX_PATH );
130 lstrcatW( buffer, System );
131 break;
132 case DIRID_SPOOL:
133 case DIRID_SPOOLDRIVERS: /* FIXME */
134 GetWindowsDirectoryW( buffer, MAX_PATH );
135 lstrcatW( buffer, Spool );
136 break;
137 case DIRID_USERPROFILE:
138 if (GetEnvironmentVariableW( UserProfile, buffer, MAX_PATH )) break;
139 return get_csidl_dir(CSIDL_PROFILE);
140 case DIRID_LOADER:
141 return C_Root; /* FIXME */
142 case DIRID_PRINTPROCESSOR:
143 if (!GetPrintProcessorDirectoryW(NULL, NULL, 1, (LPBYTE)buffer, sizeof(buffer), &needed))
145 WARN( "cannot retrieve print processor directory\n" );
146 return get_unknown_dirid();
148 break;
149 case DIRID_COLOR: /* FIXME */
150 default:
151 FIXME( "unknown dirid %d\n", dirid );
152 return get_unknown_dirid();
154 len = (lstrlenW(buffer) + 1) * sizeof(WCHAR);
155 if ((str = HeapAlloc( GetProcessHeap(), 0, len ))) memcpy( str, buffer, len );
156 return str;
159 static const WCHAR *get_csidl_dir( DWORD csidl )
161 WCHAR buffer[MAX_PATH], *str;
162 int len;
164 if (!SHGetSpecialFolderPathW( NULL, buffer, csidl, TRUE ))
166 FIXME( "CSIDL %x not found\n", csidl );
167 return get_unknown_dirid();
169 len = (lstrlenW(buffer) + 1) * sizeof(WCHAR);
170 if ((str = HeapAlloc( GetProcessHeap(), 0, len ))) memcpy( str, buffer, len );
171 return str;
174 /* retrieve the string corresponding to a dirid, or NULL if none */
175 const WCHAR *DIRID_get_string( int dirid )
177 int i;
179 if (dirid == DIRID_ABSOLUTE || dirid == DIRID_ABSOLUTE_16BIT) dirid = DIRID_NULL;
181 if (dirid >= DIRID_USER)
183 for (i = 0; i < nb_user_dirids; i++)
184 if (user_dirids[i].id == dirid) return user_dirids[i].str;
185 WARN("user id %d not found\n", dirid );
186 return NULL;
188 else if (dirid >= MIN_CSIDL_DIRID)
190 if (dirid > MAX_CSIDL_DIRID) return get_unknown_dirid();
191 dirid -= MIN_CSIDL_DIRID;
192 if (!csidl_dirids[dirid]) csidl_dirids[dirid] = get_csidl_dir( dirid );
193 return csidl_dirids[dirid];
195 else
197 if (dirid > MAX_SYSTEM_DIRID) return get_unknown_dirid();
198 if (!system_dirids[dirid]) system_dirids[dirid] = create_system_dirid( dirid );
199 return system_dirids[dirid];
203 /* store a user dirid string */
204 static BOOL store_user_dirid( HINF hinf, int id, WCHAR *str )
206 int i;
208 for (i = 0; i < nb_user_dirids; i++) if (user_dirids[i].id == id) break;
210 if (i < nb_user_dirids) HeapFree( GetProcessHeap(), 0, user_dirids[i].str );
211 else
213 if (nb_user_dirids >= alloc_user_dirids)
215 int new_size = max( 32, alloc_user_dirids * 2 );
217 struct user_dirid *new;
219 if (user_dirids)
220 new = HeapReAlloc( GetProcessHeap(), 0, user_dirids,
221 new_size * sizeof(*new) );
222 else
223 new = HeapAlloc( GetProcessHeap(), 0,
224 new_size * sizeof(*new) );
226 if (!new) return FALSE;
227 user_dirids = new;
228 alloc_user_dirids = new_size;
230 nb_user_dirids++;
232 user_dirids[i].id = id;
233 user_dirids[i].str = str;
234 TRACE("id %d -> %s\n", id, debugstr_w(str) );
235 return TRUE;
239 /***********************************************************************
240 * SetupSetDirectoryIdA (SETUPAPI.@)
242 BOOL WINAPI SetupSetDirectoryIdA( HINF hinf, DWORD id, PCSTR dir )
244 UNICODE_STRING dirW;
245 int i;
247 if (!id) /* clear everything */
249 for (i = 0; i < nb_user_dirids; i++) HeapFree( GetProcessHeap(), 0, user_dirids[i].str );
250 nb_user_dirids = 0;
251 return TRUE;
253 if (id < DIRID_USER)
255 SetLastError( ERROR_INVALID_PARAMETER );
256 return FALSE;
259 /* duplicate the string */
260 if (!RtlCreateUnicodeStringFromAsciiz( &dirW, dir ))
262 SetLastError( ERROR_NOT_ENOUGH_MEMORY );
263 return FALSE;
265 return store_user_dirid( hinf, id, dirW.Buffer );
269 /***********************************************************************
270 * SetupSetDirectoryIdW (SETUPAPI.@)
272 BOOL WINAPI SetupSetDirectoryIdW( HINF hinf, DWORD id, PCWSTR dir )
274 int i, len;
275 WCHAR *str;
277 if (!id) /* clear everything */
279 for (i = 0; i < nb_user_dirids; i++) HeapFree( GetProcessHeap(), 0, user_dirids[i].str );
280 nb_user_dirids = 0;
281 return TRUE;
283 if (id < DIRID_USER)
285 SetLastError( ERROR_INVALID_PARAMETER );
286 return FALSE;
289 /* duplicate the string */
290 len = (lstrlenW(dir)+1) * sizeof(WCHAR);
291 if (!(str = HeapAlloc( GetProcessHeap(), 0, len ))) return FALSE;
292 memcpy( str, dir, len );
293 return store_user_dirid( hinf, id, str );