Optimized include/*.h: (recursively) include all headers needed by
[wine/testsucceed.git] / misc / ddeml.c
blobebc7bda323c2155995d36d3901cc448e5be8978d
1 /*
2 * DDEML library
4 * Copyright 1997 Alexandre Julliard
5 * Copyright 1997 Len White
6 * Copyright 1999 Keith Matthews
7 */
9 /* Only empty stubs for now */
11 #include <stdlib.h>
12 #include <strings.h>
13 #include "ddeml.h"
14 #include "debug.h"
15 #include "windows.h"
16 #include "wintypes.h"
17 #include "winerror.h"
18 #include "heap.h"
19 #include "shm_semaph.h"
21 /* Has defined in atom.c file.
23 #define MAX_ATOM_LEN 255
25 /* Maximum buffer size ( including the '\0' ).
27 #define MAX_BUFFER_LEN (MAX_ATOM_LEN + 1)
30 static DDE_HANDLE_ENTRY *DDE_Handle_Table_Base = NULL;
31 static LPDWORD DDE_Max_Assigned_Instance = 0; // OK for present, may have to worry about wrap-around later
32 static const char inst_string[]= "DDEMaxInstance";
33 static LPCWSTR DDEInstanceAccess = (LPCWSTR)&inst_string;
34 static const char handle_string[] = "DDEHandleAccess";
35 static LPCWSTR DDEHandleAccess = (LPCWSTR)&handle_string;
36 static HANDLE32 inst_count_mutex = 0;
37 static HANDLE32 handle_mutex = 0;
38 DDE_HANDLE_ENTRY *this_instance;
39 SECURITY_ATTRIBUTES *s_att= NULL;
40 DWORD err_no = 0;
42 /* typedef struct {
43 DWORD nLength;
44 LPVOID lpSecurityDescriptor;
45 BOOL32 bInheritHandle;
46 } SECURITY_ATTRIBUTES; */
48 #define TRUE 1
49 #define FALSE 0
53 /* This is a simple list to keep track of the strings created
54 * by DdeCreateStringHandle. The list is used to free
55 * the strings whenever DdeUninitialize is called.
56 * This mechanism is not complete and does not handle multiple instances.
57 * Most of the DDE API use a DWORD parameter indicating which instance
58 * of a given program is calling them. The API are supposed to
59 * associate the data to the instance that created it.
61 typedef struct tagHSZNode HSZNode;
62 struct tagHSZNode
64 HSZNode* next;
65 HSZ hsz;
68 /* Start off the list pointer with a NULL.
70 static HSZNode* pHSZNodes = NULL;
73 /******************************************************************************
74 * RemoveHSZNodes (INTERNAL)
76 * Remove a node from the list of HSZ nodes.
78 ******************************************************************************
80 * Change History
82 * Vn Date Author Comment
84 * 1.0 Dec 1998 Corel/Macadamian Initial version
87 static void RemoveHSZNode( DWORD idInst, HSZ hsz )
89 HSZNode* pPrev = NULL;
90 HSZNode* pCurrent = NULL;
92 /* Set the current node at the start of the list.
94 pCurrent = pHSZNodes;
95 /* While we have more nodes.
97 while( pCurrent != NULL )
99 /* If we found the node we were looking for.
101 if( pCurrent->hsz == hsz )
103 /* Remove the node.
105 /* If the first node in the list is to to be removed.
106 * Set the global list pointer to the next node.
108 if( pCurrent == pHSZNodes )
110 pHSZNodes = pCurrent->next;
112 /* Just fix the pointers has to skip the current
113 * node so we can delete it.
115 else
117 pPrev->next = pCurrent->next;
119 /* Destroy this node.
121 free( pCurrent );
122 break;
124 /* Save the previous node pointer.
126 pPrev = pCurrent;
127 /* Move on to the next node.
129 pCurrent = pCurrent->next;
133 /******************************************************************************
134 * FreeAndRemoveHSZNodes (INTERNAL)
136 * Frees up all the strings still allocated in the list and
137 * remove all the nodes from the list of HSZ nodes.
139 ******************************************************************************
141 * Change History
143 * Vn Date Author Comment
145 * 1.0 Dec 1998 Corel/Macadamian Initial version
148 static void FreeAndRemoveHSZNodes( DWORD idInst )
150 /* Free any strings created in this instance.
152 while( pHSZNodes != NULL )
154 DdeFreeStringHandle32( idInst, pHSZNodes->hsz );
158 /******************************************************************************
159 * InsertHSZNode (INTERNAL)
161 * Insert a node to the head of the list.
163 ******************************************************************************
165 * Change History
167 * Vn Date Author Comment
169 * 1.0 Dec 1998 Corel/Macadamian Initial version
172 static void InsertHSZNode( DWORD idInst, HSZ hsz )
174 if( hsz != 0 )
176 HSZNode* pNew = NULL;
177 /* Create a new node for this HSZ.
179 pNew = (HSZNode*) malloc( sizeof( HSZNode ) );
180 if( pNew != NULL )
182 /* Set the handle value.
184 pNew->hsz = hsz;
185 /* Attach the node to the head of the list.
187 pNew->next = pHSZNodes;
188 /* The new node is now at the head of the list
189 * so set the global list pointer to it.
191 pHSZNodes = pNew;
196 /******************************************************************************
197 * Release_reserved_mutex
199 * generic routine to release a reserved mutex
202 ******************************************************************************
204 * Change History
206 * Vn Date Author Comment
208 * 1.0 Jan 1999 Keith Matthews Initial version
211 DWORD Release_reserved_mutex (HANDLE32 mutex, LPTSTR mutex_name, BOOL32 release_handle_m, BOOL32 release_this_i )
213 ReleaseMutex(mutex);
214 if ( (err_no=GetLastError()) != 0 )
216 ERR(ddeml,"ReleaseMutex failed - %s mutex %li\n",mutex_name,err_no);
217 HeapFree(GetProcessHeap(), 0, this_instance);
218 if ( release_handle_m )
220 ReleaseMutex(handle_mutex);
222 return DMLERR_SYS_ERROR;
224 if ( release_this_i )
226 HeapFree(GetProcessHeap(), 0, this_instance);
228 return DMLERR_NO_ERROR;
231 /******************************************************************************
232 * IncrementInstanceId
234 * generic routine to increment the max instance Id and allocate a new application instance
236 ******************************************************************************
238 * Change History
240 * Vn Date Author Comment
242 * 1.0 Jan 1999 Keith Matthews Initial version
245 DWORD IncrementInstanceId()
247 SECURITY_ATTRIBUTES s_attrib;
248 /* Need to set up Mutex in case it is not already present */
249 // increment handle count & get value
250 if ( !inst_count_mutex )
252 s_attrib.bInheritHandle = TRUE;
253 s_attrib.lpSecurityDescriptor = NULL;
254 s_attrib.nLength = sizeof(s_attrib);
255 inst_count_mutex = CreateMutex32W(&s_attrib,1,DDEInstanceAccess); // 1st time through
256 } else {
257 WaitForSingleObject(inst_count_mutex,1000); // subsequent calls
258 /* FIXME - needs refinement with popup for timeout, also is timeout interval OK */
260 if ( (err_no=GetLastError()) == ERROR_INVALID_HANDLE )
262 ERR(ddeml,"CreateMutex failed - inst_count %li\n",err_no);
263 err_no=Release_reserved_mutex (handle_mutex,"handle_mutex",0,1);
264 return DMLERR_SYS_ERROR;
266 DDE_Max_Assigned_Instance++;
267 this_instance->Instance_id = DDE_Max_Assigned_Instance;
268 if (Release_reserved_mutex(inst_count_mutex,"instance_count",1,0)) return DMLERR_SYS_ERROR;
269 return DMLERR_NO_ERROR;
272 /******************************************************************************
273 * DdeInitialize16 (DDEML.2)
275 UINT16 WINAPI DdeInitialize16( LPDWORD pidInst, PFNCALLBACK16 pfnCallback,
276 DWORD afCmd, DWORD ulRes)
278 return (UINT16)DdeInitialize32A(pidInst,(PFNCALLBACK32)pfnCallback,
279 afCmd, ulRes);
283 /******************************************************************************
284 * DdeInitialize32A (USER32.106)
286 UINT32 WINAPI DdeInitialize32A( LPDWORD pidInst, PFNCALLBACK32 pfnCallback,
287 DWORD afCmd, DWORD ulRes )
289 return DdeInitialize32W(pidInst,pfnCallback,afCmd,ulRes);
293 /******************************************************************************
294 * DdeInitialize32W [USER32.107]
295 * Registers an application with the DDEML
297 * PARAMS
298 * pidInst [I] Pointer to instance identifier
299 * pfnCallback [I] Pointer to callback function
300 * afCmd [I] Set of command and filter flags
301 * ulRes [I] Reserved
303 * RETURNS
304 * Success: DMLERR_NO_ERROR
305 * Failure: DMLERR_DLL_USAGE, DMLERR_INVALIDPARAMETER, DMLERR_SYS_ERROR
307 ******************************************************************************
309 * Change History
311 * Vn Date Author Comment
313 * 1.0 Pre 1998 Alexandre/Len Initial Stub
314 * 1.1 Jan 1999 Keith Matthews Initial (near-)complete version
317 UINT32 WINAPI DdeInitialize32W( LPDWORD pidInst, PFNCALLBACK32 pfnCallback,
318 DWORD afCmd, DWORD ulRes )
320 DDE_HANDLE_ENTRY *reference_inst;
321 SECURITY_ATTRIBUTES s_attrib;
322 s_att = &s_attrib;
324 // probably not really capable of handling mutliple processes, but should handle
325 // multiple instances within one process
327 if( ulRes )
329 ERR(dde, "Reserved value not zero? What does this mean?\n");
330 FIXME(ddeml, "(%p,%p,0x%lx,%ld): stub\n",pidInst,pfnCallback,afCmd,ulRes);
331 /* trap this and no more until we know more */
332 return DMLERR_NO_ERROR;
334 if (!pfnCallback )
336 /* can't set up the instance with nothing to act as a callback */
337 TRACE(ddeml,"No callback provided\n");
338 return DMLERR_INVALIDPARAMETER; /* might be DMLERR_DLL_USAGE */
341 /* grab enough heap for one control struct - not really necessary for re-initialise
342 but allows us to use same validation routines */
343 this_instance= (DDE_HANDLE_ENTRY*)HeapAlloc( SystemHeap, 0, sizeof(DDE_HANDLE_ENTRY) );
344 if ( this_instance == NULL )
346 // catastrophe !! warn user & abort
347 ERR (ddeml,"Instance create failed - out of memory\n");
348 return DMLERR_SYS_ERROR;
350 this_instance->Next_Entry = NULL;
351 this_instance->Monitor=(afCmd|APPCLASS_MONITOR);
353 // messy bit, spec implies that 'Client Only' can be set in 2 different ways, catch 1 here
355 this_instance->Client_only=afCmd&APPCMD_CLIENTONLY;
356 this_instance->Instance_id = pidInst; // May need to add calling proc Id
357 this_instance->CallBack=*pfnCallback;
358 this_instance->Txn_count=0;
359 this_instance->Unicode = TRUE;
360 this_instance->Win16 = FALSE;
361 this_instance->Monitor_flags = afCmd & MF_MASK;
363 // isolate CBF flags in one go, expect this will go the way of all attempts to be clever !!
365 this_instance->CBF_Flags=afCmd^((afCmd&MF_MASK)|((afCmd&APPCMD_MASK)|(afCmd&APPCLASS_MASK)));
367 if ( ! this_instance->Client_only )
370 // Check for other way of setting Client-only !!
372 this_instance->Client_only=(this_instance->CBF_Flags&CBF_FAIL_ALLSVRXACTIONS)
373 ==CBF_FAIL_ALLSVRXACTIONS;
376 TRACE(ddeml,"instance created - checking validity \n");
378 if( *pidInst == 0 ) {
379 /* Initialisation of new Instance Identifier */
380 TRACE(ddeml,"new instance, callback %p flags %lX\n",pfnCallback,afCmd);
381 /* Need to set up Mutex in case it is not already present */
382 s_att->bInheritHandle = TRUE;
383 s_att->lpSecurityDescriptor = NULL;
384 s_att->nLength = sizeof(s_att);
385 handle_mutex = CreateMutex32W(s_att,1,DDEHandleAccess);
386 if ( (err_no=GetLastError()) == ERROR_INVALID_HANDLE )
388 ERR(ddeml,"CreateMutex failed - handle list %li\n",err_no);
389 HeapFree(GetProcessHeap(), 0, this_instance);
390 return DMLERR_SYS_ERROR;
392 TRACE(ddeml,"Handle Mutex created/reserved\n");
393 if (DDE_Handle_Table_Base == NULL )
395 /* can't be another instance in this case, assign to the base pointer */
396 DDE_Handle_Table_Base= this_instance;
398 // since first must force filter of XTYP_CONNECT and XTYP_WILDCONNECT for
399 // present
400 // ------------------------------- NOTE NOTE NOTE --------------------------
402 // the manual is not clear if this condition
403 // applies to the first call to DdeInitialize from an application, or the
404 // first call for a given callback !!!
407 this_instance->CBF_Flags=this_instance->CBF_Flags|APPCMD_FILTERINITS;
408 TRACE(ddeml,"First application instance detected OK\n");
409 // allocate new instance ID
410 if ((err_no = IncrementInstanceId()) ) return err_no;
411 } else {
412 /* really need to chain the new one in to the latest here, but after checking conditions
413 such as trying to start a conversation from an application trying to monitor */
414 reference_inst = DDE_Handle_Table_Base;
415 TRACE(ddeml,"Subsequent application instance - starting checks\n");
416 while ( reference_inst->Next_Entry != NULL )
419 // This set of tests will work if application uses same instance Id
420 // at application level once allocated - which is what manual implies
421 // should happen. If someone tries to be
422 // clever (lazy ?) it will fail to pick up that later calls are for
423 // the same application - should we trust them ?
425 if ( this_instance->Instance_id == reference_inst->Instance_id)
427 // Check 1 - must be same Client-only state
429 if ( this_instance->Client_only != reference_inst->Client_only)
431 if ( Release_reserved_mutex(handle_mutex,"handle_mutex",0,1))
432 return DMLERR_SYS_ERROR;
433 return DMLERR_DLL_USAGE;
436 // Check 2 - cannot use 'Monitor' with any non-monitor modes
438 if ( this_instance->Monitor != reference_inst->Monitor)
440 if ( Release_reserved_mutex(handle_mutex,"handle_mutex",0,1))
441 return DMLERR_SYS_ERROR;
442 return DMLERR_INVALIDPARAMETER;
445 // Check 3 - must supply different callback address
447 if ( this_instance->CallBack == reference_inst->CallBack)
449 if ( Release_reserved_mutex(handle_mutex,"handle_mutex",0,1))
450 return DMLERR_SYS_ERROR;
451 return DMLERR_DLL_USAGE;
454 reference_inst = reference_inst->Next_Entry;
456 // All cleared, add to chain
458 TRACE(ddeml,"Application Instance checks finished\n");
459 if ((err_no = IncrementInstanceId())) return err_no;
460 if ( Release_reserved_mutex(handle_mutex,"handle_mutex",0,0)) return DMLERR_SYS_ERROR;
461 reference_inst->Next_Entry = this_instance;
463 pidInst = (LPDWORD)this_instance->Instance_id;
464 TRACE(ddeml,"New application instance processing finished OK\n");
465 } else {
466 /* Reinitialisation situation --- FIX */
467 TRACE(ddeml,"reinitialisation of (%p,%p,0x%lx,%ld): stub\n",pidInst,pfnCallback,afCmd,ulRes);
468 WaitForSingleObject(handle_mutex,1000);
469 if ( (err_no=GetLastError()) != 0 )
472 /* FIXME - needs refinement with popup for timeout, also is timeout interval OK */
474 ERR(ddeml,"WaitForSingleObject failed - handle list %li\n",err_no);
475 HeapFree(GetProcessHeap(), 0, this_instance);
476 return DMLERR_SYS_ERROR;
478 if (DDE_Handle_Table_Base == NULL )
480 if ( Release_reserved_mutex(handle_mutex,"handle_mutex",0,1)) return DMLERR_SYS_ERROR;
481 return DMLERR_DLL_USAGE;
483 HeapFree(GetProcessHeap(), 0, this_instance); // finished - release heap space used as work store
484 // can't reinitialise if we have initialised nothing !!
485 reference_inst = DDE_Handle_Table_Base;
486 /* must first check if we have been given a valid instance to re-initialise !! how do we do that ? */
487 while ( reference_inst->Next_Entry != NULL )
489 if ( pidInst == reference_inst->Instance_id && pfnCallback == reference_inst->CallBack )
491 // Check 1 - cannot change client-only mode if set via APPCMD_CLIENTONLY
493 if ( reference_inst->Client_only )
495 if ((reference_inst->CBF_Flags & CBF_FAIL_ALLSVRXACTIONS) != CBF_FAIL_ALLSVRXACTIONS)
497 // i.e. Was set to Client-only and through APPCMD_CLIENTONLY
499 if ( ! ( afCmd & APPCMD_CLIENTONLY))
501 if ( Release_reserved_mutex(handle_mutex,"handle_mutex",0,1))
502 return DMLERR_SYS_ERROR;
503 return DMLERR_DLL_USAGE;
507 // Check 2 - cannot change monitor modes
509 if ( this_instance->Monitor != reference_inst->Monitor)
511 if ( Release_reserved_mutex(handle_mutex,"handle_mutex",0,1))
512 return DMLERR_SYS_ERROR;
513 return DMLERR_DLL_USAGE;
516 // Check 3 - trying to set Client-only via APPCMD when not set so previously
518 if (( afCmd&APPCMD_CLIENTONLY) && ! reference_inst->Client_only )
520 if ( Release_reserved_mutex(handle_mutex,"handle_mutex",0,1))
521 return DMLERR_SYS_ERROR;
522 return DMLERR_DLL_USAGE;
526 // All checked - change relevant flags
528 reference_inst->CBF_Flags = this_instance->CBF_Flags;
529 reference_inst->Client_only = this_instance->Client_only;
530 reference_inst->Monitor_flags = this_instance->Monitor_flags;
531 if ( Release_reserved_mutex(handle_mutex,"handle_mutex",0,1))
532 return DMLERR_SYS_ERROR;
535 return DMLERR_NO_ERROR;
539 /*****************************************************************
540 * DdeUninitialize16 (DDEML.3)
542 BOOL16 WINAPI DdeUninitialize16( DWORD idInst )
544 return (BOOL16)DdeUninitialize32( idInst );
548 /*****************************************************************
549 * DdeUninitialize32 [USER32.119] Frees DDEML resources
551 * PARAMS
552 * idInst [I] Instance identifier
554 * RETURNS
555 * Success: TRUE
556 * Failure: FALSE
558 BOOL32 WINAPI DdeUninitialize32( DWORD idInst )
561 FIXME(ddeml, "(%ld): stub\n", idInst);
563 /* Free the nodes that were not freed by this instance
564 * and remove the nodes from the list of HSZ nodes.
566 FreeAndRemoveHSZNodes( idInst );
568 return TRUE;
572 /*****************************************************************
573 * DdeConnectList16 [DDEML.4]
575 HCONVLIST WINAPI DdeConnectList16( DWORD idInst, HSZ hszService, HSZ hszTopic,
576 HCONVLIST hConvList, LPCONVCONTEXT16 pCC )
578 return DdeConnectList32(idInst, hszService, hszTopic, hConvList,
579 (LPCONVCONTEXT32)pCC);
583 /******************************************************************************
584 * DdeConnectList32 [USER32.93] Establishes conversation with DDE servers
586 * PARAMS
587 * idInst [I] Instance identifier
588 * hszService [I] Handle to service name string
589 * hszTopic [I] Handle to topic name string
590 * hConvList [I] Handle to conversation list
591 * pCC [I] Pointer to structure with context data
593 * RETURNS
594 * Success: Handle to new conversation list
595 * Failure: 0
597 HCONVLIST WINAPI DdeConnectList32( DWORD idInst, HSZ hszService, HSZ hszTopic,
598 HCONVLIST hConvList, LPCONVCONTEXT32 pCC )
600 FIXME(ddeml, "(%ld,%ld,%ld,%ld,%p): stub\n", idInst, hszService, hszTopic,
601 hConvList,pCC);
602 return 1;
606 /*****************************************************************
607 * DdeQueryNextServer16 [DDEML.5]
609 HCONV WINAPI DdeQueryNextServer16( HCONVLIST hConvList, HCONV hConvPrev )
611 return DdeQueryNextServer32(hConvList, hConvPrev);
615 /*****************************************************************
616 * DdeQueryNextServer32 [USER32.112]
618 HCONV WINAPI DdeQueryNextServer32( HCONVLIST hConvList, HCONV hConvPrev )
620 FIXME(ddeml, "(%ld,%ld): stub\n",hConvList,hConvPrev);
621 return 0;
624 /*****************************************************************
625 * DdeQueryString32A [USER32.113]
627 DWORD WINAPI DdeQueryString32A(DWORD idInst, HSZ hsz, LPSTR psz, DWORD cchMax, INT32 iCodePage)
629 DWORD ret = 0;
630 CHAR pString[MAX_BUFFER_LEN];
632 FIXME(ddeml,
633 "(%ld, 0x%lx, %p, %ld, %d): stub\n",
634 idInst,
635 hsz,
636 psz,
637 cchMax,
638 iCodePage);
640 if( iCodePage == CP_WINANSI )
642 /* If psz is null, we have to return only the length
643 * of the string.
645 if( psz == NULL )
647 psz = pString;
648 cchMax = MAX_BUFFER_LEN;
651 ret = GlobalGetAtomName32A( hsz, (LPSTR)psz, cchMax );
654 return ret;
657 /*****************************************************************
658 * DdeQueryString32W [USER32.114]
660 DWORD WINAPI DdeQueryString32W(DWORD idInst, HSZ hsz, LPWSTR psz, DWORD cchMax, INT32 iCodePage)
662 DWORD ret = 0;
663 WCHAR pString[MAX_BUFFER_LEN];
664 int factor = 1;
666 FIXME(ddeml,
667 "(%ld, 0x%lx, %p, %ld, %d): stub\n",
668 idInst,
669 hsz,
670 psz,
671 cchMax,
672 iCodePage);
674 if( iCodePage == CP_WINUNICODE )
676 /* If psz is null, we have to return only the length
677 * of the string.
679 if( psz == NULL )
681 psz = pString;
682 cchMax = MAX_BUFFER_LEN;
683 /* Note: According to documentation if the psz parameter
684 * was NULL this API must return the length of the string in bytes.
686 factor = (int) sizeof(WCHAR)/sizeof(BYTE);
688 ret = GlobalGetAtomName32W( hsz, (LPWSTR)psz, cchMax ) * factor;
690 return ret;
694 /*****************************************************************
695 * DdeDisconnectList (DDEML.6)
697 BOOL16 WINAPI DdeDisconnectList16( HCONVLIST hConvList )
699 return (BOOL16)DdeDisconnectList32(hConvList);
703 /******************************************************************************
704 * DdeDisconnectList32 [USER32.98] Destroys list and terminates conversations
706 * RETURNS
707 * Success: TRUE
708 * Failure: FALSE
710 BOOL32 WINAPI DdeDisconnectList32(
711 HCONVLIST hConvList) /* [in] Handle to conversation list */
713 FIXME(ddeml, "(%ld): stub\n", hConvList);
714 return TRUE;
718 /*****************************************************************
719 * DdeConnect16 (DDEML.7)
721 HCONV WINAPI DdeConnect16( DWORD idInst, HSZ hszService, HSZ hszTopic,
722 LPCONVCONTEXT16 pCC )
724 FIXME( ddeml, "empty stub\n" );
725 return 0;
729 /*****************************************************************
730 * DdeConnect32 (USER32.92)
732 HCONV WINAPI DdeConnect32( DWORD idInst, HSZ hszService, HSZ hszTopic,
733 LPCONVCONTEXT32 pCC )
735 FIXME(ddeml, "(0x%lx,%ld,%ld,%p): stub\n",idInst,hszService,hszTopic,
736 pCC);
737 return 0;
741 /*****************************************************************
742 * DdeDisconnect16 (DDEML.8)
744 BOOL16 WINAPI DdeDisconnect16( HCONV hConv )
746 return (BOOL16)DdeDisconnect32( hConv );
749 /*****************************************************************
750 * DdeSetUserHandle (DDEML.10)
752 BOOL16 WINAPI DdeSetUserHandle( HCONV hConv, DWORD id, DWORD hUser )
754 FIXME( ddeml, "(%ld,%ld,%ld): stub\n",hConv,id, hUser );
755 return 0;
758 /*****************************************************************
759 * DdeCreateDataHandle16 (DDEML.14)
761 HDDEDATA WINAPI DdeCreateDataHandle16( DWORD idInst, LPBYTE pSrc, DWORD cb,
762 DWORD cbOff, HSZ hszItem, UINT16 wFmt,
763 UINT16 afCmd )
765 return DdeCreateDataHandle32(idInst,
766 pSrc,
768 cbOff,
769 hszItem,
770 wFmt,
771 afCmd);
774 /*****************************************************************
775 * DdeCreateDataHandle32 (USER32.94)
777 HDDEDATA WINAPI DdeCreateDataHandle32( DWORD idInst, LPBYTE pSrc, DWORD cb,
778 DWORD cbOff, HSZ hszItem, UINT32 wFmt,
779 UINT32 afCmd )
781 FIXME( ddeml,
782 "(%ld,%p,%ld,%ld,0x%lx,%d,%d): stub\n",
783 idInst,
784 pSrc,
786 cbOff,
787 hszItem,
788 wFmt,
789 afCmd );
791 return 0;
794 /*****************************************************************
795 * DdeDisconnect32 (USER32.97)
797 BOOL32 WINAPI DdeDisconnect32( HCONV hConv )
799 FIXME( ddeml, "empty stub\n" );
800 return 0;
804 /*****************************************************************
805 * DdeReconnect (DDEML.37) (USER32.115)
807 HCONV WINAPI DdeReconnect( HCONV hConv )
809 FIXME( ddeml, "empty stub\n" );
810 return 0;
814 /*****************************************************************
815 * DdeCreateStringHandle16 (DDEML.21)
817 HSZ WINAPI DdeCreateStringHandle16( DWORD idInst, LPCSTR str, INT16 codepage )
819 return DdeCreateStringHandle32A( idInst, str, codepage );
823 /*****************************************************************
824 * DdeCreateStringHandle32A [USER32.95]
826 * RETURNS
827 * Success: String handle
828 * Failure: 0
830 HSZ WINAPI DdeCreateStringHandle32A( DWORD idInst, LPCSTR psz, INT32 codepage )
832 HSZ hsz = 0;
833 TRACE(ddeml, "(%ld,%s,%d): stub\n",idInst,debugstr_a(psz),codepage);
835 if (codepage==CP_WINANSI)
837 hsz = GlobalAddAtom32A (psz);
838 /* Save the handle so we know to clean it when
839 * uninitialize is called.
841 InsertHSZNode( idInst, hsz );
842 return hsz;
844 return 0;
848 /******************************************************************************
849 * DdeCreateStringHandle32W [USER32.96] Creates handle to identify string
851 * RETURNS
852 * Success: String handle
853 * Failure: 0
855 HSZ WINAPI DdeCreateStringHandle32W(
856 DWORD idInst, /* [in] Instance identifier */
857 LPCWSTR psz, /* [in] Pointer to string */
858 INT32 codepage) /* [in] Code page identifier */
860 HSZ hsz = 0;
862 FIXME(ddeml, "(%ld,%s,%d): stub\n",idInst,debugstr_w(psz),codepage);
864 if (codepage==CP_WINUNICODE)
866 hsz = GlobalAddAtom32W (psz);
867 /* Save the handle so we know to clean it when
868 * uninitialize is called.
870 InsertHSZNode( idInst, hsz );
871 return hsz;
873 return 0;
877 /*****************************************************************
878 * DdeFreeStringHandle16 (DDEML.22)
880 BOOL16 WINAPI DdeFreeStringHandle16( DWORD idInst, HSZ hsz )
882 return (BOOL32)DdeFreeStringHandle32( idInst, hsz );
886 /*****************************************************************
887 * DdeFreeStringHandle32 (USER32.101)
888 * RETURNS: success: nonzero
889 * fail: zero
891 BOOL32 WINAPI DdeFreeStringHandle32( DWORD idInst, HSZ hsz )
893 TRACE( ddeml, "(%ld,%ld): stub\n",idInst, hsz );
894 /* Remove the node associated with this HSZ.
896 RemoveHSZNode( idInst, hsz );
897 /* Free the string associated with this HSZ.
899 return GlobalDeleteAtom (hsz) ? 0 : hsz;
903 /*****************************************************************
904 * DdeFreeDataHandle16 (DDEML.19)
906 BOOL16 WINAPI DdeFreeDataHandle16( HDDEDATA hData )
908 return (BOOL32)DdeFreeDataHandle32( hData );
912 /*****************************************************************
913 * DdeFreeDataHandle32 (USER32.100)
915 BOOL32 WINAPI DdeFreeDataHandle32( HDDEDATA hData )
917 FIXME( ddeml, "empty stub\n" );
918 return TRUE;
924 /*****************************************************************
925 * DdeKeepStringHandle16 (DDEML.24)
927 BOOL16 WINAPI DdeKeepStringHandle16( DWORD idInst, HSZ hsz )
929 return (BOOL32)DdeKeepStringHandle32( idInst, hsz );
933 /*****************************************************************
934 * DdeKeepStringHandle32 (USER32.108)
936 BOOL32 WINAPI DdeKeepStringHandle32( DWORD idInst, HSZ hsz )
938 FIXME( ddeml, "empty stub\n" );
939 return TRUE;
943 /*****************************************************************
944 * DdeClientTransaction16 (DDEML.11)
946 HDDEDATA WINAPI DdeClientTransaction16( LPVOID pData, DWORD cbData,
947 HCONV hConv, HSZ hszItem, UINT16 wFmt,
948 UINT16 wType, DWORD dwTimeout,
949 LPDWORD pdwResult )
951 return DdeClientTransaction32( (LPBYTE)pData, cbData, hConv, hszItem,
952 wFmt, wType, dwTimeout, pdwResult );
956 /*****************************************************************
957 * DdeClientTransaction32 (USER32.90)
959 HDDEDATA WINAPI DdeClientTransaction32( LPBYTE pData, DWORD cbData,
960 HCONV hConv, HSZ hszItem, UINT32 wFmt,
961 UINT32 wType, DWORD dwTimeout,
962 LPDWORD pdwResult )
964 FIXME( ddeml, "empty stub\n" );
965 return 0;
968 /*****************************************************************
969 * DdeAbandonTransaction (DDEML.12)
971 BOOL16 WINAPI DdeAbandonTransaction( DWORD idInst, HCONV hConv,
972 DWORD idTransaction )
974 FIXME( ddeml, "empty stub\n" );
975 return 0;
979 /*****************************************************************
980 * DdePostAdvise16 [DDEML.13]
982 BOOL16 WINAPI DdePostAdvise16( DWORD idInst, HSZ hszTopic, HSZ hszItem )
984 return (BOOL16)DdePostAdvise32(idInst, hszTopic, hszItem);
988 /******************************************************************************
989 * DdePostAdvise32 [USER32.110] Send transaction to DDE callback function.
991 * RETURNS
992 * Success: TRUE
993 * Failure: FALSE
995 BOOL32 WINAPI DdePostAdvise32(
996 DWORD idInst, /* [in] Instance identifier */
997 HSZ hszTopic, /* [in] Handle to topic name string */
998 HSZ hszItem) /* [in] Handle to item name string */
1000 FIXME(ddeml, "(%ld,%ld,%ld): stub\n",idInst,hszTopic,hszItem);
1001 return TRUE;
1005 /*****************************************************************
1006 * DdeAddData (DDEML.15)
1008 HDDEDATA WINAPI DdeAddData( HDDEDATA hData, LPBYTE pSrc, DWORD cb,
1009 DWORD cbOff )
1011 FIXME( ddeml, "empty stub\n" );
1012 return 0;
1016 /******************************************************************************
1017 * DdeGetData32 [USER32.102] Copies data from DDE object ot local buffer
1019 * RETURNS
1020 * Size of memory object associated with handle
1022 DWORD WINAPI DdeGetData32(
1023 HDDEDATA hData, /* [in] Handle to DDE object */
1024 LPBYTE pDst, /* [in] Pointer to destination buffer */
1025 DWORD cbMax, /* [in] Amount of data to copy */
1026 DWORD cbOff) /* [in] Offset to beginning of data */
1028 FIXME(ddeml, "(%ld,%p,%ld,%ld): stub\n",hData,pDst,cbMax,cbOff);
1029 return cbMax;
1033 /*****************************************************************
1034 * DdeGetData16 [DDEML.16]
1036 DWORD WINAPI DdeGetData16(
1037 HDDEDATA hData,
1038 LPBYTE pDst,
1039 DWORD cbMax,
1040 DWORD cbOff)
1042 return DdeGetData32(hData, pDst, cbMax, cbOff);
1046 /*****************************************************************
1047 * DdeAccessData16 (DDEML.17)
1049 LPBYTE WINAPI DdeAccessData16( HDDEDATA hData, LPDWORD pcbDataSize )
1051 return DdeAccessData32(hData, pcbDataSize);
1054 /*****************************************************************
1055 * DdeAccessData32 (USER32.88)
1057 LPBYTE WINAPI DdeAccessData32( HDDEDATA hData, LPDWORD pcbDataSize )
1059 FIXME( ddeml, "(%ld,%p): stub\n", hData, pcbDataSize);
1060 return 0;
1063 /*****************************************************************
1064 * DdeUnaccessData16 (DDEML.18)
1066 BOOL16 WINAPI DdeUnaccessData16( HDDEDATA hData )
1068 return DdeUnaccessData32(hData);
1071 /*****************************************************************
1072 * DdeUnaccessData32 (USER32.118)
1074 BOOL32 WINAPI DdeUnaccessData32( HDDEDATA hData )
1076 FIXME( ddeml, "(0x%lx): stub\n", hData);
1078 return 0;
1081 /*****************************************************************
1082 * DdeEnableCallback16 (DDEML.26)
1084 BOOL16 WINAPI DdeEnableCallback16( DWORD idInst, HCONV hConv, UINT16 wCmd )
1086 return DdeEnableCallback32(idInst, hConv, wCmd);
1089 /*****************************************************************
1090 * DdeEnableCallback32 (USER32.99)
1092 BOOL32 WINAPI DdeEnableCallback32( DWORD idInst, HCONV hConv, UINT32 wCmd )
1094 FIXME( ddeml, "(%ld, 0x%lx, %d) stub\n", idInst, hConv, wCmd);
1096 return 0;
1099 /*****************************************************************
1100 * DdeNameService16 (DDEML.27)
1102 HDDEDATA WINAPI DdeNameService16( DWORD idInst, HSZ hsz1, HSZ hsz2,
1103 UINT16 afCmd )
1105 return DdeNameService32( idInst, hsz1, hsz2, afCmd );
1109 /******************************************************************************
1110 * DdeNameService32 [USER32.109] {Un}registers service name of DDE server
1112 * PARAMS
1113 * idInst [I] Instance identifier
1114 * hsz1 [I] Handle to service name string
1115 * hsz2 [I] Reserved
1116 * afCmd [I] Service name flags
1118 * RETURNS
1119 * Success: Non-zero
1120 * Failure: 0
1122 HDDEDATA WINAPI DdeNameService32( DWORD idInst, HSZ hsz1, HSZ hsz2,
1123 UINT32 afCmd )
1125 FIXME(ddeml, "(%ld,%ld,%ld,%d): stub\n",idInst,hsz1,hsz2,afCmd);
1126 return 1;
1130 /*****************************************************************
1131 * DdeGetLastError16 (DDEML.20)
1133 UINT16 WINAPI DdeGetLastError16( DWORD idInst )
1135 return (UINT16)DdeGetLastError32( idInst );
1139 /******************************************************************************
1140 * DdeGetLastError32 [USER32.103] Gets most recent error code
1142 * PARAMS
1143 * idInst [I] Instance identifier
1145 * RETURNS
1146 * Last error code
1148 UINT32 WINAPI DdeGetLastError32( DWORD idInst )
1150 FIXME(ddeml, "(%ld): stub\n",idInst);
1151 return 0;
1155 /*****************************************************************
1156 * DdeCmpStringHandles16 (DDEML.36)
1158 int WINAPI DdeCmpStringHandles16( HSZ hsz1, HSZ hsz2 )
1160 return DdeCmpStringHandles32(hsz1, hsz2);
1163 /*****************************************************************
1164 * DdeCmpStringHandles32 (USER32.91)
1166 * Compares the value of two string handles. This comparison is
1167 * not case sensitive.
1169 * Returns:
1170 * -1 The value of hsz1 is zero or less than hsz2
1171 * 0 The values of hsz 1 and 2 are the same or both zero.
1172 * 1 The value of hsz2 is zero of less than hsz1
1174 int WINAPI DdeCmpStringHandles32( HSZ hsz1, HSZ hsz2 )
1176 CHAR psz1[MAX_BUFFER_LEN];
1177 CHAR psz2[MAX_BUFFER_LEN];
1178 int ret = 0;
1179 int ret1, ret2;
1181 TRACE( ddeml, "handle 1, handle 2\n" );
1183 ret1 = GlobalGetAtomName32A( hsz1, psz1, MAX_BUFFER_LEN );
1184 ret2 = GlobalGetAtomName32A( hsz2, psz2, MAX_BUFFER_LEN );
1185 /* Make sure we found both strings.
1187 if( ret1 == 0 && ret2 == 0 )
1189 /* If both are not found, return both "zero strings".
1191 ret = 0;
1193 else if( ret1 == 0 )
1195 /* If hsz1 is a not found, return hsz1 is "zero string".
1197 ret = -1;
1199 else if( ret2 == 0 )
1201 /* If hsz2 is a not found, return hsz2 is "zero string".
1203 ret = 1;
1205 else
1207 /* Compare the two strings we got ( case insensitive ).
1209 ret = strcasecmp( psz1, psz2 );
1210 /* Since strcmp returns any number smaller than
1211 * 0 when the first string is found to be less than
1212 * the second one we must make sure we are returning
1213 * the proper values.
1215 if( ret < 0 )
1217 ret = -1;
1219 else if( ret > 0 )
1221 ret = 1;
1225 return ret;
1228 /*****************************************************************
1229 * PackDDElParam (USER32.414)
1231 * RETURNS
1232 * success: nonzero
1233 * failure: zero
1235 UINT32 WINAPI PackDDElParam(UINT32 msg, UINT32 uiLo, UINT32 uiHi)
1237 FIXME(ddeml, "stub.\n");
1238 return 0;
1242 /*****************************************************************
1243 * UnpackDDElParam (USER32.562)
1245 * RETURNS
1246 * success: nonzero
1247 * failure: zero
1249 UINT32 WINAPI UnpackDDElParam(UINT32 msg, UINT32 lParam,
1250 UINT32 *uiLo, UINT32 *uiHi)
1252 FIXME(ddeml, "stub.\n");
1253 return 0;
1257 /*****************************************************************
1258 * FreeDDElParam (USER32.204)
1260 * RETURNS
1261 * success: nonzero
1262 * failure: zero
1264 UINT32 WINAPI FreeDDElParam(UINT32 msg, UINT32 lParam)
1266 FIXME(ddeml, "stub.\n");
1267 return 0;
1270 /*****************************************************************
1271 * ReuseDDElParam (USER32.446)
1274 UINT32 WINAPI ReuseDDElParam(UINT32 lParam, UINT32 msgIn, UINT32 msgOut,
1275 UINT32 uiLi, UINT32 uiHi)
1277 FIXME(ddeml, "stub.\n");
1278 return 0;