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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 #include "wine/unicode.h"
33 #include "setupapi_private.h"
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
38 #define MAX_SYSTEM_DIRID DIRID_PRINTPROCESSOR
46 static int nb_user_dirids; /* number of user dirids in use */
47 static int alloc_user_dirids; /* number of allocated user dirids */
48 static struct user_dirid *user_dirids;
49 static const WCHAR *system_dirids[MAX_SYSTEM_DIRID+1];
51 /* retrieve the string for unknown dirids */
52 static const WCHAR *get_unknown_dirid(void)
54 static WCHAR *unknown_dirid;
55 static const WCHAR unknown_str[] = {'\\','u','n','k','n','o','w','n',0};
59 UINT len = GetSystemDirectoryW( NULL, 0 ) + strlenW(unknown_str);
60 if (!(unknown_dirid = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return NULL;
61 GetSystemDirectoryW( unknown_dirid, len );
62 strcatW( unknown_dirid, unknown_str );
67 /* create the string for a system dirid */
68 static const WCHAR *create_system_dirid( int dirid )
70 static const WCHAR Null[] = {0};
71 static const WCHAR C_Root[] = {'C',':','\\',0};
72 static const WCHAR Drivers[] = {'\\','d','r','i','v','e','r','s',0};
73 static const WCHAR Inf[] = {'\\','i','n','f',0};
74 static const WCHAR Help[] = {'\\','h','e','l','p',0};
75 static const WCHAR Fonts[] = {'\\','f','o','n','t','s',0};
76 static const WCHAR Viewers[] = {'\\','v','i','e','w','e','r','s',0};
77 static const WCHAR System[] = {'\\','s','y','s','t','e','m',0};
78 static const WCHAR Spool[] = {'\\','s','p','o','o','l',0};
79 static const WCHAR Profile[] = {'\\','p','r','o','f','i','l','e','s','\\','A','d','m','i','n','i','s','t','r','a','t','o','r',0};
80 static const WCHAR UserProfile[] = {'U','S','E','R','P','R','O','F','I','L','E',0};
82 WCHAR buffer[MAX_PATH+32], *str;
90 GetWindowsDirectoryW( buffer, MAX_PATH );
93 GetSystemDirectoryW( buffer, MAX_PATH );
96 GetSystemDirectoryW( buffer, MAX_PATH );
97 strcatW( buffer, Drivers );
100 GetWindowsDirectoryW( buffer, MAX_PATH );
101 strcatW( buffer, Inf );
104 GetWindowsDirectoryW( buffer, MAX_PATH );
105 strcatW( buffer, Help );
108 GetWindowsDirectoryW( buffer, MAX_PATH );
109 strcatW( buffer, Fonts );
112 GetSystemDirectoryW( buffer, MAX_PATH );
113 strcatW( buffer, Viewers );
116 return C_Root; /* FIXME */
118 GetWindowsDirectoryW( buffer, MAX_PATH );
121 return C_Root; /* FIXME */
123 GetWindowsDirectoryW( buffer, MAX_PATH );
124 strcatW( buffer, System );
127 case DIRID_SPOOLDRIVERS: /* FIXME */
128 GetWindowsDirectoryW( buffer, MAX_PATH );
129 strcatW( buffer, Spool );
131 case DIRID_USERPROFILE:
132 if (GetEnvironmentVariableW( UserProfile, buffer, MAX_PATH )) break;
133 GetWindowsDirectoryW( buffer, MAX_PATH );
134 strcatW( buffer, Profile );
137 return C_Root; /* FIXME */
138 case DIRID_COLOR: /* FIXME */
139 case DIRID_PRINTPROCESSOR: /* FIXME */
141 FIXME( "unknown dirid %d\n", dirid );
142 return get_unknown_dirid();
144 len = (strlenW(buffer) + 1) * sizeof(WCHAR);
145 if ((str = HeapAlloc( GetProcessHeap(), 0, len ))) memcpy( str, buffer, len );
149 /* retrieve the string corresponding to a dirid, or NULL if none */
150 const WCHAR *DIRID_get_string( HINF hinf, int dirid )
154 if (dirid == DIRID_ABSOLUTE || dirid == DIRID_ABSOLUTE_16BIT) dirid = DIRID_NULL;
156 if (dirid >= DIRID_USER)
158 for (i = 0; i < nb_user_dirids; i++)
159 if (user_dirids[i].id == dirid) return user_dirids[i].str;
160 ERR("user id %d not found\n", dirid );
165 if (dirid > MAX_SYSTEM_DIRID) return get_unknown_dirid();
166 if (dirid == DIRID_SRCPATH) return PARSER_get_src_root( hinf );
167 if (!system_dirids[dirid]) system_dirids[dirid] = create_system_dirid( dirid );
168 return system_dirids[dirid];
172 /* store a user dirid string */
173 static BOOL store_user_dirid( HINF hinf, int id, WCHAR *str )
177 for (i = 0; i < nb_user_dirids; i++) if (user_dirids[i].id == id) break;
179 if (i < nb_user_dirids) HeapFree( GetProcessHeap(), 0, user_dirids[i].str );
182 if (nb_user_dirids >= alloc_user_dirids)
184 int new_size = max( 32, alloc_user_dirids * 2 );
186 struct user_dirid *new;
189 new = HeapReAlloc( GetProcessHeap(), 0, user_dirids,
190 new_size * sizeof(*new) );
192 new = HeapAlloc( GetProcessHeap(), 0,
193 new_size * sizeof(*new) );
195 if (!new) return FALSE;
197 alloc_user_dirids = new_size;
201 user_dirids[i].id = id;
202 user_dirids[i].str = str;
203 TRACE("id %d -> %s\n", id, debugstr_w(str) );
208 /***********************************************************************
209 * SetupSetDirectoryIdA (SETUPAPI.@)
211 BOOL WINAPI SetupSetDirectoryIdA( HINF hinf, DWORD id, PCSTR dir )
216 if (!id) /* clear everything */
218 for (i = 0; i < nb_user_dirids; i++) HeapFree( GetProcessHeap(), 0, user_dirids[i].str );
224 SetLastError( ERROR_INVALID_PARAMETER );
228 /* duplicate the string */
229 if (!RtlCreateUnicodeStringFromAsciiz( &dirW, dir ))
231 SetLastError( ERROR_NOT_ENOUGH_MEMORY );
234 return store_user_dirid( hinf, id, dirW.Buffer );
238 /***********************************************************************
239 * SetupSetDirectoryIdW (SETUPAPI.@)
241 BOOL WINAPI SetupSetDirectoryIdW( HINF hinf, DWORD id, PCWSTR dir )
246 if (!id) /* clear everything */
248 for (i = 0; i < nb_user_dirids; i++) HeapFree( GetProcessHeap(), 0, user_dirids[i].str );
254 SetLastError( ERROR_INVALID_PARAMETER );
258 /* duplicate the string */
259 len = (strlenW(dir)+1) * sizeof(WCHAR);
260 if (!(str = HeapAlloc( GetProcessHeap(), 0, len ))) return FALSE;
261 memcpy( str, dir, len );
262 return store_user_dirid( hinf, id, str );