~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/shlwapi/thread.c

Version: ~ [ wine-1.5.30 ] ~ [ wine-1.5.29 ] ~ [ wine-1.5.28 ] ~ [ wine-1.5.27 ] ~ [ wine-1.5.26 ] ~ [ wine-1.5.25 ] ~ [ wine-1.5.24 ] ~ [ wine-1.5.23 ] ~ [ wine-1.5.22 ] ~ [ wine-1.5.21 ] ~ [ wine-1.5.20 ] ~ [ wine-1.5.19 ] ~ [ wine-1.5.18 ] ~ [ wine-1.5.17 ] ~ [ wine-1.5.16 ] ~ [ wine-1.5.15 ] ~ [ wine-1.5.14 ] ~ [ wine-1.5.13 ] ~ [ wine-1.5.12 ] ~ [ wine-1.5.11 ] ~ [ wine-1.5.10 ] ~ [ wine-1.5.9 ] ~ [ wine-1.5.8 ] ~ [ wine-1.5.7 ] ~ [ wine-1.4.1 ] ~ [ wine-1.5.6 ] ~ [ wine-1.5.5 ] ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  * SHLWAPI thread and MT synchronisation functions
  3  *
  4  * Copyright 2002 Juergen Schmied
  5  * Copyright 2002 Jon Griffiths
  6  *
  7  * This library is free software; you can redistribute it and/or
  8  * modify it under the terms of the GNU Lesser General Public
  9  * License as published by the Free Software Foundation; either
 10  * version 2.1 of the License, or (at your option) any later version.
 11  *
 12  * This library is distributed in the hope that it will be useful,
 13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 15  * Lesser General Public License for more details.
 16  *
 17  * You should have received a copy of the GNU Lesser General Public
 18  * License along with this library; if not, write to the Free Software
 19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 20  */
 21 #include <stdarg.h>
 22 #include <string.h>
 23 
 24 #define COBJMACROS
 25 
 26 #include "windef.h"
 27 #include "winbase.h"
 28 #include "winnls.h"
 29 #include "winuser.h"
 30 #define NO_SHLWAPI_REG
 31 #define NO_SHLWAPI_PATH
 32 #define NO_SHLWAPI_GDI
 33 #define NO_SHLWAPI_STREAM
 34 #define NO_SHLWAPI_USER
 35 #include "shlwapi.h"
 36 #include "shlobj.h"
 37 #include "wine/debug.h"
 38 
 39 WINE_DEFAULT_DEBUG_CHANNEL(shell);
 40 
 41 extern DWORD SHLWAPI_ThreadRef_index;  /* Initialised in shlwapi_main.c */
 42 
 43 INT WINAPI SHStringFromGUIDA(REFGUID,LPSTR,INT);
 44 
 45 /**************************************************************************
 46  *      CreateAllAccessSecurityAttributes       [SHLWAPI.356]
 47  *
 48  * Initialise security attributes from a security descriptor.
 49  *
 50  * PARAMS
 51  *  lpAttr [O] Security attributes
 52  *  lpSec  [I] Security descriptor
 53  *
 54  * RETURNS
 55  *  Success: lpAttr, initialised using lpSec.
 56  *  Failure: NULL, if any parameters are invalid.
 57  *
 58  * NOTES
 59  *  This function always returns NULL if the underlying OS version
 60  *  Wine is impersonating does not use security descriptors (i.e. anything
 61  *  before Windows NT).
 62  */
 63 LPSECURITY_ATTRIBUTES WINAPI CreateAllAccessSecurityAttributes(
 64         LPSECURITY_ATTRIBUTES lpAttr,
 65         PSECURITY_DESCRIPTOR lpSec,
 66         DWORD p3)
 67 {
 68   /* This function is used within SHLWAPI only to create security attributes
 69    * for shell semaphores. */
 70 
 71   TRACE("(%p,%p,%08x)\n", lpAttr, lpSec, p3);
 72 
 73   if (!(GetVersion() & 0x80000000))  /* NT */
 74   {
 75     if (!lpSec || !lpAttr)
 76       return NULL;
 77 
 78     if (InitializeSecurityDescriptor(lpSec, 1))
 79     {
 80       if (SetSecurityDescriptorDacl(lpSec, TRUE, NULL, FALSE))
 81       {
 82          lpAttr->nLength = sizeof(SECURITY_ATTRIBUTES);
 83          lpAttr->lpSecurityDescriptor = lpSec;
 84          lpAttr->bInheritHandle = FALSE;
 85          return lpAttr;
 86       }
 87     }
 88   }
 89   return NULL;
 90 }
 91 
 92 /*************************************************************************
 93  *      _SHGetInstanceExplorer  [SHLWAPI.@]
 94  *
 95  * Get an interface to the shell explorer.
 96  *
 97  * PARAMS
 98  *  lppUnknown [O] Destination for explorers IUnknown interface.
 99  *
100  * RETURNS
101  *  Success: S_OK. lppUnknown contains the explorer interface.
102  *  Failure: An HRESULT error code.
103  */
104 HRESULT WINAPI _SHGetInstanceExplorer(IUnknown **lppUnknown)
105 {
106   /* This function is used within SHLWAPI only to hold the IE reference
107    * for threads created with the CTF_PROCESS_REF flag set. */
108     return SHGetInstanceExplorer(lppUnknown);
109 }
110 
111 /* Internal thread information structure */
112 typedef struct tagSHLWAPI_THREAD_INFO
113 {
114   LPTHREAD_START_ROUTINE pfnThreadProc; /* Thread start */
115   LPTHREAD_START_ROUTINE pfnCallback;   /* Thread initialisation */
116   PVOID     pData;                      /* Application specific data */
117   BOOL      bInitCom;                   /* Initialise COM for the thread? */
118   HANDLE    hEvent;                     /* Signal for creator to continue */
119   IUnknown *refThread;                  /* Reference to thread creator */
120   IUnknown *refIE;                      /* Reference to the IE process */
121 } SHLWAPI_THREAD_INFO, *LPSHLWAPI_THREAD_INFO;
122 
123 
124 /*************************************************************************
125  * SHGetThreadRef       [SHLWAPI.@]
126  *
127  * Get a per-thread object reference set by SHSetThreadRef().
128  *
129  * PARAMS
130  *   lppUnknown [O] Destination to receive object reference
131  *
132  * RETURNS
133  *   Success: S_OK. lppUnknown is set to the object reference.
134  *   Failure: E_NOINTERFACE, if an error occurs or lppUnknown is NULL.
135  */
136 HRESULT WINAPI SHGetThreadRef(IUnknown **lppUnknown)
137 {
138   TRACE("(%p)\n", lppUnknown);
139 
140   if (!lppUnknown || SHLWAPI_ThreadRef_index == TLS_OUT_OF_INDEXES)
141     return E_NOINTERFACE;
142 
143   *lppUnknown = TlsGetValue(SHLWAPI_ThreadRef_index);
144   if (!*lppUnknown)
145     return E_NOINTERFACE;
146 
147   /* Add a reference. Caller will Release() us when finished */
148   IUnknown_AddRef(*lppUnknown);
149   return S_OK;
150 }
151 
152 /*************************************************************************
153  * SHSetThreadRef       [SHLWAPI.@]
154  *
155  * Store a per-thread object reference.
156  *
157  * PARAMS
158  *   lpUnknown [I] Object reference to store
159  *
160  * RETURNS
161  *   Success: S_OK. lpUnknown is stored and can be retrieved by SHGetThreadRef()
162  *   Failure: E_NOINTERFACE, if an error occurs or lpUnknown is NULL.
163  */
164 HRESULT WINAPI SHSetThreadRef(IUnknown *lpUnknown)
165 {
166   TRACE("(%p)\n", lpUnknown);
167 
168   if (!lpUnknown || SHLWAPI_ThreadRef_index  == TLS_OUT_OF_INDEXES)
169     return E_NOINTERFACE;
170 
171   TlsSetValue(SHLWAPI_ThreadRef_index, lpUnknown);
172   return S_OK;
173 }
174 
175 /*************************************************************************
176  * SHReleaseThreadRef   [SHLWAPI.@]
177  *
178  * Release a per-thread object reference.
179  *
180  * PARAMS
181  *  None.
182  *
183  * RETURNS
184  *   Success: S_OK. The threads object reference is released.
185  *   Failure: An HRESULT error code.
186  */
187 HRESULT WINAPI SHReleaseThreadRef(void)
188 {
189   FIXME("() - stub!\n");
190   return S_OK;
191 }
192 
193 /*************************************************************************
194  * SHLWAPI_ThreadWrapper
195  *
196  * Internal wrapper for executing user thread functions from SHCreateThread.
197  */
198 static DWORD WINAPI SHLWAPI_ThreadWrapper(PVOID pTi)
199 {
200   SHLWAPI_THREAD_INFO ti;
201   HRESULT hCom = E_FAIL;
202   DWORD dwRet;
203 
204   TRACE("(%p)\n", pTi);
205 
206   /* We are now executing in the context of the newly created thread.
207    * So we copy the data passed to us (it is on the stack of the function
208    * that called us, which is waiting for us to signal an event before
209    * returning). */
210   memcpy(&ti, pTi, sizeof(SHLWAPI_THREAD_INFO));
211 
212   /* Initialise COM for the thread, if desired */
213   if (ti.bInitCom)
214   {
215     hCom = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED|COINIT_DISABLE_OLE1DDE);
216 
217     if (FAILED(hCom))
218       hCom = CoInitializeEx(NULL, COINIT_DISABLE_OLE1DDE);
219   }
220 
221   /* Execute the callback function before returning */
222   if (ti.pfnCallback)
223     ti.pfnCallback(ti.pData);
224 
225   /* Signal the thread that created us; it can return now */
226   SetEvent(ti.hEvent);
227 
228   /* Execute the callers start code */
229   dwRet = ti.pfnThreadProc(ti.pData);
230 
231   /* Release references to the caller and IE process, if held */
232   if (ti.refThread)
233     IUnknown_Release(ti.refThread);
234 
235   if (ti.refIE)
236     IUnknown_Release(ti.refIE);
237 
238   if (SUCCEEDED(hCom))
239     CoUninitialize();
240 
241   /* Return the users thread return value */
242   return dwRet;
243 }
244 
245 /*************************************************************************
246  *      SHCreateThread  [SHLWAPI.16]
247  *
248  * Create a new thread.
249  *
250  * PARAMS
251  *   pfnThreadProc [I] Function to execute in new thread
252  *   pData         [I] Application specific data passed to pfnThreadProc
253  *   dwFlags       [I] CTF_ flags from "shlwapi.h"
254  *   pfnCallback   [I] Function to execute before pfnThreadProc
255  *
256  * RETURNS
257  *   Success: TRUE. pfnThreadProc was executed.
258  *   Failure: FALSE. pfnThreadProc was not executed.
259  *
260  * NOTES
261  *   If the thread cannot be created, pfnCallback is NULL, and dwFlags
262  *   has bit CTF_INSIST set, pfnThreadProc will be executed synchronously.
263  */
264 BOOL WINAPI SHCreateThread(LPTHREAD_START_ROUTINE pfnThreadProc, VOID *pData,
265                            DWORD dwFlags, LPTHREAD_START_ROUTINE pfnCallback)
266 {
267   SHLWAPI_THREAD_INFO ti;
268   BOOL bCalled = FALSE;
269 
270   TRACE("(%p,%p,0x%X,%p)\n", pfnThreadProc, pData, dwFlags, pfnCallback);
271 
272   /* Set up data to pass to the new thread (On our stack) */
273   ti.pfnThreadProc = pfnThreadProc;
274   ti.pfnCallback = pfnCallback;
275   ti.pData = pData;
276   ti.bInitCom = dwFlags & CTF_COINIT ? TRUE : FALSE;
277   ti.hEvent = CreateEventW(NULL,FALSE,FALSE,NULL);
278 
279   /* Hold references to the current thread and IE process, if desired */
280   if(dwFlags & CTF_THREAD_REF)
281     SHGetThreadRef(&ti.refThread);
282   else
283     ti.refThread = NULL;
284 
285   if(dwFlags & CTF_PROCESS_REF)
286     _SHGetInstanceExplorer(&ti.refIE);
287   else
288     ti.refIE = NULL;
289 
290   /* Create the thread */
291   if(ti.hEvent)
292   {
293     DWORD dwRetVal;
294     HANDLE hThread;
295 
296     hThread = CreateThread(NULL, 0, SHLWAPI_ThreadWrapper, &ti, 0, &dwRetVal);
297 
298     if(hThread)
299     {
300       /* Wait for the thread to signal us to continue */
301       WaitForSingleObject(ti.hEvent, INFINITE);
302       CloseHandle(hThread);
303       bCalled = TRUE;
304     }
305     CloseHandle(ti.hEvent);
306   }
307 
308   if (!bCalled)
309   {
310     if (!ti.pfnCallback && dwFlags & CTF_INSIST)
311     {
312       /* Couldn't call, call synchronously */
313       pfnThreadProc(pData);
314       bCalled = TRUE;
315     }
316     else
317     {
318       /* Free references, since thread hasn't run to do so */
319       if(ti.refThread)
320         IUnknown_Release(ti.refThread);
321 
322       if(ti.refIE)
323         IUnknown_Release(ti.refIE);
324     }
325   }
326   return bCalled;
327 }
328 
329 /*************************************************************************
330  *      SHGlobalCounterGetValue [SHLWAPI.223]
331  *
332  * Get the current count of a semaphore.
333  *
334  * PARAMS
335  *  hSem [I] Semaphore handle
336  *
337  * RETURNS
338  *  The current count of the semaphore.
339  */
340 LONG WINAPI SHGlobalCounterGetValue(HANDLE hSem)
341 {
342   LONG dwOldCount = 0;
343 
344   TRACE("(%p)\n", hSem);
345   ReleaseSemaphore(hSem, 1, &dwOldCount); /* +1 */
346   WaitForSingleObject(hSem, 0);           /* -1 */
347   return dwOldCount;
348 }
349 
350 /*************************************************************************
351  *      SHGlobalCounterIncrement        [SHLWAPI.224]
352  *
353  * Claim a semaphore.
354  *
355  * PARAMS
356  *  hSem [I] Semaphore handle
357  *
358  * RETURNS
359  *  The new count of the semaphore.
360  */
361 LONG WINAPI SHGlobalCounterIncrement(HANDLE hSem)
362 {
363   LONG dwOldCount = 0;
364 
365   TRACE("(%p)\n", hSem);
366   ReleaseSemaphore(hSem, 1, &dwOldCount);
367   return dwOldCount + 1;
368 }
369 
370 /*************************************************************************
371  *      SHGlobalCounterDecrement        [SHLWAPI.424]
372  *
373  * Release a semaphore.
374  *
375  * PARAMS
376  *  hSem [I] Semaphore handle
377  *
378  * RETURNS
379  *  The new count of the semaphore.
380  */
381 DWORD WINAPI SHGlobalCounterDecrement(HANDLE hSem)
382 {
383   DWORD dwOldCount = 0;
384 
385   TRACE("(%p)\n", hSem);
386 
387   dwOldCount = SHGlobalCounterGetValue(hSem);
388   WaitForSingleObject(hSem, 0);
389   return dwOldCount - 1;
390 }
391 
392 /*************************************************************************
393  *      SHGlobalCounterCreateNamedW     [SHLWAPI.423]
394  *
395  * Unicode version of SHGlobalCounterCreateNamedA.
396  */
397 HANDLE WINAPI SHGlobalCounterCreateNamedW(LPCWSTR lpszName, DWORD iInitial)
398 {
399   static const WCHAR szPrefix[] = { 's', 'h', 'e', 'l', 'l', '.', '\0' };
400   const int iPrefixLen = 6;
401   WCHAR szBuff[MAX_PATH];
402   const int iBuffLen = sizeof(szBuff)/sizeof(WCHAR);
403   SECURITY_DESCRIPTOR sd;
404   SECURITY_ATTRIBUTES sAttr, *pSecAttr;
405   HANDLE hRet;
406 
407   TRACE("(%s,%d)\n", debugstr_w(lpszName), iInitial);
408 
409   /* Create Semaphore name */
410   memcpy(szBuff, szPrefix, (iPrefixLen + 1) * sizeof(WCHAR));
411   if (lpszName)
412     StrCpyNW(szBuff + iPrefixLen, lpszName, iBuffLen - iPrefixLen);
413 
414   /* Initialise security attributes */
415   pSecAttr = CreateAllAccessSecurityAttributes(&sAttr, &sd, 0);
416 
417   if (!(hRet = CreateSemaphoreW(pSecAttr , iInitial, MAXLONG, szBuff)))
418     hRet = OpenSemaphoreW(SYNCHRONIZE|SEMAPHORE_MODIFY_STATE, 0, szBuff);
419   return hRet;
420 }
421 
422 /*************************************************************************
423  *      SHGlobalCounterCreateNamedA     [SHLWAPI.422]
424  *
425  * Create a semaphore.
426  *
427  * PARAMS
428  *  lpszName [I] Name of semaphore
429  *  iInitial [I] Initial count for semaphore
430  *
431  * RETURNS
432  *  A new semaphore handle.
433  */
434 HANDLE WINAPI SHGlobalCounterCreateNamedA(LPCSTR lpszName, DWORD iInitial)
435 {
436   WCHAR szBuff[MAX_PATH];
437 
438   TRACE("(%s,%d)\n", debugstr_a(lpszName), iInitial);
439 
440   if (lpszName)
441     MultiByteToWideChar(0, 0, lpszName, -1, szBuff, MAX_PATH);
442   return SHGlobalCounterCreateNamedW(lpszName ? szBuff : NULL, iInitial);
443 }
444 
445 /*************************************************************************
446  *      SHGlobalCounterCreate   [SHLWAPI.222]
447  *
448  * Create a semaphore using the name of a GUID.
449  *
450  * PARAMS
451  *  guid [I] GUID to use as semaphore name
452  *
453  * RETURNS
454  *  A handle to the semaphore.
455  *
456  * NOTES
457  *  The initial count of the semaphore is set to 0.
458  */
459 HANDLE WINAPI SHGlobalCounterCreate (REFGUID guid)
460 {
461   char szName[40];
462 
463   TRACE("(%s)\n", debugstr_guid(guid));
464 
465   /* Create a named semaphore using the GUID string */
466   SHStringFromGUIDA(guid, szName, sizeof(szName) - 1);
467   return SHGlobalCounterCreateNamedA(szName, 0);
468 }
469 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.