Let property sheets update the cached system colors upon receiving
[wine] / dlls / kernel / oldconfig.c
1 /*
2  * Support for converting from old configuration format
3  *
4  * Copyright 2005 Alexandre Julliard
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  * NOTES
21  *   This file should be removed after a suitable transition period.
22  */
23
24 #include "config.h"
25 #include "wine/port.h"
26
27 #include <stdarg.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #ifdef HAVE_SYS_STAT_H
31 # include <sys/stat.h>
32 #endif
33 #include <fcntl.h>
34 #ifdef HAVE_SYS_IOCTL_H
35 #include <sys/ioctl.h>
36 #endif
37 #ifdef HAVE_LINUX_HDREG_H
38 # include <linux/hdreg.h>
39 #endif
40
41 #define NONAMELESSUNION
42 #define NONAMELESSSTRUCT
43 #include "windef.h"
44 #include "winbase.h"
45 #include "winnls.h"
46 #include "winternl.h"
47 #include "ntstatus.h"
48 #include "winioctl.h"
49 #include "ntddscsi.h"
50 #include "wine/library.h"
51 #include "wine/server.h"
52 #include "wine/unicode.h"
53 #include "wine/debug.h"
54 #include "kernel_private.h"
55
56 WINE_DEFAULT_DEBUG_CHANNEL(reg);
57
58
59 /* registry initialisation, allocates some default keys. */
60 static ULONG allocate_default_keys(void)
61 {
62     static const WCHAR StatDataW[] = {'D','y','n','D','a','t','a','\\',
63                                       'P','e','r','f','S','t','a','t','s','\\',
64                                       'S','t','a','t','D','a','t','a',0};
65     static const WCHAR ConfigManagerW[] = {'D','y','n','D','a','t','a','\\',
66                                            'C','o','n','f','i','g',' ','M','a','n','a','g','e','r','\\',
67                                             'E','n','u','m',0};
68     HANDLE hkey;
69     ULONG dispos;
70     OBJECT_ATTRIBUTES attr;
71     UNICODE_STRING nameW;
72
73     attr.Length = sizeof(attr);
74     attr.RootDirectory = 0;
75     attr.ObjectName = &nameW;
76     attr.Attributes = 0;
77     attr.SecurityDescriptor = NULL;
78     attr.SecurityQualityOfService = NULL;
79
80     RtlInitUnicodeString( &nameW, StatDataW );
81     if (!NtCreateKey( &hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, &dispos )) NtClose( hkey );
82     if (dispos == REG_OPENED_EXISTING_KEY)
83         return dispos; /* someone else already loaded the registry */
84
85     RtlInitUnicodeString( &nameW, ConfigManagerW );
86     if (!NtCreateKey( &hkey, KEY_ALL_ACCESS, &attr, 0, NULL, 0, NULL )) NtClose( hkey );
87
88     return dispos;
89 }
90
91
92 /******************************************************************
93  *              init_cdrom_registry
94  *
95  * Initializes registry to contain scsi info about the cdrom in NT.
96  * All devices (even not real scsi ones) have this info in NT.
97  * TODO: for now it only works for non scsi devices
98  * NOTE: programs usually read these registry entries after sending the
99  *       IOCTL_SCSI_GET_ADDRESS ioctl to the cdrom
100  */
101 static void init_cdrom_registry( HANDLE handle )
102 {
103     OBJECT_ATTRIBUTES attr;
104     UNICODE_STRING nameW;
105     WCHAR dataW[50];
106     DWORD lenW;
107     char buffer[40];
108     DWORD value;
109     const char *data;
110     HANDLE scsiKey;
111     HANDLE portKey;
112     HANDLE busKey;
113     HANDLE targetKey;
114     DWORD disp;
115     IO_STATUS_BLOCK io;
116     SCSI_ADDRESS scsi_addr;
117
118     if (NtDeviceIoControlFile( handle, 0, NULL, NULL, &io, IOCTL_SCSI_GET_ADDRESS,
119                                NULL, 0, &scsi_addr, sizeof(scsi_addr) ))
120         return;
121
122     attr.Length = sizeof(attr);
123     attr.RootDirectory = 0;
124     attr.ObjectName = &nameW;
125     attr.Attributes = 0;
126     attr.SecurityDescriptor = NULL;
127     attr.SecurityQualityOfService = NULL;
128
129     /* Ensure there is Scsi key */
130     if (!RtlCreateUnicodeStringFromAsciiz( &nameW, "Machine\\HARDWARE\\DEVICEMAP\\Scsi" ) ||
131         NtCreateKey( &scsiKey, KEY_ALL_ACCESS, &attr, 0,
132                      NULL, REG_OPTION_VOLATILE, &disp ))
133     {
134         ERR("Cannot create DEVICEMAP\\Scsi registry key\n" );
135         return;
136     }
137     RtlFreeUnicodeString( &nameW );
138
139     snprintf(buffer,sizeof(buffer),"Scsi Port %d",scsi_addr.PortNumber);
140     attr.RootDirectory = scsiKey;
141     if (!RtlCreateUnicodeStringFromAsciiz( &nameW, buffer ) ||
142         NtCreateKey( &portKey, KEY_ALL_ACCESS, &attr, 0,
143                      NULL, REG_OPTION_VOLATILE, &disp ))
144     {
145         ERR("Cannot create DEVICEMAP\\Scsi Port registry key\n" );
146         return;
147     }
148     RtlFreeUnicodeString( &nameW );
149
150     RtlCreateUnicodeStringFromAsciiz( &nameW, "Driver" );
151     data = "atapi";
152     RtlMultiByteToUnicodeN( dataW, 50, &lenW, data, strlen(data));
153     NtSetValueKey( portKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW );
154     RtlFreeUnicodeString( &nameW );
155     value = 10;
156     RtlCreateUnicodeStringFromAsciiz( &nameW, "FirstBusTimeScanInMs" );
157     NtSetValueKey( portKey,&nameW, 0, REG_DWORD, (BYTE *)&value, sizeof(DWORD));
158     RtlFreeUnicodeString( &nameW );
159     value = 0;
160 #ifdef HDIO_GET_DMA
161     {
162         int fd, dma;
163         if (!wine_server_handle_to_fd( handle, 0, &fd, NULL ))
164         {
165             if (ioctl(fd,HDIO_GET_DMA, &dma) != -1) value = dma;
166             wine_server_release_fd( handle, fd );
167         }
168     }
169 #endif
170     RtlCreateUnicodeStringFromAsciiz( &nameW, "DMAEnabled" );
171     NtSetValueKey( portKey,&nameW, 0, REG_DWORD, (BYTE *)&value, sizeof(DWORD));
172     RtlFreeUnicodeString( &nameW );
173
174     snprintf(buffer,40,"Scsi Bus %d", scsi_addr.PathId);
175     attr.RootDirectory = portKey;
176     if (!RtlCreateUnicodeStringFromAsciiz( &nameW, buffer ) ||
177         NtCreateKey( &busKey, KEY_ALL_ACCESS, &attr, 0,
178                      NULL, REG_OPTION_VOLATILE, &disp ))
179     {
180         ERR("Cannot create DEVICEMAP\\Scsi Port\\Scsi Bus registry key\n" );
181         return;
182     }
183     RtlFreeUnicodeString( &nameW );
184
185     attr.RootDirectory = busKey;
186     if (!RtlCreateUnicodeStringFromAsciiz( &nameW, "Initiator Id 255" ) ||
187         NtCreateKey( &targetKey, KEY_ALL_ACCESS, &attr, 0,
188                      NULL, REG_OPTION_VOLATILE, &disp ))
189     {
190         ERR("Cannot create DEVICEMAP\\Scsi Port\\Scsi Bus\\Initiator Id 255 registry key\n" );
191         return;
192     }
193     RtlFreeUnicodeString( &nameW );
194     NtClose( targetKey );
195
196     snprintf(buffer,40,"Target Id %d", scsi_addr.TargetId);
197     attr.RootDirectory = busKey;
198     if (!RtlCreateUnicodeStringFromAsciiz( &nameW, buffer ) ||
199         NtCreateKey( &targetKey, KEY_ALL_ACCESS, &attr, 0,
200                      NULL, REG_OPTION_VOLATILE, &disp ))
201     {
202         ERR("Cannot create DEVICEMAP\\Scsi Port\\Scsi Bus 0\\Target Id registry key\n" );
203         return;
204     }
205     RtlFreeUnicodeString( &nameW );
206
207     RtlCreateUnicodeStringFromAsciiz( &nameW, "Type" );
208     data = "CdRomPeripheral";
209     RtlMultiByteToUnicodeN( dataW, 50, &lenW, data, strlen(data));
210     NtSetValueKey( targetKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW );
211     RtlFreeUnicodeString( &nameW );
212     /* FIXME - maybe read the real identifier?? */
213     RtlCreateUnicodeStringFromAsciiz( &nameW, "Identifier" );
214     data = "Wine CDROM";
215     RtlMultiByteToUnicodeN( dataW, 50, &lenW, data, strlen(data));
216     NtSetValueKey( targetKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW );
217     RtlFreeUnicodeString( &nameW );
218     /* FIXME - we always use Cdrom0 - do not know about the nt behaviour */
219     RtlCreateUnicodeStringFromAsciiz( &nameW, "DeviceName" );
220     data = "Cdrom0";
221     RtlMultiByteToUnicodeN( dataW, 50, &lenW, data, strlen(data));
222     NtSetValueKey( targetKey, &nameW, 0, REG_SZ, (BYTE*)dataW, lenW );
223     RtlFreeUnicodeString( &nameW );
224
225     NtClose( targetKey );
226     NtClose( busKey );
227     NtClose( portKey );
228     NtClose( scsiKey );
229 }
230
231
232 /* create the hardware registry branch */
233 static void create_hardware_branch(void)
234 {
235     int i;
236     HANDLE handle;
237     char drive[] = "\\\\.\\A:";
238
239     /* create entries for cdroms (skipping A: and B:) */
240     for (i = 2; i < 26; i++)
241     {
242         drive[4] = 'A' + i;
243         handle = CreateFileA( drive, 0, 0, NULL, OPEN_EXISTING, 0, 0 );
244         if (handle == INVALID_HANDLE_VALUE) continue;
245         init_cdrom_registry( handle );
246         CloseHandle( handle );
247     }
248 }
249
250
251 /***********************************************************************
252  *              convert_old_config
253  */
254 void convert_old_config(void)
255 {
256     HANDLE hkey_current_user;
257
258     if (allocate_default_keys() == REG_OPENED_EXISTING_KEY)
259         return; /* someone else already loaded the registry */
260
261     RtlOpenCurrentUser( KEY_ALL_ACCESS, &hkey_current_user );
262
263     /* load the user registry (FIXME: should be done at server init time) */
264     SERVER_START_REQ( load_user_registries )
265     {
266         req->hkey = hkey_current_user;
267         wine_server_call( req );
268     }
269     SERVER_END_REQ;
270
271     /* create some hardware keys (FIXME: should not be done here) */
272     create_hardware_branch();
273
274     NtClose( hkey_current_user );
275 }