ReactOS  0.4.13-dev-92-gf251225
install.c
Go to the documentation of this file.
1 /*
2  * Unit test for setupapi.dll install functions
3  *
4  * Copyright 2007 Misha Koshelev
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include <stdarg.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <assert.h>
25 
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winnls.h"
29 #include "winuser.h"
30 #include "winreg.h"
31 #include "winsvc.h"
32 #include "setupapi.h"
33 #include "shlobj.h"
34 
35 #include "wine/test.h"
36 
37 static const char inffile[] = "test.inf";
38 static const WCHAR inffileW[] = {'t','e','s','t','.','i','n','f',0};
39 static char CURR_DIR[MAX_PATH];
40 
41 /* Notes on InstallHinfSectionA/W:
42  * - InstallHinfSectionA on WinXP seems to be a stub - it does not do anything
43  * and simply returns without displaying any error message or setting last
44  * error.
45  * - These functions do not return a value and do not always set last error to
46  * ERROR_SUCCESS when installation still occurs (e.g., unquoted inf file with
47  * spaces, registry keys are written but last error is 6).
48  * - On installation problems, a MessageBox() is displayed and a Beep() is
49  * issued. The MessageBox() is disabled with a CBT hook.
50  */
51 
52 /*
53  * Helpers
54  */
55 
56 static void create_inf_file(LPCSTR filename, const char *data)
57 {
58  DWORD res;
59  BOOL ret;
64  assert(ret != 0);
66 }
67 
68 /* CBT hook to ensure a window (e.g., MessageBox) cannot be created */
69 static HHOOK hhook;
71 {
72  return nCode == HCBT_CREATEWND ? 1: CallNextHookEx(hhook, nCode, wParam, lParam);
73 }
74 
75 /*
76  * Tests
77  */
78 
79 static const char *cmdline_inf = "[Version]\n"
80  "Signature=\"$Chicago$\"\n"
81  "[DefaultInstall]\n"
82  "AddReg=Add.Settings\n"
83  "[Add.Settings]\n"
84  "HKCU,Software\\Wine\\setupapitest,,\n";
85 
87 {
88  CHAR cmdline[MAX_PATH * 2];
89  WCHAR cmdlinew[MAX_PATH * 2];
90 
91  sprintf(cmdline, "%s %d %s", section, mode, path);
92  MultiByteToWideChar(CP_ACP, 0, cmdline, -1, cmdlinew, MAX_PATH*2);
93  InstallHinfSectionW(NULL, NULL, cmdlinew, 0);
94 }
95 
96 static void ok_registry(BOOL expectsuccess)
97 {
98  LONG ret;
99 
100  /* Functional tests for success of install and clean up */
101  ret = RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Wine\\setupapitest");
102  ok((expectsuccess && ret == ERROR_SUCCESS) ||
103  (!expectsuccess && ret == ERROR_FILE_NOT_FOUND),
104  "Expected registry key Software\\Wine\\setupapitest to %s, RegDeleteKey returned %d\n",
105  expectsuccess ? "exist" : "not exist",
106  ret);
107 }
108 
109 /* Test command line processing */
110 static void test_cmdline(void)
111 {
112  static const char infwithspaces[] = "test file.inf";
113  char path[MAX_PATH];
114  BOOL ret;
115 
117  sprintf(path, "%s\\%s", CURR_DIR, inffile);
118  run_cmdline("DefaultInstall", 128, path);
119  ok_registry(TRUE);
121  ok(ret, "Expected source inf to exist, last error was %d\n", GetLastError());
122 
123  /* Test handling of spaces in path, unquoted and quoted */
124  create_inf_file(infwithspaces, cmdline_inf);
125 
126  sprintf(path, "%s\\%s", CURR_DIR, infwithspaces);
127  run_cmdline("DefaultInstall", 128, path);
128  ok_registry(TRUE);
129 
130  sprintf(path, "\"%s\\%s\"", CURR_DIR, infwithspaces);
131  run_cmdline("DefaultInstall", 128, path);
133 
134  ret = DeleteFileA(infwithspaces);
135  ok(ret, "Expected source inf to exist, last error was %d\n", GetLastError());
136 }
137 
138 static const char *cmdline_inf_reg = "[Version]\n"
139  "Signature=\"$Chicago$\"\n"
140  "[DefaultInstall]\n"
141  "DelReg=Del.Settings\n"
142  "[Del.Settings]\n"
143  "HKCU,Software\\Wine\\setupapitest\n";
144 
145 static void test_registry(void)
146 {
147  HKEY key;
148  LONG res;
149  char path[MAX_PATH];
150  BOOL ret;
151 
152  /* First create a registry structure we would like to be deleted */
153  ok(!RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Wine\\setupapitest\\setupapitest", &key),
154  "Expected RegCreateKeyA to succeed\n");
155 
156  /* Doublecheck if the registry key is present */
157  ok(!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\setupapitest\\setupapitest", &key),
158  "Expected registry key to exist\n");
159 
161  sprintf(path, "%s\\%s", CURR_DIR, inffile);
162  run_cmdline("DefaultInstall", 128, path);
163 
164  /* Check if the registry key is recursively deleted */
165  res = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\setupapitest", &key);
166  ok(res == ERROR_FILE_NOT_FOUND, "Didn't expect the registry key to exist\n");
167  /* Just in case */
168  if (res == ERROR_SUCCESS)
169  {
170  RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Wine\\setupapitest\\setupapitest");
171  RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Wine\\setupapitest");
172  }
174  ok(ret, "Expected source inf to exist, last error was %d\n", GetLastError());
175 }
176 
177 static void test_install_from(void)
178 {
179  char path[MAX_PATH];
180  HINF infhandle;
181  HKEY key;
182  LONG res;
183  BOOL ret;
184 
185  /* First create a registry structure we would like to be deleted */
186  ok(!RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Wine\\setupapitest\\setupapitest", &key),
187  "Expected RegCreateKeyA to succeed\n");
188 
189  /* Doublecheck if the registry key is present */
190  ok(!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\setupapitest\\setupapitest", &key),
191  "Expected registry key to exist\n");
192 
194  sprintf(path, "%s\\%s", CURR_DIR, inffile);
196  SetLastError(0xdeadbeef);
197  ret = SetupInstallFromInfSectionA(NULL, infhandle, "DefaultInstall", SPINST_REGISTRY, key,
198  "A:\\", 0, NULL, NULL, NULL, NULL);
199  ok(ret, "Unexpected failure\n");
200  ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %08x\n", GetLastError());
201 
202  /* Check if the registry key is recursively deleted */
203  res = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\setupapitest", &key);
204  ok(res == ERROR_FILE_NOT_FOUND, "Didn't expect the registry key to exist\n");
205  /* Just in case */
206  if (res == ERROR_SUCCESS)
207  {
208  RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Wine\\setupapitest\\setupapitest");
209  RegDeleteKeyA(HKEY_CURRENT_USER, "Software\\Wine\\setupapitest");
210  }
211 
212  SetupCloseInfFile(infhandle);
214 }
215 
216 static void test_install_svc_from(void)
217 {
218  char inf[2048];
219  char path[MAX_PATH];
220  HINF infhandle;
221  BOOL ret;
222  SC_HANDLE scm_handle, svc_handle;
223 
224  /* Basic inf file to satisfy SetupOpenInfFileA */
225  strcpy(inf, "[Version]\nSignature=\"$Chicago$\"\n");
226  create_inf_file(inffile, inf);
227  sprintf(path, "%s\\%s", CURR_DIR, inffile);
229 
230  /* Nothing but the Version section */
231  SetLastError(0xdeadbeef);
232  ret = SetupInstallServicesFromInfSectionA(infhandle, "Winetest.Services", 0);
233  ok(!ret, "Expected failure\n");
235  "Expected ERROR_SECTION_NOT_FOUND, got %08x\n", GetLastError());
236  SetupCloseInfFile(infhandle);
238 
239  /* Add the section */
240  strcat(inf, "[Winetest.Services]\n");
241  create_inf_file(inffile, inf);
243  SetLastError(0xdeadbeef);
244  ret = SetupInstallServicesFromInfSectionA(infhandle, "Winetest.Services", 0);
245  ok(!ret, "Expected failure\n");
247  "Expected ERROR_SECTION_NOT_FOUND, got %08x\n", GetLastError());
248  SetupCloseInfFile(infhandle);
250 
251  /* Add a reference */
252  strcat(inf, "AddService=Winetest,,Winetest.Service\n");
253  create_inf_file(inffile, inf);
255  SetLastError(0xdeadbeef);
256  ret = SetupInstallServicesFromInfSectionA(infhandle, "Winetest.Services", 0);
257  ok(!ret, "Expected failure\n");
259  "Expected ERROR_BAD_SERVICE_INSTALLSECT, got %08x\n", GetLastError());
260  SetupCloseInfFile(infhandle);
262 
263  /* Add the section */
264  strcat(inf, "[Winetest.Service]\n");
265  create_inf_file(inffile, inf);
267  SetLastError(0xdeadbeef);
268  ret = SetupInstallServicesFromInfSectionA(infhandle, "Winetest.Services", 0);
269  ok(!ret, "Expected failure\n");
271  "Expected ERROR_BAD_SERVICE_INSTALLSECT, got %08x\n", GetLastError());
272  SetupCloseInfFile(infhandle);
274 
275  /* Just the ServiceBinary */
276  strcat(inf, "ServiceBinary=%12%\\winetest.sys\n");
277  create_inf_file(inffile, inf);
279  SetLastError(0xdeadbeef);
280  ret = SetupInstallServicesFromInfSectionA(infhandle, "Winetest.Services", 0);
281  ok(!ret, "Expected failure\n");
283  "Expected ERROR_BAD_SERVICE_INSTALLSECT, got %08x\n", GetLastError());
284  SetupCloseInfFile(infhandle);
286 
287  /* Add the ServiceType */
288  strcat(inf, "ServiceType=1\n");
289  create_inf_file(inffile, inf);
291  SetLastError(0xdeadbeef);
292  ret = SetupInstallServicesFromInfSectionA(infhandle, "Winetest.Services", 0);
293  ok(!ret, "Expected failure\n");
295  "Expected ERROR_BAD_SERVICE_INSTALLSECT, got %08x\n", GetLastError());
296  SetupCloseInfFile(infhandle);
298 
299  /* Add the StartType */
300  strcat(inf, "StartType=4\n");
301  create_inf_file(inffile, inf);
303  SetLastError(0xdeadbeef);
304  ret = SetupInstallServicesFromInfSectionA(infhandle, "Winetest.Services", 0);
305  ok(!ret, "Expected failure\n");
307  "Expected ERROR_BAD_SERVICE_INSTALLSECT, got %08x\n", GetLastError());
308  SetupCloseInfFile(infhandle);
310 
311  /* This should be it, the minimal entries to install a service */
312  strcat(inf, "ErrorControl=1");
313  create_inf_file(inffile, inf);
315  SetLastError(0xdeadbeef);
316  ret = SetupInstallServicesFromInfSectionA(infhandle, "Winetest.Services", 0);
317  if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
318  {
319  skip("Not enough rights to install the service\n");
320  SetupCloseInfFile(infhandle);
322  return;
323  }
324  ok(ret, "Expected success\n");
326  "Expected ERROR_SUCCESS, got %08x\n", GetLastError());
327  SetupCloseInfFile(infhandle);
329 
331 
332  /* Open the service to see if it's really there */
333  svc_handle = OpenServiceA(scm_handle, "Winetest", DELETE);
334  ok(svc_handle != NULL, "Service was not created\n");
335 
336  SetLastError(0xdeadbeef);
337  ret = DeleteService(svc_handle);
338  ok(ret, "Service could not be deleted : %d\n", GetLastError());
339 
340  CloseServiceHandle(svc_handle);
342 
343  strcpy(inf, "[Version]\nSignature=\"$Chicago$\"\n");
344  strcat(inf, "[XSP.InstallPerVer]\n");
345  strcat(inf, "AddReg=AspEventlogMsg.Reg,Perf.Reg,AspVersions.Reg,FreeADO.Reg,IndexServer.Reg\n");
346  create_inf_file(inffile, inf);
347  sprintf(path, "%s\\%s", CURR_DIR, inffile);
349 
350  SetLastError(0xdeadbeef);
351  ret = SetupInstallServicesFromInfSectionA(infhandle, "XSP.InstallPerVer", 0);
352  ok(ret, "Expected success\n");
353  ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %08x\n", GetLastError());
354  SetupCloseInfFile(infhandle);
356 
357  /* TODO: Test the Flags */
358 }
359 
360 static void test_driver_install(void)
361 {
362  HANDLE handle;
363  SC_HANDLE scm_handle, svc_handle;
364  BOOL ret;
365  char path[MAX_PATH], windir[MAX_PATH], driver[MAX_PATH];
366  DWORD attrs;
367  /* Minimal stuff needed */
368  static const char *inf =
369  "[Version]\n"
370  "Signature=\"$Chicago$\"\n"
371  "[DestinationDirs]\n"
372  "Winetest.DriverFiles=12\n"
373  "[DefaultInstall]\n"
374  "CopyFiles=Winetest.DriverFiles\n"
375  "[DefaultInstall.Services]\n"
376  "AddService=Winetest,,Winetest.Service\n"
377  "[Winetest.Service]\n"
378  "ServiceBinary=%12%\\winetest.sys\n"
379  "ServiceType=1\n"
380  "StartType=4\n"
381  "ErrorControl=1\n"
382  "[Winetest.DriverFiles]\n"
383  "winetest.sys";
384 
385  /* Bail out if we don't have enough rights */
386  SetLastError(0xdeadbeef);
389  {
390  skip("Not enough rights to install the service\n");
391  return;
392  }
394 
395  /* Place where we expect the driver to be installed */
397  lstrcpyA(driver, windir);
398  lstrcatA(driver, "\\system32\\drivers\\winetest.sys");
399 
400  /* Create a dummy driver file */
401  handle = CreateFileA("winetest.sys", GENERIC_WRITE, 0, NULL,
404 
405  create_inf_file(inffile, inf);
406  sprintf(path, "%s\\%s", CURR_DIR, inffile);
407  run_cmdline("DefaultInstall", 128, path);
408 
409  /* Driver should have been installed */
410  attrs = GetFileAttributesA(driver);
411  ok(attrs != INVALID_FILE_ATTRIBUTES, "Expected driver to exist\n");
412 
414 
415  /* Open the service to see if it's really there */
416  svc_handle = OpenServiceA(scm_handle, "Winetest", DELETE);
417  ok(svc_handle != NULL, "Service was not created\n");
418 
419  SetLastError(0xdeadbeef);
420  ret = DeleteService(svc_handle);
421  ok(ret, "Service could not be deleted : %d\n", GetLastError());
422 
423  CloseServiceHandle(svc_handle);
425 
426  /* File cleanup */
428  DeleteFileA("winetest.sys");
430 }
431 
432 static void test_profile_items(void)
433 {
434  char path[MAX_PATH], commonprogs[MAX_PATH];
435 
436  static const char *inf =
437  "[Version]\n"
438  "Signature=\"$Chicago$\"\n"
439  "[DefaultInstall]\n"
440  "ProfileItems=TestItem,TestItem2,TestGroup\n"
441  "[TestItem]\n"
442  "Name=TestItem\n"
443  "CmdLine=11,,notepad.exe\n"
444  "[TestItem2]\n"
445  "Name=TestItem2\n"
446  "CmdLine=11,,notepad.exe\n"
447  "SubDir=TestDir\n"
448  "[TestGroup]\n"
449  "Name=TestGroup,4\n"
450  ;
451 
453  {
454  skip("No common program files directory exists\n");
455  goto cleanup;
456  }
457 
458  snprintf(path, MAX_PATH, "%s\\TestDir", commonprogs);
460  {
461  skip("need admin rights\n");
462  return;
463  }
465 
466  create_inf_file(inffile, inf);
467  sprintf(path, "%s\\%s", CURR_DIR, inffile);
468  run_cmdline("DefaultInstall", 128, path);
469 
470  snprintf(path, MAX_PATH, "%s\\TestItem.lnk", commonprogs);
471  snprintf(path, MAX_PATH, "%s\\TestDir", commonprogs);
472  ok(INVALID_FILE_ATTRIBUTES != GetFileAttributesA(path), "directory not created\n");
473  snprintf(path, MAX_PATH, "%s\\TestDir\\TestItem2.lnk", commonprogs);
474  ok(INVALID_FILE_ATTRIBUTES != GetFileAttributesA(path), "link not created\n");
475  snprintf(path, MAX_PATH, "%s\\TestGroup", commonprogs);
476  ok(INVALID_FILE_ATTRIBUTES != GetFileAttributesA(path), "group not created\n");
477 
478  snprintf(path, MAX_PATH, "%s\\TestItem.lnk", commonprogs);
479  DeleteFileA(path);
480  snprintf(path, MAX_PATH, "%s\\TestDir\\TestItem2.lnk", commonprogs);
481  DeleteFileA(path);
482  snprintf(path, MAX_PATH, "%s\\TestItem2.lnk", commonprogs);
483  DeleteFileA(path);
484  snprintf(path, MAX_PATH, "%s\\TestDir", commonprogs);
486  snprintf(path, MAX_PATH, "%s\\TestGroup", commonprogs);
488 
489 cleanup:
491 }
492 
493 static void test_inffilelistA(void)
494 {
495  static const char inffile2[] = "test2.inf";
496  static const char *inf =
497  "[Version]\n"
498  "Signature=\"$Chicago$\"";
499 
500  char buffer[MAX_PATH] = { 0 };
501  char dir[MAX_PATH], *p;
503  BOOL ret;
504 
505  /* create a private directory, the temp directory may contain some
506  * inf files left over from old installations
507  */
508  if (!GetTempFileNameA(CURR_DIR, "inftest", 1, dir))
509  {
510  win_skip("GetTempFileNameA failed with error %d\n", GetLastError());
511  return;
512  }
513  if (!CreateDirectoryA(dir, NULL ))
514  {
515  win_skip("CreateDirectoryA(%s) failed with error %d\n", dir, GetLastError());
516  return;
517  }
519  {
520  win_skip("SetCurrentDirectoryA failed with error %d\n", GetLastError());
522  return;
523  }
524 
525  create_inf_file(inffile, inf);
526  create_inf_file(inffile2, inf);
527 
528  /* mixed style
529  */
530  expected = 3 + strlen(inffile) + strlen(inffile2);
532  MAX_PATH, &outsize);
533  ok(ret, "expected SetupGetInfFileListA to succeed!\n");
534  ok(expected == outsize, "expected required buffersize to be %d, got %d\n",
535  expected, outsize);
536  for(p = buffer; lstrlenA(p) && (outsize > (p - buffer)); p+=lstrlenA(p) + 1)
537  ok(!lstrcmpA(p,inffile2) || !lstrcmpA(p,inffile),
538  "unexpected filename %s\n",p);
539 
541  DeleteFileA(inffile2);
544 }
545 
546 static void test_inffilelist(void)
547 {
548  static const char inffile2[] = "test2.inf";
549  static const WCHAR inffile2W[] = {'t','e','s','t','2','.','i','n','f',0};
550  static const char invalid_inf[] = "invalid.inf";
551  static const WCHAR invalid_infW[] = {'i','n','v','a','l','i','d','.','i','n','f',0};
552  static const char *inf =
553  "[Version]\n"
554  "Signature=\"$Chicago$\"";
555  static const char *inf2 =
556  "[Version]\n"
557  "Signature=\"$CHICAGO$\"";
558  static const char *infNT =
559  "[Version]\n"
560  "Signature=\"$WINDOWS NT$\"";
561 
562  WCHAR *p, *ptr;
563  char dirA[MAX_PATH];
564  WCHAR dir[MAX_PATH] = { 0 };
565  WCHAR buffer[MAX_PATH] = { 0 };
567  BOOL ret;
568 
569  /* NULL means %windir%\\inf
570  * get the value as reference
571  */
572  expected = 0;
573  SetLastError(0xdeadbeef);
575  ok(ret, "expected SetupGetInfFileListW to succeed! Error: %d\n", GetLastError());
576  ok(expected > 0, "expected required buffersize to be at least 1\n");
577 
578  /* check if an empty string doesn't behaves like NULL */
579  outsize = 0;
580  SetLastError(0xdeadbeef);
582  ok(!ret, "expected SetupGetInfFileListW to fail!\n");
583 
584  /* create a private directory, the temp directory may contain some
585  * inf files left over from old installations
586  */
587  if (!GetTempFileNameA(CURR_DIR, "inftest", 1, dirA))
588  {
589  win_skip("GetTempFileNameA failed with error %d\n", GetLastError());
590  return;
591  }
592  if (!CreateDirectoryA(dirA, NULL ))
593  {
594  win_skip("CreateDirectoryA(%s) failed with error %d\n", dirA, GetLastError());
595  return;
596  }
597  if (!SetCurrentDirectoryA(dirA))
598  {
599  win_skip("SetCurrentDirectoryA failed with error %d\n", GetLastError());
600  RemoveDirectoryA(dirA);
601  return;
602  }
603 
604  MultiByteToWideChar(CP_ACP, 0, dirA, -1, dir, MAX_PATH);
605  /* check a not existing directory
606  */
607  ptr = dir + lstrlenW(dir);
608  MultiByteToWideChar(CP_ACP, 0, "\\not_existent", -1, ptr, MAX_PATH - lstrlenW(dir));
609  outsize = 0xffffffff;
610  SetLastError(0xdeadbeef);
612  ok(ret, "expected SetupGetInfFileListW to succeed!\n");
613  ok(outsize == 1, "expected required buffersize to be 1, got %d\n", outsize);
615  "expected error ERROR_PATH_NOT_FOUND, got %d\n", GetLastError());
616 
617  create_inf_file(inffile, inf);
618  create_inf_file(inffile2, inf);
619  create_inf_file(invalid_inf, "This content does not match the inf file format");
620 
621  /* pass a filename instead of a directory
622  */
623  *ptr = '\\';
624  MultiByteToWideChar(CP_ACP, 0, invalid_inf, -1, ptr+1, MAX_PATH - lstrlenW(dir));
625  outsize = 0xffffffff;
626  SetLastError(0xdeadbeef);
628  ok(!ret, "expected SetupGetInfFileListW to fail!\n");
630  "expected error ERROR_DIRECTORY, got %d\n", GetLastError());
631 
632  /* make the filename look like directory
633  */
634  dir[1 + lstrlenW(dir)] = 0;
635  dir[lstrlenW(dir)] = '\\';
636  SetLastError(0xdeadbeef);
638  ok(!ret, "expected SetupGetInfFileListW to fail!\n");
640  "expected error ERROR_DIRECTORY, got %d\n", GetLastError());
641 
642  /* now check the buffer contents of a valid call
643  */
644  *ptr = 0;
645  expected = 3 + strlen(inffile) + strlen(inffile2);
647  ok(ret, "expected SetupGetInfFileListW to succeed!\n");
648  ok(expected == outsize, "expected required buffersize to be %d, got %d\n",
649  expected, outsize);
650  for(p = buffer; lstrlenW(p) && (outsize > (p - buffer)); p+=lstrlenW(p) + 1)
651  ok(!lstrcmpW(p,inffile2W) || !lstrcmpW(p,inffileW),
652  "unexpected filename %s\n",wine_dbgstr_w(p));
653 
654  /* upper case value
655  */
656  create_inf_file(inffile2, inf2);
658  ok(ret, "expected SetupGetInfFileListW to succeed!\n");
659  ok(expected == outsize, "expected required buffersize to be %d, got %d\n",
660  expected, outsize);
661  for(p = buffer; lstrlenW(p) && (outsize > (p - buffer)); p+=lstrlenW(p) + 1)
662  ok(!lstrcmpW(p,inffile2W) || !lstrcmpW(p,inffileW),
663  "unexpected filename %s\n",wine_dbgstr_w(p));
664 
665  /* signature Windows NT is also inf style win4
666  */
667  create_inf_file(inffile2, infNT);
668  expected = 3 + strlen(inffile) + strlen(inffile2);
670  ok(ret, "expected SetupGetInfFileListW to succeed!\n");
671  ok(expected == outsize, "expected required buffersize to be %d, got %d\n",
672  expected, outsize);
673  for(p = buffer; lstrlenW(p) && (outsize > (p - buffer)); p+=lstrlenW(p) + 1)
674  ok(!lstrcmpW(p,inffile2W) || !lstrcmpW(p,inffileW),
675  "unexpected filename %s\n",wine_dbgstr_w(p));
676 
677  /* old style
678  */
679  expected = 2 + strlen(invalid_inf);
681  ok(ret, "expected SetupGetInfFileListW to succeed!\n");
682  ok(expected == outsize, "expected required buffersize to be %d, got %d\n",
683  expected, outsize);
684  for(p = buffer; lstrlenW(p) && (outsize > (p - buffer)); p+=lstrlenW(p) + 1)
685  ok(!lstrcmpW(p,invalid_infW), "unexpected filename %s\n",wine_dbgstr_w(p));
686 
687  /* mixed style
688  */
689  expected = 4 + strlen(inffile) + strlen(inffile2) + strlen(invalid_inf);
691  MAX_PATH, &outsize);
692  ok(ret, "expected SetupGetInfFileListW to succeed!\n");
693  ok(expected == outsize, "expected required buffersize to be %d, got %d\n",
694  expected, outsize);
695  for(p = buffer; lstrlenW(p) && (outsize > (p - buffer)); p+=lstrlenW(p) + 1)
696  ok(!lstrcmpW(p,inffile2W) || !lstrcmpW(p,inffileW) || !lstrcmpW(p,invalid_infW),
697  "unexpected filename %s\n",wine_dbgstr_w(p));
698 
700  DeleteFileA(inffile2);
701  DeleteFileA(invalid_inf);
703  RemoveDirectoryA(dirA);
704 }
705 
706 static const char dirid_inf[] = "[Version]\n"
707  "Signature=\"$Chicago$\"\n"
708  "[DefaultInstall]\n"
709  "AddReg=Add.Settings\n"
710  "[Add.Settings]\n"
711  "HKCU,Software\\Wine\\setupapitest,dirid,,%%%i%%\n";
712 
713 static void check_dirid(int dirid, LPCSTR expected)
714 {
715  char buffer[sizeof(dirid_inf)+11];
716  char path[MAX_PATH], actual[MAX_PATH];
717  LONG ret;
718  DWORD size, type;
719  HKEY key;
720 
721  sprintf(buffer, dirid_inf, dirid);
722 
724 
725  sprintf(path, "%s\\%s", CURR_DIR, inffile);
726  run_cmdline("DefaultInstall", 128, path);
727 
728  size = sizeof(actual);
729  actual[0] = '\0';
730  ret = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\setupapitest", &key);
731  if (ret == ERROR_SUCCESS)
732  {
733  ret = RegQueryValueExA(key, "dirid", NULL, &type, (BYTE*)&actual, &size);
734  RegCloseKey(key);
735  if (type != REG_SZ)
737  }
738 
739  ok(ret == ERROR_SUCCESS, "Failed getting value for dirid %i, err=%d\n", dirid, ret);
740  ok(!strcmp(actual, expected), "Expected path for dirid %i was \"%s\", got \"%s\"\n", dirid, expected, actual);
741 
742  ok_registry(TRUE);
744  ok(ret, "Expected source inf to exist, last error was %d\n", GetLastError());
745 }
746 
747 /* Test dirid values */
748 static void test_dirid(void)
749 {
750  char expected[MAX_PATH];
751 
752  check_dirid(DIRID_NULL, "");
753 
756 
759 
760  strcat(expected, "\\unknown");
761  check_dirid(40, expected);
762 }
763 
765 {
766  char temp_path[MAX_PATH], prev_path[MAX_PATH];
767  DWORD len;
768 
769  GetCurrentDirectoryA(MAX_PATH, prev_path);
772 
774  len = strlen(CURR_DIR);
775  if(len && (CURR_DIR[len - 1] == '\\'))
776  CURR_DIR[len - 1] = 0;
777 
778  /* Set CBT hook to disallow MessageBox creation in current thread */
780  assert(hhook != 0);
781 
782  test_cmdline();
783  test_registry();
787  test_dirid();
788 
790 
791  /* We have to run this test after the CBT hook is disabled because
792  ProfileItems needs to create a window on Windows XP. */
794 
797 
798  SetCurrentDirectoryA(prev_path);
799 }
static HHOOK hhook
Definition: install.c:69
DWORD size
Definition: install.c:3631
static const char * cmdline_inf_reg
Definition: install.c:138
LONG WINAPI RegOpenKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3272
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
LONG WINAPI RegQueryValueExA(_In_ HKEY hkeyorg, _In_ LPCSTR name, _In_ LPDWORD reserved, _Out_opt_ LPDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ LPDWORD count)
Definition: reg.c:4041
#define GENERIC_ALL
Definition: nt_native.h:92
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED LPLOOKUPSERVICE_COMPLETION_ROUTINE HANDLE * handle
Definition: sock.c:82
#define ERROR_SECTION_NOT_FOUND
Definition: setupapi.h:288
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
#define HCBT_CREATEWND
Definition: winuser.h:58
#define INF_STYLE_WIN4
Definition: infsupp.h:41
#define ERROR_SUCCESS
Definition: deptool.c:10
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
int install
Definition: msacm.c:1353
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
static SC_HANDLE scm_handle
Definition: ServiceArgs.c:20
#define CP_ACP
Definition: compat.h:99
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
#define HKEY_CURRENT_USER
Definition: winreg.h:11
char CHAR
Definition: xmlstorage.h:175
static void test_cmdline(void)
Definition: install.c:110
#define INF_STYLE_OLDNT
Definition: infsupp.h:37
#define CALLBACK
Definition: compat.h:27
#define wine_dbgstr_w
Definition: kernel32.h:34
UINT WINAPI GetSystemDirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2282
#define snprintf
Definition: wintirpc.h:48
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
#define assert(x)
Definition: debug.h:53
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
static void run_cmdline(LPCSTR section, int mode, LPCSTR path)
Definition: install.c:86
GLuint buffer
Definition: glext.h:5915
UINT_PTR WPARAM
Definition: windef.h:207
TCHAR * cmdline
Definition: stretchblt.cpp:32
static void test_profile_items(void)
Definition: install.c:432
Definition: parser.c:55
BOOL WINAPI DeleteService(SC_HANDLE hService)
Definition: scm.c:916
#define DIRID_SYSTEM
Definition: setupapi.h:188
const char * filename
Definition: ioapi.h:135
#define ERROR_DIRECTORY
Definition: winerror.h:295
#define lstrlenW
Definition: compat.h:407
BOOL WINAPI SetupInstallServicesFromInfSectionA(HINF Inf, PCSTR SectionName, DWORD Flags)
Definition: install.c:1617
WPARAM wParam
Definition: combotst.c:138
VOID WINAPI SetupCloseInfFile(IN HINF InfHandle)
Definition: infsupp.c:43
#define CSIDL_COMMON_PROGRAMS
Definition: shlobj.h:2025
static void ok_registry(BOOL expectsuccess)
Definition: install.c:96
#define sprintf(buf, format,...)
Definition: sprintf.c:55
HHOOK WINAPI SetWindowsHookExA(_In_ int, _In_ HOOKPROC, _In_opt_ HINSTANCE, _In_ DWORD)
#define DIRID_NULL
Definition: setupapi.h:185
BOOL WINAPI SetupGetInfFileListW(IN PCWSTR DirectoryPath OPTIONAL, IN DWORD InfStyle, IN OUT PWSTR ReturnBuffer OPTIONAL, IN DWORD ReturnBufferSize OPTIONAL, OUT PDWORD RequiredSize OPTIONAL)
Definition: parser.c:2139
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
SC_HANDLE WINAPI OpenSCManagerA(LPCSTR lpMachineName, LPCSTR lpDatabaseName, DWORD dwDesiredAccess)
Definition: scm.c:1967
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
void WINAPI InstallHinfSectionW(HWND hwnd, HINSTANCE handle, LPCWSTR cmdline, INT show)
Definition: install.c:1461
DWORD WINAPI GetFileAttributesA(LPCSTR lpFileName)
Definition: fileinfo.c:786
#define GENERIC_WRITE
Definition: nt_native.h:90
static PVOID ptr
Definition: dispmode.c:27
#define ok(value,...)
BOOL WINAPI CloseServiceHandle(SC_HANDLE hSCObject)
Definition: scm.c:577
#define DIRID_WINDOWS
Definition: setupapi.h:187
#define SPINST_REGISTRY
Definition: setupapi.h:585
BOOL WINAPI CreateDirectoryA(IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:37
smooth NULL
Definition: ftsmooth.c:416
LONG_PTR LPARAM
Definition: windef.h:208
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
#define WH_CBT
Definition: winuser.h:35
unsigned int dir
Definition: maze.c:112
const char * LPCSTR
Definition: xmlstorage.h:183
BOOL WINAPI SetupInstallFromInfSectionA(HWND owner, HINF hinf, PCSTR section, UINT flags, HKEY key_root, PCSTR src_root, UINT copy_flags, PSP_FILE_CALLBACK_A callback, PVOID context, HDEVINFO devinfo, PSP_DEVINFO_DATA devinfo_data)
Definition: install.c:1252
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
LONG WINAPI RegCreateKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1180
DWORD WINAPI GetCurrentThreadId(VOID)
Definition: thread.c:421
static const char inffile[]
Definition: install.c:37
static const char dirid_inf[]
Definition: install.c:706
static LRESULT CALLBACK cbt_hook_proc(int nCode, WPARAM wParam, LPARAM lParam)
Definition: install.c:70
LPSTR WINAPI lstrcatA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:123
GLsizeiptr size
Definition: glext.h:5919
#define ERROR_BAD_SERVICE_INSTALLSECT
Definition: setupapi.h:314
__wchar_t WCHAR
Definition: xmlstorage.h:180
static void check_dirid(int dirid, LPCSTR expected)
Definition: install.c:713
#define MAX_PATH
Definition: compat.h:26
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:409
unsigned char unsigned long * outsize
Definition: jpeglib.h:979
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
static void test_registry(void)
Definition: install.c:145
int ret
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
static char CURR_DIR[MAX_PATH]
Definition: install.c:39
HKEY key
Definition: reg.c:42
BOOL WINAPI SetCurrentDirectoryA(IN LPCSTR lpPathName)
Definition: path.c:2205
static void create_inf_file(LPCSTR filename, const char *data)
Definition: install.c:56
GLenum GLsizei len
Definition: glext.h:6722
unsigned char BYTE
Definition: mem.h:68
GLenum mode
Definition: glext.h:6217
BOOL WINAPI UnhookWindowsHookEx(_In_ HHOOK)
HINF WINAPI SetupOpenInfFileA(PCSTR name, PCSTR class, DWORD style, UINT *error)
Definition: parser.c:1139
LONG WINAPI RegDeleteKeyA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey)
Definition: reg.c:1225
static void test_dirid(void)
Definition: install.c:748
#define S_OK
Definition: intsafe.h:59
#define CREATE_ALWAYS
Definition: disk.h:72
LRESULT WINAPI CallNextHookEx(_In_opt_ HHOOK, _In_ int, _In_ WPARAM, _In_ LPARAM)
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2053
static void test_inffilelist(void)
Definition: install.c:546
HRESULT WINAPI SHGetFolderPathA(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPSTR pszPath)
Definition: shellpath.c:2326
DWORD WINAPI GetCurrentDirectoryA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2145
Definition: services.c:325
UINT WINAPI GetWindowsDirectoryA(OUT LPSTR lpBuffer, IN UINT uSize)
Definition: path.c:2336
BOOL WINAPI RemoveDirectoryA(IN LPCSTR lpPathName)
Definition: dir.c:714
static void test_install_svc_from(void)
Definition: install.c:216
static const char * cmdline_inf
Definition: install.c:79
#define MultiByteToWideChar
Definition: compat.h:100
#define skip(...)
SC_HANDLE WINAPI OpenServiceA(SC_HANDLE hSCManager, LPCSTR lpServiceName, DWORD dwDesiredAccess)
Definition: scm.c:2055
BOOL WINAPI SetupGetInfFileListA(IN PCSTR DirectoryPath OPTIONAL, IN DWORD InfStyle, IN OUT PSTR ReturnBuffer OPTIONAL, IN DWORD ReturnBufferSize OPTIONAL, OUT PDWORD RequiredSize OPTIONAL)
Definition: parser.c:2272
static const WCHAR inffileW[]
Definition: install.c:38
GLuint res
Definition: glext.h:9613
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
static void test_driver_install(void)
Definition: install.c:360
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
char * cleanup(char *str)
Definition: wpickclick.c:99
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:399
START_TEST(install)
Definition: install.c:285
GLfloat GLfloat p
Definition: glext.h:8902
LONG_PTR LRESULT
Definition: windef.h:209
#define win_skip
Definition: test.h:141
LPARAM lParam
Definition: combotst.c:139
UINT WINAPI GetTempFileNameA(IN LPCSTR lpPathName, IN LPCSTR lpPrefixString, IN UINT uUnique, OUT LPSTR lpTempFileName)
Definition: filename.c:26
struct @1596::@1597 driver
BOOL expected
Definition: store.c:2063
#define DELETE
Definition: nt_native.h:57
Definition: path.c:42
static void test_install_from(void)
Definition: install.c:177
char temp_path[MAX_PATH]
Definition: mspatcha.c:123
static void test_inffilelistA(void)
Definition: install.c:493
#define REG_SZ
Definition: layer.c:22