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