source: trunk/src/setupapi/dirid.c

Last change on this file was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

File size: 7.3 KB
Line 
1/*
2 * Directory id handling
3 *
4 * Copyright 2002 Alexandre Julliard for CodeWeavers
5 *
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.
10 *
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.
15 *
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
19 */
20
21#include <memory.h>
22
23#include "windef.h"
24#include "winbase.h"
25#include "winternl.h"
26#include "winerror.h"
27#include "setupapi.h"
28#include "wine/unicode.h"
29#include "setupapi_private.h"
30#include "wine/debug.h"
31
32WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
33
34#define MAX_SYSTEM_DIRID DIRID_PRINTPROCESSOR
35
36struct user_dirid
37{
38 int id;
39 WCHAR *str;
40};
41
42static int nb_user_dirids; /* number of user dirids in use */
43static int alloc_user_dirids; /* number of allocated user dirids */
44static struct user_dirid *user_dirids;
45static const WCHAR *system_dirids[MAX_SYSTEM_DIRID+1];
46
47/* retrieve the string for unknown dirids */
48static const WCHAR *get_unknown_dirid(void)
49{
50 static WCHAR *unknown_dirid;
51 static const WCHAR unknown_str[] = {'\\','u','n','k','n','o','w','n',0};
52
53 if (!unknown_dirid)
54 {
55 UINT len = GetSystemDirectoryW( NULL, 0 ) + strlenW(unknown_str);
56 if (!(unknown_dirid = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return NULL;
57 GetSystemDirectoryW( unknown_dirid, len );
58 strcatW( unknown_dirid, unknown_str );
59 }
60 return unknown_dirid;
61}
62
63/* create the string for a system dirid */
64static const WCHAR *create_system_dirid( int dirid )
65{
66 static const WCHAR Null[] = {0};
67 static const WCHAR C_Root[] = {'C',':','\\',0};
68 static const WCHAR Drivers[] = {'\\','d','r','i','v','e','r','s',0};
69 static const WCHAR Inf[] = {'\\','i','n','f',0};
70 static const WCHAR Help[] = {'\\','h','e','l','p',0};
71 static const WCHAR Fonts[] = {'\\','f','o','n','t','s',0};
72 static const WCHAR Viewers[] = {'\\','v','i','e','w','e','r','s',0};
73 static const WCHAR System[] = {'\\','s','y','s','t','e','m',0};
74 static const WCHAR Spool[] = {'\\','s','p','o','o','l',0};
75
76 WCHAR buffer[MAX_PATH+16], *str;
77 int len;
78
79 switch(dirid)
80 {
81 case DIRID_NULL:
82 return Null;
83 case DIRID_WINDOWS:
84 GetWindowsDirectoryW( buffer, MAX_PATH );
85 break;
86 case DIRID_SYSTEM:
87 GetSystemDirectoryW( buffer, MAX_PATH );
88 break;
89 case DIRID_DRIVERS:
90 GetSystemDirectoryW( buffer, MAX_PATH );
91 strcatW( buffer, Drivers );
92 break;
93 case DIRID_INF:
94 GetWindowsDirectoryW( buffer, MAX_PATH );
95 strcatW( buffer, Inf );
96 break;
97 case DIRID_HELP:
98 GetWindowsDirectoryW( buffer, MAX_PATH );
99 strcatW( buffer, Help );
100 break;
101 case DIRID_FONTS:
102 GetWindowsDirectoryW( buffer, MAX_PATH );
103 strcatW( buffer, Fonts );
104 break;
105 case DIRID_VIEWERS:
106 GetSystemDirectoryW( buffer, MAX_PATH );
107 strcatW( buffer, Viewers );
108 break;
109 case DIRID_APPS:
110 return C_Root; /* FIXME */
111 case DIRID_SHARED:
112 GetWindowsDirectoryW( buffer, MAX_PATH );
113 break;
114 case DIRID_BOOT:
115 return C_Root; /* FIXME */
116 case DIRID_SYSTEM16:
117 GetWindowsDirectoryW( buffer, MAX_PATH );
118 strcatW( buffer, System );
119 break;
120 case DIRID_SPOOL:
121 case DIRID_SPOOLDRIVERS: /* FIXME */
122 GetWindowsDirectoryW( buffer, MAX_PATH );
123 strcatW( buffer, Spool );
124 break;
125 case DIRID_LOADER:
126 return C_Root; /* FIXME */
127 case DIRID_USERPROFILE: /* FIXME */
128 case DIRID_COLOR: /* FIXME */
129 case DIRID_PRINTPROCESSOR: /* FIXME */
130 default:
131 FIXME( "unknwon dirid %d\n", dirid );
132 return get_unknown_dirid();
133 }
134 len = (strlenW(buffer) + 1) * sizeof(WCHAR);
135 if ((str = HeapAlloc( GetProcessHeap(), 0, len ))) memcpy( str, buffer, len );
136 return str;
137}
138
139/* retrieve the string corresponding to a dirid, or NULL if none */
140const WCHAR *DIRID_get_string( HINF hinf, int dirid )
141{
142 int i;
143
144 if (dirid == DIRID_ABSOLUTE || dirid == DIRID_ABSOLUTE_16BIT) dirid = DIRID_NULL;
145
146 if (dirid >= DIRID_USER)
147 {
148 for (i = 0; i < nb_user_dirids; i++)
149 if (user_dirids[i].id == dirid) return user_dirids[i].str;
150 ERR("user id %d not found\n", dirid );
151 return NULL;
152 }
153 else
154 {
155 if (dirid > MAX_SYSTEM_DIRID) return get_unknown_dirid();
156 if (dirid == DIRID_SRCPATH) return PARSER_get_src_root( hinf );
157 if (!system_dirids[dirid]) system_dirids[dirid] = create_system_dirid( dirid );
158 return system_dirids[dirid];
159 }
160}
161
162/* store a user dirid string */
163static BOOL store_user_dirid( HINF hinf, int id, WCHAR *str )
164{
165 int i;
166
167 for (i = 0; i < nb_user_dirids; i++) if (user_dirids[i].id == id) break;
168
169 if (i < nb_user_dirids) HeapFree( GetProcessHeap(), 0, user_dirids[i].str );
170 else
171 {
172 if (nb_user_dirids >= alloc_user_dirids)
173 {
174 int new_size = max( 32, alloc_user_dirids * 2 );
175 struct user_dirid *new = HeapReAlloc( GetProcessHeap(), 0, user_dirids,
176 new_size * sizeof(*new) );
177 if (!new) return FALSE;
178 user_dirids = new;
179 alloc_user_dirids = new_size;
180 }
181 nb_user_dirids++;
182 }
183 user_dirids[i].id = id;
184 user_dirids[i].str = str;
185 TRACE("id %d -> %s\n", id, debugstr_w(str) );
186 return TRUE;
187}
188
189
190/***********************************************************************
191 * SetupSetDirectoryIdA (SETUPAPI.@)
192 */
193BOOL WINAPI SetupSetDirectoryIdA( HINF hinf, DWORD id, PCSTR dir )
194{
195 UNICODE_STRING dirW;
196 int i;
197
198 if (!id) /* clear everything */
199 {
200 for (i = 0; i < nb_user_dirids; i++) HeapFree( GetProcessHeap(), 0, user_dirids[i].str );
201 nb_user_dirids = 0;
202 return TRUE;
203 }
204 if (id < DIRID_USER)
205 {
206 SetLastError( ERROR_INVALID_PARAMETER );
207 return FALSE;
208 }
209
210 /* duplicate the string */
211 if (!RtlCreateUnicodeStringFromAsciiz( &dirW, dir ))
212 {
213 SetLastError( ERROR_NOT_ENOUGH_MEMORY );
214 return FALSE;
215 }
216 return store_user_dirid( hinf, id, dirW.Buffer );
217}
218
219
220/***********************************************************************
221 * SetupSetDirectoryIdW (SETUPAPI.@)
222 */
223BOOL WINAPI SetupSetDirectoryIdW( HINF hinf, DWORD id, PCWSTR dir )
224{
225 int i, len;
226 WCHAR *str;
227
228 if (!id) /* clear everything */
229 {
230 for (i = 0; i < nb_user_dirids; i++) HeapFree( GetProcessHeap(), 0, user_dirids[i].str );
231 nb_user_dirids = 0;
232 return TRUE;
233 }
234 if (id < DIRID_USER)
235 {
236 SetLastError( ERROR_INVALID_PARAMETER );
237 return FALSE;
238 }
239
240 /* duplicate the string */
241 len = (strlenW(dir)+1) * sizeof(WCHAR);
242 if (!(str = HeapAlloc( GetProcessHeap(), 0, len ))) return FALSE;
243 memcpy( str, dir, len );
244 return store_user_dirid( hinf, id, str );
245}
Note: See TracBrowser for help on using the repository browser.