Missing WINAPI.
[wine] / misc / ddeml.c
1 /*
2  * DDEML library
3  *
4  * Copyright 1997 Alexandre Julliard
5  * Copyright 1997 Len White
6  */
7
8 /* Only empty stubs for now */
9
10 #include <stdlib.h>
11 #include <strings.h>
12 #include "ddeml.h"
13 #include "debug.h"
14 #include "windows.h"
15 #include "heap.h"
16
17 /* FIXME: What are these values? */
18 #define DMLERR_NO_ERROR         0
19
20 /* Has defined in atom.c file.
21  */
22 #define MAX_ATOM_LEN              255
23
24 /* Maximum buffer size ( including the '\0' ).
25  */
26 #define MAX_BUFFER_LEN            (MAX_ATOM_LEN + 1)
27
28 static LONG     DDE_current_handle;
29
30 /* This is a simple list to keep track of the strings created
31  * by DdeCreateStringHandle.  The list is used to free
32  * the strings whenever DdeUninitialize is called.
33  * This mechanism is not complete and does not handle multiple instances.
34  * Most of the DDE API use a DWORD parameter indicating witch instance
35  * of a given program is calling them.  The API are supposed to
36  * associate the data to the instance that created it.
37  */
38 typedef struct tagHSZNode HSZNode;
39 struct tagHSZNode
40 {
41     HSZNode* next;
42     HSZ hsz;
43 };
44
45 /* Start off the list pointer with a NULL.
46  */
47 static HSZNode* pHSZNodes = NULL;
48
49
50 /******************************************************************************
51  *            RemoveHSZNodes    (INTERNAL)
52  *
53  * Remove a node from the list of HSZ nodes.
54  */
55 static void RemoveHSZNode( DWORD idInst, HSZ hsz )
56 {
57     HSZNode* pPrev = NULL;
58     HSZNode* pCurrent = NULL;
59
60     /* Set the current node at the start of the list.
61      */
62     pCurrent = pHSZNodes;
63     /* While we have more nodes.
64      */
65     while( pCurrent != NULL )
66     {
67         /* If we found the node we were looking for.
68          */
69         if( pCurrent->hsz == hsz )
70         {
71             /* Remove the node.
72              */
73             /* If the first node in the list is to to be removed.
74              * Set the global list pointer to the next node.
75              */
76             if( pCurrent == pHSZNodes )
77             {
78                 pHSZNodes = pCurrent->next;
79             }
80             /* Just fix the pointers has to skip the current
81              * node so we can delete it.
82              */
83             else
84             {
85                 pPrev->next = pCurrent->next;
86             }
87             /* Destroy this node.
88              */
89             free( pCurrent );
90             break;
91         }
92         /* Save the previous node pointer.
93          */
94         pPrev = pCurrent;
95         /* Move on to the next node.
96          */
97         pCurrent = pCurrent->next;
98     }
99 }
100
101 /******************************************************************************
102  *            FreeAndRemoveHSZNodes    (INTERNAL)
103  *
104  * Frees up all the strings still allocated in the list and
105  * remove all the nodes from the list of HSZ nodes.
106  */
107 static void FreeAndRemoveHSZNodes( DWORD idInst )
108 {
109     /* Free any strings created in this instance.
110      */
111     while( pHSZNodes != NULL )
112     {
113         DdeFreeStringHandle32( idInst, pHSZNodes->hsz );
114     }
115 }
116
117 /******************************************************************************
118  *            InsertHSZNode    (INTERNAL)
119  *
120  * Insert a node to the head of the list.
121  */
122 static void InsertHSZNode( DWORD idInst, HSZ hsz )
123 {
124     if( hsz != 0 )
125     {
126         HSZNode* pNew = NULL;
127         /* Create a new node for this HSZ.
128          */
129         pNew = (HSZNode*) malloc( sizeof( HSZNode ) );
130         if( pNew != NULL )
131         {
132             /* Set the handle value.
133              */
134             pNew->hsz = hsz;
135             /* Attach the node to the head of the list.
136              */
137             pNew->next = pHSZNodes;
138             /* The new node is now at the head of the list
139              * so set the global list pointer to it.
140              */
141             pHSZNodes = pNew;
142         }
143     }
144 }
145
146
147 /******************************************************************************
148  *            DdeInitialize16   (DDEML.2)
149  */
150 UINT16 WINAPI DdeInitialize16( LPDWORD pidInst, PFNCALLBACK16 pfnCallback,
151                                DWORD afCmd, DWORD ulRes)
152 {
153     return (UINT16)DdeInitialize32A(pidInst,(PFNCALLBACK32)pfnCallback,
154                                     afCmd, ulRes);
155 }
156
157
158 /******************************************************************************
159  *            DdeInitialize32A   (USER32.106)
160  */
161 UINT32 WINAPI DdeInitialize32A( LPDWORD pidInst, PFNCALLBACK32 pfnCallback,
162                                 DWORD afCmd, DWORD ulRes )
163 {
164     return DdeInitialize32W(pidInst,pfnCallback,afCmd,ulRes);
165 }
166
167
168 /******************************************************************************
169  * DdeInitialize32W [USER32.107]
170  * Registers an application with the DDEML
171  *
172  * PARAMS
173  *    pidInst     [I] Pointer to instance identifier
174  *    pfnCallback [I] Pointer to callback function
175  *    afCmd       [I] Set of command and filter flags
176  *    ulRes       [I] Reserved
177  *
178  * RETURNS
179  *    Success: DMLERR_NO_ERROR
180  *    Failure: DMLERR_DLL_USAGE, DMLERR_INVALIDPARAMETER, DMLERR_SYS_ERROR
181  */
182 UINT32 WINAPI DdeInitialize32W( LPDWORD pidInst, PFNCALLBACK32 pfnCallback,
183                                 DWORD afCmd, DWORD ulRes )
184 {
185     FIXME(ddeml, "(%p,%p,0x%lx,%ld): stub\n",pidInst,pfnCallback,afCmd,ulRes);
186
187     if(pidInst)
188       *pidInst = 0;
189
190     if( ulRes )
191         ERR(dde, "Reserved value not zero?  What does this mean?\n");
192
193     return DMLERR_NO_ERROR;
194 }
195
196
197 /*****************************************************************
198  *            DdeUninitialize16   (DDEML.3)
199  */
200 BOOL16 WINAPI DdeUninitialize16( DWORD idInst )
201 {
202     return (BOOL16)DdeUninitialize32( idInst );
203 }
204
205
206 /*****************************************************************
207  * DdeUninitialize32 [USER32.119]  Frees DDEML resources
208  *
209  * PARAMS
210  *    idInst [I] Instance identifier
211  *
212  * RETURNS
213  *    Success: TRUE
214  *    Failure: FALSE
215  */
216 BOOL32 WINAPI DdeUninitialize32( DWORD idInst )
217 {
218
219     FIXME(ddeml, "(%ld): stub\n", idInst);
220
221     /* Free the nodes that were not freed by this instance
222      * and remove the nodes from the list of HSZ nodes.
223      */
224     FreeAndRemoveHSZNodes( idInst );
225     
226     return TRUE;
227 }
228
229
230 /*****************************************************************
231  * DdeConnectList16 [DDEML.4]
232  */
233 HCONVLIST WINAPI DdeConnectList16( DWORD idInst, HSZ hszService, HSZ hszTopic,
234                  HCONVLIST hConvList, LPCONVCONTEXT16 pCC )
235 {
236     return DdeConnectList32(idInst, hszService, hszTopic, hConvList, 
237                             (LPCONVCONTEXT32)pCC);
238 }
239
240
241 /******************************************************************************
242  * DdeConnectList32 [USER32.93]  Establishes conversation with DDE servers
243  *
244  * PARAMS
245  *    idInst     [I] Instance identifier
246  *    hszService [I] Handle to service name string
247  *    hszTopic   [I] Handle to topic name string
248  *    hConvList  [I] Handle to conversation list
249  *    pCC        [I] Pointer to structure with context data
250  *
251  * RETURNS
252  *    Success: Handle to new conversation list
253  *    Failure: 0
254  */
255 HCONVLIST WINAPI DdeConnectList32( DWORD idInst, HSZ hszService, HSZ hszTopic,
256                  HCONVLIST hConvList, LPCONVCONTEXT32 pCC )
257 {
258     FIXME(ddeml, "(%ld,%ld,%ld,%ld,%p): stub\n", idInst, hszService, hszTopic,
259           hConvList,pCC);
260     return 1;
261 }
262
263
264 /*****************************************************************
265  * DdeQueryNextServer16 [DDEML.5]
266  */
267 HCONV WINAPI DdeQueryNextServer16( HCONVLIST hConvList, HCONV hConvPrev )
268 {
269     return DdeQueryNextServer32(hConvList, hConvPrev);
270 }
271
272
273 /*****************************************************************
274  * DdeQueryNextServer32 [USER32.112]
275  */
276 HCONV WINAPI DdeQueryNextServer32( HCONVLIST hConvList, HCONV hConvPrev )
277 {
278     FIXME(ddeml, "(%ld,%ld): stub\n",hConvList,hConvPrev);
279     return 0;
280 }
281
282 /*****************************************************************
283  * DdeQueryString32A [USER32.113]
284  */
285 DWORD WINAPI DdeQueryString32A(DWORD idInst, HSZ hsz, LPSTR psz, DWORD cchMax, INT32 iCodePage)
286 {
287     DWORD ret = 0;
288     CHAR pString[MAX_BUFFER_LEN];
289
290     FIXME(ddeml,
291          "(%ld, 0x%lx, %p, %ld, %d): stub\n",
292          idInst,
293          hsz,
294          psz, 
295          cchMax,
296          iCodePage);
297
298     if( iCodePage == CP_WINANSI )
299     {
300         /* If psz is null, we have to return only the length
301          * of the string.
302          */
303         if( psz == NULL )
304         {
305             psz = pString;
306             cchMax = MAX_BUFFER_LEN;
307 }
308
309         ret = GlobalGetAtomName32A( hsz, (LPSTR)psz, cchMax );
310     }
311     
312     return ret;
313 }
314
315 /*****************************************************************
316  * DdeQueryString32W [USER32.114]
317  */
318 DWORD WINAPI DdeQueryString32W(DWORD idInst, HSZ hsz, LPWSTR psz, DWORD cchMax, INT32 iCodePage)
319 {
320     DWORD ret = 0;
321     WCHAR pString[MAX_BUFFER_LEN];
322     int factor = 1;
323
324     FIXME(ddeml,
325          "(%ld, 0x%lx, %p, %ld, %d): stub\n",
326          idInst,
327          hsz,
328          psz, 
329          cchMax,
330          iCodePage);
331
332     if( iCodePage == CP_WINUNICODE )
333     {
334         /* If psz is null, we have to return only the length
335          * of the string.
336          */
337         if( psz == NULL )
338         {
339             psz = pString;
340             cchMax = MAX_BUFFER_LEN;
341             /* Note: According to documentation if the psz parameter
342              * was NULL this API must return the length of the string in bytes.
343              */
344             factor = (int) sizeof(WCHAR)/sizeof(BYTE);
345         }
346         ret = GlobalGetAtomName32W( hsz, (LPWSTR)psz, cchMax ) * factor;
347     }
348     return ret;
349 }
350
351
352 /*****************************************************************
353  *            DdeDisconnectList (DDEML.6)
354  */
355 BOOL16 WINAPI DdeDisconnectList16( HCONVLIST hConvList )
356 {
357     return (BOOL16)DdeDisconnectList32(hConvList);
358 }
359
360
361 /******************************************************************************
362  * DdeDisconnectList32 [USER32.98]  Destroys list and terminates conversations
363  *
364  * RETURNS
365  *    Success: TRUE
366  *    Failure: FALSE
367  */
368 BOOL32 WINAPI DdeDisconnectList32(
369     HCONVLIST hConvList) /* [in] Handle to conversation list */
370 {
371     FIXME(ddeml, "(%ld): stub\n", hConvList);
372     return TRUE;
373 }
374
375
376 /*****************************************************************
377  *            DdeConnect16   (DDEML.7)
378  */
379 HCONV WINAPI DdeConnect16( DWORD idInst, HSZ hszService, HSZ hszTopic,
380                            LPCONVCONTEXT16 pCC )
381 {
382     FIXME( ddeml, "empty stub\n" );
383     return 0;
384 }
385
386
387 /*****************************************************************
388  *            DdeConnect32   (USER32.92)
389  */
390 HCONV WINAPI DdeConnect32( DWORD idInst, HSZ hszService, HSZ hszTopic,
391                            LPCONVCONTEXT32 pCC )
392 {
393     FIXME(ddeml, "(0x%lx,%ld,%ld,%p): stub\n",idInst,hszService,hszTopic,
394           pCC);
395     return 0;
396 }
397
398
399 /*****************************************************************
400  *            DdeDisconnect16   (DDEML.8)
401  */
402 BOOL16 WINAPI DdeDisconnect16( HCONV hConv )
403 {
404     return (BOOL16)DdeDisconnect32( hConv );
405 }
406
407 /*****************************************************************
408  *            DdeSetUserHandle (DDEML.10)
409  */
410 BOOL16 WINAPI DdeSetUserHandle( HCONV hConv, DWORD id, DWORD hUser )
411 {
412     FIXME( ddeml, "(%ld,%ld,%ld): stub\n",hConv,id, hUser );
413     return 0;
414 }
415
416 /*****************************************************************
417  *            DdeCreateDataHandle16 (DDEML.14)
418  */
419 HDDEDATA WINAPI DdeCreateDataHandle16( DWORD idInst, LPBYTE pSrc, DWORD cb, 
420                                      DWORD cbOff, HSZ hszItem, UINT16 wFmt, 
421                                      UINT16 afCmd )
422 {
423     return DdeCreateDataHandle32(idInst,
424                                 pSrc,
425                                 cb,
426                                 cbOff,
427                                 hszItem,
428                                 wFmt,
429                                 afCmd);
430 }
431
432 /*****************************************************************
433  *            DdeCreateDataHandle32 (USER32.94)
434  */
435 HDDEDATA WINAPI DdeCreateDataHandle32( DWORD idInst, LPBYTE pSrc, DWORD cb, 
436                                        DWORD cbOff, HSZ hszItem, UINT32 wFmt, 
437                                        UINT32 afCmd )
438 {
439     FIXME( ddeml,
440           "(%ld,%p,%ld,%ld,0x%lx,%d,%d): stub\n",
441           idInst,
442           pSrc,
443           cb,
444           cbOff,
445            hszItem,
446           wFmt, 
447           afCmd );
448
449     return 0;
450 }
451
452 /*****************************************************************
453  *            DdeDisconnect32   (USER32.97)
454  */
455 BOOL32 WINAPI DdeDisconnect32( HCONV hConv )
456 {
457     FIXME( ddeml, "empty stub\n" );
458     return 0;
459 }
460
461
462 /*****************************************************************
463  *            DdeReconnect   (DDEML.37) (USER32.115)
464  */
465 HCONV WINAPI DdeReconnect( HCONV hConv )
466 {
467     FIXME( ddeml, "empty stub\n" );
468     return 0;
469 }
470
471
472 /*****************************************************************
473  *            DdeCreateStringHandle16   (DDEML.21)
474  */
475 HSZ WINAPI DdeCreateStringHandle16( DWORD idInst, LPCSTR str, INT16 codepage )
476 {
477     return DdeCreateStringHandle32A( idInst, str, codepage );
478 }
479
480
481 /*****************************************************************
482  * DdeCreateStringHandle32A [USER32.95]
483  *
484  * RETURNS
485  *    Success: String handle
486  *    Failure: 0
487  */
488 HSZ WINAPI DdeCreateStringHandle32A( DWORD idInst, LPCSTR psz, INT32 codepage )
489 {
490   HSZ hsz = 0;
491   TRACE(ddeml, "(%ld,%s,%d): stub\n",idInst,debugstr_a(psz),codepage);
492   
493   if (codepage==CP_WINANSI)
494   {
495       hsz = GlobalAddAtom32A (psz);
496       /* Save the handle so we know to clean it when
497        * uninitialize is called.
498        */
499       InsertHSZNode( idInst, hsz );
500       return hsz;
501   }
502     return 0;  
503 }
504
505
506 /******************************************************************************
507  * DdeCreateStringHandle32W [USER32.96]  Creates handle to identify string
508  *
509  * RETURNS
510  *    Success: String handle
511  *    Failure: 0
512  */
513 HSZ WINAPI DdeCreateStringHandle32W(
514     DWORD idInst,   /* [in] Instance identifier */
515     LPCWSTR psz,    /* [in] Pointer to string */
516     INT32 codepage) /* [in] Code page identifier */
517 {
518   HSZ hsz = 0;
519
520     FIXME(ddeml, "(%ld,%s,%d): stub\n",idInst,debugstr_w(psz),codepage);
521
522   if (codepage==CP_WINUNICODE)
523   {
524       hsz = GlobalAddAtom32W (psz);
525       /* Save the handle so we know to clean it when
526        * uninitialize is called.
527        */
528       InsertHSZNode( idInst, hsz );
529       return hsz;
530 }
531   return 0;
532 }
533
534
535 /*****************************************************************
536  *            DdeFreeStringHandle16   (DDEML.22)
537  */
538 BOOL16 WINAPI DdeFreeStringHandle16( DWORD idInst, HSZ hsz )
539 {
540     return (BOOL32)DdeFreeStringHandle32( idInst, hsz );
541 }
542
543
544 /*****************************************************************
545  *            DdeFreeStringHandle32   (USER32.101)
546  * RETURNS: success: nonzero
547  *          fail:    zero
548  */
549 BOOL32 WINAPI DdeFreeStringHandle32( DWORD idInst, HSZ hsz )
550 {
551     TRACE( ddeml, "(%ld,%ld): stub\n",idInst, hsz );
552     /* Remove the node associated with this HSZ.
553      */
554     RemoveHSZNode( idInst, hsz );
555     /* Free the string associated with this HSZ.
556      */
557     return GlobalDeleteAtom (hsz) ? 0 : hsz;
558 }
559
560
561 /*****************************************************************
562  *            DdeFreeDataHandle16   (DDEML.19)
563  */
564 BOOL16 WINAPI DdeFreeDataHandle16( HDDEDATA hData )
565 {
566     return (BOOL32)DdeFreeDataHandle32( hData );
567 }
568
569
570 /*****************************************************************
571  *            DdeFreeDataHandle32   (USER32.100)
572  */
573 BOOL32 WINAPI DdeFreeDataHandle32( HDDEDATA hData )
574 {
575     FIXME( ddeml, "empty stub\n" );
576     return TRUE;
577 }
578
579
580
581
582 /*****************************************************************
583  *            DdeKeepStringHandle16   (DDEML.24)
584  */
585 BOOL16 WINAPI DdeKeepStringHandle16( DWORD idInst, HSZ hsz )
586 {
587     return (BOOL32)DdeKeepStringHandle32( idInst, hsz );
588 }
589
590
591 /*****************************************************************
592  *            DdeKeepStringHandle32  (USER32.108)
593  */
594 BOOL32 WINAPI DdeKeepStringHandle32( DWORD idInst, HSZ hsz )
595 {
596     FIXME( ddeml, "empty stub\n" );
597     return TRUE;
598 }
599
600
601 /*****************************************************************
602  *            DdeClientTransaction16  (DDEML.11)
603  */
604 HDDEDATA WINAPI DdeClientTransaction16( LPVOID pData, DWORD cbData,
605                                         HCONV hConv, HSZ hszItem, UINT16 wFmt,
606                                         UINT16 wType, DWORD dwTimeout,
607                                         LPDWORD pdwResult )
608 {
609     return DdeClientTransaction32( (LPBYTE)pData, cbData, hConv, hszItem,
610                                    wFmt, wType, dwTimeout, pdwResult );
611 }
612
613
614 /*****************************************************************
615  *            DdeClientTransaction32  (USER32.90)
616  */
617 HDDEDATA WINAPI DdeClientTransaction32( LPBYTE pData, DWORD cbData,
618                                         HCONV hConv, HSZ hszItem, UINT32 wFmt,
619                                         UINT32 wType, DWORD dwTimeout,
620                                         LPDWORD pdwResult )
621 {
622     FIXME( ddeml, "empty stub\n" );
623     return 0;
624 }
625
626 /*****************************************************************
627  *            DdeAbandonTransaction (DDEML.12)
628  */
629 BOOL16 WINAPI DdeAbandonTransaction( DWORD idInst, HCONV hConv, 
630                                      DWORD idTransaction )
631 {
632     FIXME( ddeml, "empty stub\n" );
633     return 0;
634 }
635
636
637 /*****************************************************************
638  * DdePostAdvise16 [DDEML.13]
639  */
640 BOOL16 WINAPI DdePostAdvise16( DWORD idInst, HSZ hszTopic, HSZ hszItem )
641 {
642     return (BOOL16)DdePostAdvise32(idInst, hszTopic, hszItem);
643 }
644
645
646 /******************************************************************************
647  * DdePostAdvise32 [USER32.110]  Send transaction to DDE callback function.
648  *
649  * RETURNS
650  *    Success: TRUE
651  *    Failure: FALSE
652  */
653 BOOL32 WINAPI DdePostAdvise32(
654     DWORD idInst, /* [in] Instance identifier */
655     HSZ hszTopic, /* [in] Handle to topic name string */
656     HSZ hszItem)  /* [in] Handle to item name string */
657 {
658     FIXME(ddeml, "(%ld,%ld,%ld): stub\n",idInst,hszTopic,hszItem);
659     return TRUE;
660 }
661
662
663 /*****************************************************************
664  *            DdeAddData (DDEML.15)
665  */
666 HDDEDATA WINAPI DdeAddData( HDDEDATA hData, LPBYTE pSrc, DWORD cb,
667                             DWORD cbOff )
668 {
669     FIXME( ddeml, "empty stub\n" );
670     return 0;
671 }
672
673
674 /******************************************************************************
675  * DdeGetData32 [USER32.102]  Copies data from DDE object ot local buffer
676  *
677  * RETURNS
678  *    Size of memory object associated with handle
679  */
680 DWORD WINAPI DdeGetData32(
681     HDDEDATA hData, /* [in] Handle to DDE object */
682     LPBYTE pDst,    /* [in] Pointer to destination buffer */
683     DWORD cbMax,    /* [in] Amount of data to copy */
684     DWORD cbOff)    /* [in] Offset to beginning of data */
685 {
686     FIXME(ddeml, "(%ld,%p,%ld,%ld): stub\n",hData,pDst,cbMax,cbOff);
687     return cbMax;
688 }
689
690
691 /*****************************************************************
692  * DdeGetData16 [DDEML.16]
693  */
694 DWORD WINAPI DdeGetData16(
695     HDDEDATA hData,
696     LPBYTE pDst,
697     DWORD cbMax, 
698     DWORD cbOff)
699 {
700     return DdeGetData32(hData, pDst, cbMax, cbOff);
701 }
702
703
704 /*****************************************************************
705  *            DdeAccessData16 (DDEML.17)
706  */
707 LPBYTE WINAPI DdeAccessData16( HDDEDATA hData, LPDWORD pcbDataSize )
708 {
709      return DdeAccessData32(hData, pcbDataSize);
710 }
711
712 /*****************************************************************
713  *            DdeAccessData32 (USER32.88)
714  */
715 LPBYTE WINAPI DdeAccessData32( HDDEDATA hData, LPDWORD pcbDataSize )
716 {
717      FIXME( ddeml, "(%ld,%p): stub\n", hData, pcbDataSize);
718      return 0;
719 }
720
721 /*****************************************************************
722  *            DdeUnaccessData16 (DDEML.18)
723  */
724 BOOL16 WINAPI DdeUnaccessData16( HDDEDATA hData )
725 {
726      return DdeUnaccessData32(hData);
727 }
728
729 /*****************************************************************
730  *            DdeUnaccessData32 (USER32.118)
731  */
732 BOOL32 WINAPI DdeUnaccessData32( HDDEDATA hData )
733 {
734      FIXME( ddeml, "(0x%lx): stub\n", hData);
735
736      return 0;
737 }
738
739 /*****************************************************************
740  *            DdeEnableCallback16 (DDEML.26)
741  */
742 BOOL16 WINAPI DdeEnableCallback16( DWORD idInst, HCONV hConv, UINT16 wCmd )
743 {
744      return DdeEnableCallback32(idInst, hConv, wCmd);
745 }
746
747 /*****************************************************************
748  *            DdeEnableCallback32 (USER32.99)
749  */
750 BOOL32 WINAPI DdeEnableCallback32( DWORD idInst, HCONV hConv, UINT32 wCmd )
751 {
752      FIXME( ddeml, "(%ld, 0x%lx, %d) stub\n", idInst, hConv, wCmd);
753
754      return 0;
755 }
756
757 /*****************************************************************
758  *            DdeNameService16  (DDEML.27)
759  */
760 HDDEDATA WINAPI DdeNameService16( DWORD idInst, HSZ hsz1, HSZ hsz2,
761                                   UINT16 afCmd )
762 {
763     return DdeNameService32( idInst, hsz1, hsz2, afCmd );
764 }
765
766
767 /******************************************************************************
768  * DdeNameService32 [USER32.109]  {Un}registers service name of DDE server
769  *
770  * PARAMS
771  *    idInst [I] Instance identifier
772  *    hsz1   [I] Handle to service name string
773  *    hsz2   [I] Reserved
774  *    afCmd  [I] Service name flags
775  *
776  * RETURNS
777  *    Success: Non-zero
778  *    Failure: 0
779  */
780 HDDEDATA WINAPI DdeNameService32( DWORD idInst, HSZ hsz1, HSZ hsz2,
781                 UINT32 afCmd )
782 {
783     FIXME(ddeml, "(%ld,%ld,%ld,%d): stub\n",idInst,hsz1,hsz2,afCmd);
784     return 1;
785 }
786
787
788 /*****************************************************************
789  *            DdeGetLastError16  (DDEML.20)
790  */
791 UINT16 WINAPI DdeGetLastError16( DWORD idInst )
792 {
793     return (UINT16)DdeGetLastError32( idInst );
794 }
795
796
797 /******************************************************************************
798  * DdeGetLastError32 [USER32.103]  Gets most recent error code
799  *
800  * PARAMS
801  *    idInst [I] Instance identifier
802  *
803  * RETURNS
804  *    Last error code
805  */
806 UINT32 WINAPI DdeGetLastError32( DWORD idInst )
807 {
808     FIXME(ddeml, "(%ld): stub\n",idInst);
809     return 0;
810 }
811
812
813 /*****************************************************************
814  *            DdeCmpStringHandles16 (DDEML.36)
815  */
816 int WINAPI DdeCmpStringHandles16( HSZ hsz1, HSZ hsz2 )
817 {
818      return DdeCmpStringHandles32(hsz1, hsz2);
819 }
820
821 /*****************************************************************
822  *            DdeCmpStringHandles32 (USER32.91)
823  *
824  * Compares the value of two string handles.  This comparison is
825  * not case sensitive.
826  *
827  * Returns:
828  * -1 The value of hsz1 is zero or less than hsz2
829  * 0  The values of hsz 1 and 2 are the same or both zero.
830  * 1  The value of hsz2 is zero of less than hsz1
831  */
832 int WINAPI DdeCmpStringHandles32( HSZ hsz1, HSZ hsz2 )
833 {
834     CHAR psz1[MAX_BUFFER_LEN];
835     CHAR psz2[MAX_BUFFER_LEN];
836     int ret = 0;
837     int ret1, ret2;
838
839     TRACE( ddeml, "handle 1, handle 2\n" );
840
841     ret1 = GlobalGetAtomName32A( hsz1, psz1, MAX_BUFFER_LEN );
842     ret2 = GlobalGetAtomName32A( hsz2, psz2, MAX_BUFFER_LEN );
843     /* Make sure we found both strings.
844      */
845     if( ret1 == 0 && ret2 == 0 )
846     {
847         /* If both are not found, return both  "zero strings".
848          */
849         ret = 0;
850     }
851     else if( ret1 == 0 )
852     {
853         /* If hsz1 is a not found, return hsz1 is "zero string".
854          */
855         ret = -1;
856     }
857     else if( ret2 == 0 )
858     {
859         /* If hsz2 is a not found, return hsz2 is "zero string".
860          */
861         ret = 1;
862     }
863     else
864     {
865         /* Compare the two strings we got ( case insensitive ).
866          */
867         ret = strcasecmp( psz1, psz2 );
868         /* Since strcmp returns any number smaller than
869          * 0 when the first string is found to be less than
870          * the second one we must make sure we are returning
871          * the proper values.
872          */
873         if( ret < 0 )
874         {
875             ret = -1;
876         }
877         else if( ret > 0 )
878         {
879             ret = 1;
880         }
881     }
882
883     return ret;
884 }
885
886 /*****************************************************************
887  *            PackDDElParam (USER32.414)
888  *
889  * RETURNS
890  *   success: nonzero
891  *   failure: zero
892  */
893 UINT32 WINAPI PackDDElParam(UINT32 msg, UINT32 uiLo, UINT32 uiHi)
894 {
895     FIXME(ddeml, "stub.\n");
896     return 0;
897 }
898
899
900 /*****************************************************************
901  *            UnpackDDElParam (USER32.562)
902  *
903  * RETURNS
904  *   success: nonzero
905  *   failure: zero
906  */
907 UINT32 WINAPI UnpackDDElParam(UINT32 msg, UINT32 lParam,
908                               UINT32 *uiLo, UINT32 *uiHi)
909 {
910     FIXME(ddeml, "stub.\n");
911     return 0;
912 }
913
914
915 /*****************************************************************
916  *            FreeDDElParam (USER32.204)
917  *
918  * RETURNS
919  *   success: nonzero
920  *   failure: zero
921  */
922 UINT32 WINAPI FreeDDElParam(UINT32 msg, UINT32 lParam)
923 {
924     FIXME(ddeml, "stub.\n");
925     return 0;
926 }
927
928 /*****************************************************************
929  *            ReuseDDElParam (USER32.446)
930  *
931  */
932 UINT32 WINAPI ReuseDDElParam(UINT32 lParam, UINT32 msgIn, UINT32 msgOut,
933                              UINT32 uiLi, UINT32 uiHi)
934 {
935     FIXME(ddeml, "stub.\n");
936     return 0;
937