Advertisement
Guest User

ntdll use unix pipes for synchronization objects

a guest
Apr 13th, 2014
54
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.49 KB | None | 0 0
  1. --- wine-rt-1.6.1.orig/dlls/advapi32/service.c
  2. +++ wine-rt-1.6.1/dlls/advapi32/service.c
  3. @@ -460,6 +460,11 @@ static BOOL service_run_main_thread(void
  4. HANDLE wait_handles[MAXIMUM_WAIT_OBJECTS];
  5. UINT wait_services[MAXIMUM_WAIT_OBJECTS];
  6. dispatcher_data *disp = HeapAlloc( GetProcessHeap(), 0, sizeof(*disp) );
  7. + WCHAR en[] = { 's','r','v','t','h','r','d','X','X','X','X',0 };
  8. + int hashNum;
  9. + WCHAR *hashLoc = en + 7;
  10. + unsigned int seed;
  11. + struct timeval tv;
  12.  
  13. disp->manager = OpenSCManagerW( NULL, NULL, SC_MANAGER_CONNECT );
  14. if (!disp->manager)
  15. @@ -479,8 +484,22 @@ static BOOL service_run_main_thread(void
  16. return FALSE;
  17. }
  18.  
  19. - service_event = CreateEventW( NULL, FALSE, FALSE, NULL );
  20. - stop_event = CreateEventW( NULL, FALSE, FALSE, NULL );
  21. + // Hash the name to avoid collisions between services.exe and rm-host.exe
  22. + gettimeofday(&tv, 0);
  23. + seed = (unsigned int)(tv.tv_sec * 1000 + tv.tv_usec / 1000);
  24. + while (*hashLoc != 0) {
  25. + hashNum = (rand_r(&seed) >> 16) % 62;
  26. + if (hashNum < 10)
  27. + *hashLoc = '0'+hashNum;
  28. + else if (hashNum < 36)
  29. + *hashLoc = 'a'+hashNum-10;
  30. + else
  31. + *hashLoc = 'A'+hashNum-36;
  32. + hashLoc++;
  33. + }
  34. +
  35. + service_event = CreateEventW( NULL, FALSE, FALSE, en );
  36. + stop_event = CreateEventW( NULL, FALSE, FALSE, en );
  37.  
  38. /* FIXME: service_control_dispatcher should be merged into the main thread */
  39. wait_handles[0] = __wine_make_process_system();
  40. --- wine-rt-1.6.1.orig/dlls/ntdll/heap.c
  41. +++ wine-rt-1.6.1/dlls/ntdll/heap.c
  42. @@ -44,6 +44,7 @@
  43. #include "wine/list.h"
  44. #include "wine/debug.h"
  45. #include "wine/server.h"
  46. +#include "ntdll_misc.h"
  47.  
  48. WINE_DEFAULT_DEBUG_CHANNEL(heap);
  49.  
  50. @@ -177,6 +178,8 @@ static HEAP *processHeap; /* main proce
  51.  
  52. static BOOL HEAP_IsRealArena( HEAP *heapPtr, DWORD flags, LPCVOID block, BOOL quiet );
  53.  
  54. +static PIPEOBJ processHeapSemaphore;
  55. +
  56. /* mark a block of memory as free for debugging purposes */
  57. static inline void mark_block_free( void *ptr, SIZE_T size, DWORD flags )
  58. {
  59. @@ -1564,6 +1567,11 @@ HANDLE WINAPI RtlCreateHeap( ULONG flags
  60. }
  61. else if (!addr)
  62. {
  63. + if (use_pipe_objects()) {
  64. + init_pipe_object(&processHeapSemaphore, SEMAPHORE_MAGIC, 0);
  65. + subheap->heap->critSection.LockSemaphore = &processHeapSemaphore;
  66. + }
  67. +
  68. processHeap = subheap->heap; /* assume the first heap we create is the process main heap */
  69. list_init( &processHeap->entry );
  70. }
  71. --- wine-rt-1.6.1.orig/dlls/ntdll/ntdll_misc.h
  72. +++ wine-rt-1.6.1/dlls/ntdll/ntdll_misc.h
  73. @@ -185,6 +185,22 @@ extern int ntdll_wcstoumbs(DWORD flags,
  74. extern int CDECL NTDLL__vsnprintf( char *str, SIZE_T len, const char *format, __ms_va_list args ) DECLSPEC_HIDDEN;
  75. extern int CDECL NTDLL__vsnwprintf( WCHAR *str, SIZE_T len, const WCHAR *format, __ms_va_list args ) DECLSPEC_HIDDEN;
  76.  
  77. +#define EVENT_MAGIC 0x4556
  78. +#define SEMAPHORE_MAGIC 0x5373
  79. +#define MUTEX_MAGIC 0x4D55
  80. +
  81. +typedef struct _PIPEOBJ
  82. +{
  83. + WORD wMagic;
  84. + int fd[2]; /* Pipe handles */
  85. + struct _PIPEOBJ* next;
  86. + struct _PIPEOBJ* prev;
  87. +} PIPEOBJ, *LPPIPEOBJ;
  88. +
  89. +extern NTSTATUS close_pipe_object(HANDLE handle, BOOL freemem);
  90. +extern NTSTATUS init_pipe_object(LPPIPEOBJ pobj, WORD type, int signaled);
  91. +extern BOOL use_pipe_objects(void);
  92. +
  93. /* load order */
  94.  
  95. enum loadorder
  96. --- wine-rt-1.6.1.orig/dlls/ntdll/om.c
  97. +++ wine-rt-1.6.1/dlls/ntdll/om.c
  98. @@ -373,6 +373,9 @@ NTSTATUS close_handle( HANDLE handle )
  99. */
  100. NTSTATUS WINAPI NtClose( HANDLE Handle )
  101. {
  102. + if (HIWORD(Handle) != 0 && close_pipe_object(Handle, TRUE) == STATUS_SUCCESS && use_pipe_objects())
  103. + return(STATUS_SUCCESS);
  104. +
  105. return close_handle( Handle );
  106. }
  107.  
  108. --- wine-rt-1.6.1.orig/dlls/ntdll/sync.c
  109. +++ wine-rt-1.6.1/dlls/ntdll/sync.c
  110. @@ -47,6 +47,8 @@
  111. #include <stdio.h>
  112. #include <stdlib.h>
  113. #include <time.h>
  114. +#include <fcntl.h>
  115. +
  116.  
  117. #define NONAMELESSUNION
  118. #define NONAMELESSSTRUCT
  119. @@ -133,6 +135,244 @@ void NTDLL_free_struct_sd(struct securit
  120. RtlFreeHeap(GetProcessHeap(), 0, server_sd);
  121. }
  122.  
  123. +#define is_pipe_object(h) (h != INVALID_HANDLE_VALUE && HIWORD(h) != 0)
  124. +#define is_pipe_event(h) (is_pipe_object(h) && ((LPPIPEOBJ)h)->wMagic == EVENT_MAGIC)
  125. +#define is_pipe_semaphore(h) (is_pipe_object(h) && ((LPPIPEOBJ)h)->wMagic == SEMAPHORE_MAGIC)
  126. +#define is_pipe_mutex(h) (is_pipe_object(h) && ((LPPIPEOBJ)h)->wMagic == MUTEX_MAGIC)
  127. +
  128. +static CRITICAL_SECTION csPipeObjs;
  129. +static CRITICAL_SECTION_DEBUG critsect_debug =
  130. +{
  131. + 0, 0, &csPipeObjs,
  132. + { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
  133. + 0, 0, { (DWORD_PTR)(__FILE__ ": csPipeObjs") }
  134. +};
  135. +static CRITICAL_SECTION csPipeObjs = { &critsect_debug, -1, 0, 0, 0, 0 };
  136. +
  137. +static LPPIPEOBJ pipeobjs;
  138. +static int pipe_count;
  139. +
  140. +/******************************************************************************
  141. + * use_pipe_objects
  142. + */
  143. +BOOL use_pipe_objects(void)
  144. +{
  145. + static const char* s_enable_pipe_sync = 0;
  146. + if (s_enable_pipe_sync == 0) {
  147. + const char* env;
  148. + extern int __wine_main_argc;
  149. + extern char** __wine_main_argv;
  150. +
  151. + s_enable_pipe_sync = "0";
  152. + env = getenv("L_ENABLE_PIPE_SYNC_FOR_APP");
  153. + if (env) {
  154. + /* note: PEB command line is not available when this is first called so use main args */
  155. + if (__wine_main_argc < 2)
  156. + ERR("bad __wine_main_argc: %d\n", __wine_main_argc);
  157. + else if (strstr(__wine_main_argv[1], env) != 0) {
  158. + MESSAGE("Honoring L_ENABLE_PIPE_SYNC_FOR_APP: %s (%s)\n", env, __wine_main_argv[1]);
  159. + s_enable_pipe_sync = "1";
  160. + }
  161. + }
  162. + }
  163. + return(*s_enable_pipe_sync != '0');
  164. +}
  165. +
  166. +/******************************************************************************
  167. + * is_valid_pipe_object
  168. + */
  169. +BOOL is_valid_pipe_object(HANDLE handle)
  170. +{
  171. + BOOL valid = FALSE;
  172. + LPPIPEOBJ p = (LPPIPEOBJ) pipeobjs;
  173. +
  174. + RtlEnterCriticalSection(&csPipeObjs);
  175. + while (p)
  176. + {
  177. + if (p == handle)
  178. + {
  179. + valid = TRUE;
  180. + break;
  181. + }
  182. +
  183. + p = p->next;
  184. + }
  185. + RtlLeaveCriticalSection(&csPipeObjs);
  186. +
  187. + TRACE("%p valid=%d\n", handle, valid);
  188. +
  189. + return valid;
  190. +}
  191. +
  192. +
  193. +
  194. +/******************************************************************************
  195. + * close_pipe_object
  196. + */
  197. +NTSTATUS close_pipe_object(HANDLE handle, BOOL freemem)
  198. +{
  199. + NTSTATUS ret = STATUS_SUCCESS;
  200. +
  201. + TRACE("%p\n", handle);
  202. +
  203. + if (is_valid_pipe_object(handle) &&
  204. + (is_pipe_event(handle) ||
  205. + is_pipe_semaphore(handle) ||
  206. + is_pipe_mutex(handle)))
  207. +
  208. + {
  209. + LPPIPEOBJ pobj = (LPPIPEOBJ) handle;
  210. +
  211. + close(pobj->fd[0]);
  212. + close(pobj->fd[1]);
  213. + pobj->wMagic = 0;
  214. +
  215. + RtlEnterCriticalSection(&csPipeObjs);
  216. + if (pobj->next)
  217. + pobj->next->prev = pobj->prev;
  218. + if (pobj->prev)
  219. + pobj->prev->next = pobj->next;
  220. + if (pipeobjs == pobj)
  221. + pipeobjs = pobj->next;
  222. + pipe_count--;
  223. + RtlLeaveCriticalSection(&csPipeObjs);
  224. +
  225. + if (freemem)
  226. + RtlFreeHeap(GetProcessHeap(), 0, pobj);
  227. + }
  228. + else
  229. + ret = STATUS_INVALID_HANDLE;
  230. +
  231. + return ret;
  232. +}
  233. +
  234. +
  235. +/******************************************************************************
  236. + * wait_for_pipe_object
  237. + */
  238. +static NTSTATUS wait_for_pipe_object(LPPIPEOBJ pobj, const LARGE_INTEGER *timeout, int clear)
  239. +{
  240. + char c;
  241. + NTSTATUS ret;
  242. + struct pollfd pfd;
  243. + int tm;
  244. +
  245. + pfd.fd = pobj->fd[0];
  246. + pfd.events = POLLIN;
  247. + pfd.revents = 0;
  248. +
  249. + if (!timeout)
  250. + tm = -1;
  251. + else
  252. + tm = (-timeout->QuadPart) / (ULONGLONG)10000;
  253. +
  254. + TRACE("%p timeout=%d\n", pobj, tm);
  255. +
  256. + if (poll(&pfd, 1, tm) == -1)
  257. + ret = WAIT_FAILED;
  258. + else if (pfd.revents & POLLIN)
  259. + {
  260. + ret = WAIT_OBJECT_0;
  261. +
  262. + TRACE("pipe object signaled before time out\n");
  263. + if (clear)
  264. + {
  265. + if (read(pobj->fd[0], &c, 1) != 1) /* Clear the signal */
  266. + {
  267. + ERR("Failed to clear pipe object\n");
  268. + ret = WAIT_FAILED;
  269. + }
  270. + }
  271. + }
  272. + else
  273. + {
  274. + TRACE("pipe object timed out\n");
  275. + ret = WAIT_TIMEOUT;
  276. + }
  277. +
  278. + return ret;
  279. +}
  280. +
  281. +
  282. +static NTSTATUS create_pipe_object(HANDLE *h, WORD type, int signaled)
  283. +{
  284. + NTSTATUS ret;
  285. + LPPIPEOBJ pobj = RtlAllocateHeap(GetProcessHeap(), 0, sizeof(PIPEOBJ));
  286. +
  287. + ret = init_pipe_object(pobj, type, signaled);
  288. + if (ret)
  289. + RtlFreeHeap(GetProcessHeap(), 0, pobj);
  290. + else
  291. + *h = (HANDLE)pobj;
  292. +
  293. + return ret;
  294. +}
  295. +
  296. +NTSTATUS init_pipe_object(LPPIPEOBJ pobj, WORD type, int signaled)
  297. +{
  298. + NTSTATUS ret = STATUS_SUCCESS;
  299. +
  300. + pobj->wMagic = type;
  301. +
  302. + if (pipe(pobj->fd) < 0)
  303. + {
  304. + ERR("failed to create pipe object\n");
  305. + return STATUS_NO_MEMORY; /* Most likely reached fd limit */
  306. + }
  307. +
  308. + fcntl(pobj->fd[0], F_SETFL, O_NONBLOCK);
  309. + fcntl(pobj->fd[1], F_SETFL, O_NONBLOCK);
  310. +
  311. + if (signaled)
  312. + {
  313. + if (write(pobj->fd[1], "s", 1) != 1)
  314. + {
  315. + close_pipe_object(pobj, FALSE);
  316. + ERR("failed to signal pipe object\n");
  317. + ret = STATUS_UNSUCCESSFUL;
  318. + }
  319. + }
  320. +
  321. + if (SUCCEEDED(ret))
  322. + {
  323. + RtlEnterCriticalSection(&csPipeObjs);
  324. + pobj->prev = 0;
  325. + pobj->next = pipeobjs;
  326. + if (pipeobjs)
  327. + pipeobjs->prev = pobj;
  328. + pipeobjs = pobj;
  329. + pipe_count++;
  330. + RtlLeaveCriticalSection(&csPipeObjs);
  331. + }
  332. +
  333. + TRACE("handle=%p type 0x%04x ret=0x%08d pipe count=%d\n", pobj, type, ret, pipe_count);
  334. +
  335. + return ret;
  336. +}
  337. +
  338. +
  339. +static NTSTATUS signal_pipe_object(LPPIPEOBJ pobj)
  340. +{
  341. + LARGE_INTEGER timeout;
  342. +
  343. + ZeroMemory(&timeout, sizeof(timeout));
  344. +
  345. + if (wait_for_pipe_object(pobj, &timeout, 0) == WAIT_TIMEOUT)
  346. + {
  347. + if (write(pobj->fd[1], "s", 1) != 1)
  348. + {
  349. + ERR("Failed to signal pipe object %p\n", pobj);
  350. + return STATUS_UNSUCCESSFUL;
  351. + }
  352. + /* don't starve other same priority threads on same fd */
  353. + sched_yield();
  354. + }
  355. +
  356. + TRACE("%p signaled\n", pobj);
  357. +
  358. + return STATUS_SUCCESS;
  359. +}
  360. +
  361. /*
  362. * Semaphores
  363. */
  364. @@ -151,6 +391,9 @@ NTSTATUS WINAPI NtCreateSemaphore( OUT P
  365. struct object_attributes objattr;
  366. struct security_descriptor *sd = NULL;
  367.  
  368. + TRACE("Max Count=%ld InitialCount = %ld\n", MaximumCount, InitialCount);
  369. +
  370. +
  371. if (MaximumCount <= 0 || InitialCount < 0 || InitialCount > MaximumCount)
  372. return STATUS_INVALID_PARAMETER;
  373. if (len >= MAX_PATH * sizeof(WCHAR)) return STATUS_NAME_TOO_LONG;
  374. @@ -164,19 +407,25 @@ NTSTATUS WINAPI NtCreateSemaphore( OUT P
  375. if (ret != STATUS_SUCCESS) return ret;
  376. }
  377.  
  378. - SERVER_START_REQ( create_semaphore )
  379. + if (!len && MaximumCount == 1 && use_pipe_objects())
  380. {
  381. - req->access = access;
  382. - req->attributes = (attr) ? attr->Attributes : 0;
  383. - req->initial = InitialCount;
  384. - req->max = MaximumCount;
  385. - wine_server_add_data( req, &objattr, sizeof(objattr) );
  386. - if (objattr.sd_len) wine_server_add_data( req, sd, objattr.sd_len );
  387. - if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len );
  388. - ret = wine_server_call( req );
  389. - *SemaphoreHandle = wine_server_ptr_handle( reply->handle );
  390. + ret = create_pipe_object(SemaphoreHandle, SEMAPHORE_MAGIC, InitialCount);
  391. + }
  392. + else {
  393. + SERVER_START_REQ( create_semaphore )
  394. + {
  395. + req->access = access;
  396. + req->attributes = (attr) ? attr->Attributes : 0;
  397. + req->initial = InitialCount;
  398. + req->max = MaximumCount;
  399. + wine_server_add_data( req, &objattr, sizeof(objattr) );
  400. + if (objattr.sd_len) wine_server_add_data( req, sd, objattr.sd_len );
  401. + if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len );
  402. + ret = wine_server_call( req );
  403. + *SemaphoreHandle = wine_server_ptr_handle( reply->handle );
  404. + }
  405. + SERVER_END_REQ;
  406. }
  407. - SERVER_END_REQ;
  408.  
  409. NTDLL_free_struct_sd( sd );
  410.  
  411. @@ -229,6 +478,12 @@ NTSTATUS WINAPI NtQuerySemaphore(
  412. NTSTATUS WINAPI NtReleaseSemaphore( HANDLE handle, ULONG count, PULONG previous )
  413. {
  414. NTSTATUS ret;
  415. +
  416. + TRACE("%p\n", handle);
  417. +
  418. + if (is_pipe_semaphore(handle))
  419. + return signal_pipe_object((LPPIPEOBJ)handle);
  420. +
  421. SERVER_START_REQ( release_semaphore )
  422. {
  423. req->handle = wine_server_obj_handle( handle );
  424. @@ -269,19 +524,27 @@ NTSTATUS WINAPI NtCreateEvent( PHANDLE E
  425. if (ret != STATUS_SUCCESS) return ret;
  426. }
  427.  
  428. - SERVER_START_REQ( create_event )
  429. + /* Use pipe for anonymous auto-reset event */
  430. + if (!len && type != NotificationEvent /* !ManualReset, see req below */ && use_pipe_objects())
  431. {
  432. - req->access = DesiredAccess;
  433. - req->attributes = (attr) ? attr->Attributes : 0;
  434. - req->manual_reset = (type == NotificationEvent);
  435. - req->initial_state = InitialState;
  436. - wine_server_add_data( req, &objattr, sizeof(objattr) );
  437. - if (objattr.sd_len) wine_server_add_data( req, sd, objattr.sd_len );
  438. - if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len );
  439. - ret = wine_server_call( req );
  440. - *EventHandle = wine_server_ptr_handle( reply->handle );
  441. + ret = create_pipe_object(EventHandle, EVENT_MAGIC, InitialState);
  442. + }
  443. + else
  444. + {
  445. + SERVER_START_REQ( create_event )
  446. + {
  447. + req->access = DesiredAccess;
  448. + req->attributes = (attr) ? attr->Attributes : 0;
  449. + req->manual_reset = (type == NotificationEvent);
  450. + req->initial_state = InitialState;
  451. + wine_server_add_data( req, &objattr, sizeof(objattr) );
  452. + if (objattr.sd_len) wine_server_add_data( req, sd, objattr.sd_len );
  453. + if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len );
  454. + ret = wine_server_call( req );
  455. + *EventHandle = wine_server_ptr_handle( reply->handle );
  456. + }
  457. + SERVER_END_REQ;
  458. }
  459. - SERVER_END_REQ;
  460.  
  461. NTDLL_free_struct_sd( sd );
  462.  
  463. @@ -324,6 +587,11 @@ NTSTATUS WINAPI NtSetEvent( HANDLE handl
  464. {
  465. NTSTATUS ret;
  466.  
  467. + TRACE("%p\n", handle);
  468. +
  469. + if (is_pipe_event(handle))
  470. + return signal_pipe_object((LPPIPEOBJ)handle);
  471. +
  472. /* FIXME: set NumberOfThreadsReleased */
  473.  
  474. SERVER_START_REQ( event_op )
  475. @@ -443,6 +711,8 @@ NTSTATUS WINAPI NtCreateMutant(OUT HANDL
  476.  
  477. if (len >= MAX_PATH * sizeof(WCHAR)) return STATUS_NAME_TOO_LONG;
  478.  
  479. + TRACE("\n");
  480. +
  481. objattr.rootdir = wine_server_obj_handle( attr ? attr->RootDirectory : 0 );
  482. objattr.sd_len = 0;
  483. objattr.name_len = len;
  484. @@ -452,18 +722,25 @@ NTSTATUS WINAPI NtCreateMutant(OUT HANDL
  485. if (status != STATUS_SUCCESS) return status;
  486. }
  487.  
  488. - SERVER_START_REQ( create_mutex )
  489. + if (!len && use_pipe_objects())
  490. {
  491. - req->access = access;
  492. - req->attributes = (attr) ? attr->Attributes : 0;
  493. - req->owned = InitialOwner;
  494. - wine_server_add_data( req, &objattr, sizeof(objattr) );
  495. - if (objattr.sd_len) wine_server_add_data( req, sd, objattr.sd_len );
  496. - if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len );
  497. - status = wine_server_call( req );
  498. - *MutantHandle = wine_server_ptr_handle( reply->handle );
  499. + status = create_pipe_object(MutantHandle, MUTEX_MAGIC, !InitialOwner);
  500. + }
  501. + else
  502. + {
  503. + SERVER_START_REQ( create_mutex )
  504. + {
  505. + req->access = access;
  506. + req->attributes = (attr) ? attr->Attributes : 0;
  507. + req->owned = InitialOwner;
  508. + wine_server_add_data( req, &objattr, sizeof(objattr) );
  509. + if (objattr.sd_len) wine_server_add_data( req, sd, objattr.sd_len );
  510. + if (len) wine_server_add_data( req, attr->ObjectName->Buffer, len );
  511. + status = wine_server_call( req );
  512. + *MutantHandle = wine_server_ptr_handle( reply->handle );
  513. + }
  514. + SERVER_END_REQ;
  515. }
  516. - SERVER_END_REQ;
  517.  
  518. NTDLL_free_struct_sd( sd );
  519.  
  520. @@ -504,6 +781,11 @@ NTSTATUS WINAPI NtReleaseMutant( IN HAND
  521. {
  522. NTSTATUS status;
  523.  
  524. + TRACE("%p\n", handle);
  525. +
  526. + if (is_pipe_mutex(handle))
  527. + return signal_pipe_object((LPPIPEOBJ)handle);
  528. +
  529. SERVER_START_REQ( release_mutex )
  530. {
  531. req->handle = wine_server_obj_handle( handle );
  532. @@ -826,7 +1108,22 @@ NTSTATUS WINAPI NtWaitForMultipleObjects
  533. {
  534. select_op_t select_op;
  535. UINT i, flags = SELECT_INTERRUPTIBLE;
  536. + int j;
  537. +
  538. + TRACE("count=%ld handles=%p wait_all=%d alertable=%d timeout=%p %lld\n", count, handles, wait_all, alertable, timeout, timeout ? timeout->QuadPart : -1);
  539.  
  540. + if (count == 1 && is_pipe_object(handles[0]))
  541. + return wait_for_pipe_object((LPPIPEOBJ)*handles, timeout, 1);
  542. + for (j = 0; j < count; ++j) {
  543. + if (is_pipe_object(handles[j])) {
  544. + static int s_once = 1;
  545. + if (s_once) {
  546. + ERR("Cannot wait on both pipe objects and multiple objects (only warning!); j=%d, count=%d, handle=%x\n", j, count, (unsigned int) handles[j]);
  547. + s_once = 0;
  548. + }
  549. + return STATUS_INVALID_PARAMETER_2;
  550. + }
  551. + }
  552. if (!count || count > MAXIMUM_WAIT_OBJECTS) return STATUS_INVALID_PARAMETER_1;
  553.  
  554. if (alertable) flags |= SELECT_ALERTABLE;
  555. --- wine-rt-1.6.1.orig/dlls/rpcrt4/rpc_transport.c
  556. +++ wine-rt-1.6.1/dlls/rpcrt4/rpc_transport.c
  557. @@ -637,9 +637,30 @@ typedef struct _RpcServerProtseq_np
  558.  
  559. static RpcServerProtseq *rpcrt4_protseq_np_alloc(void)
  560. {
  561. + WCHAR n[] = { 'r','p','c','m','e','X','X','X','X',0 };
  562. RpcServerProtseq_np *ps = HeapAlloc(GetProcessHeap(), 0, sizeof(*ps));
  563. + int hashNum;
  564. + WCHAR *hashLoc = n + 5;
  565. + unsigned int seed;
  566. + struct timeval tv;
  567. +
  568. + // Hash the name to avoid collisions between services.exe and rm-host.exe
  569. + gettimeofday(&tv, 0);
  570. + seed = (unsigned int)(tv.tv_sec * 1000 + tv.tv_usec / 1000);
  571. + while (*hashLoc != 0) {
  572. + hashNum = (rand_r(&seed) >> 16) % 62;
  573. + if (hashNum < 10)
  574. + *hashLoc = '0'+hashNum;
  575. + else if (hashNum < 36)
  576. + *hashLoc = 'a'+hashNum-10;
  577. + else
  578. + *hashLoc = 'A'+hashNum-36;
  579. + hashLoc++;
  580. + }
  581. +
  582. if (ps)
  583. - ps->mgr_event = CreateEventW(NULL, FALSE, FALSE, NULL);
  584. + ps->mgr_event = CreateEventW(NULL, FALSE, FALSE, n);
  585. +
  586. return &ps->common;
  587. }
  588.  
  589. --- wine-rt-1.6.1.orig/programs/winedevice/device.c
  590. +++ wine-rt-1.6.1/programs/winedevice/device.c
  591. @@ -286,11 +286,12 @@ static DWORD WINAPI service_handler( DWO
  592.  
  593. static void WINAPI ServiceMain( DWORD argc, LPWSTR *argv )
  594. {
  595. + WCHAR en[] = { 'w','d','s','e',0 };
  596. SERVICE_STATUS status;
  597.  
  598. WINE_TRACE( "starting service %s\n", wine_dbgstr_w(driver_name) );
  599.  
  600. - stop_event = CreateEventW( NULL, TRUE, FALSE, NULL );
  601. + stop_event = CreateEventW( NULL, TRUE, FALSE, en );
  602.  
  603. service_handle = RegisterServiceCtrlHandlerExW( driver_name, service_handler, NULL );
  604. if (!service_handle)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement