Annotation of mstools/samples/ddeml/ddeprog/proghelp.c, revision 1.1.1.1

1.1       root        1: /*****************************************************************************\
                      2: * PROGHELP.C
                      3: *
                      4: * Main module to implement a simple DDEML service DLL that makes interaction
                      5: * with progman simple.
                      6: \*****************************************************************************/
                      7: 
                      8: #include <windows.h>
                      9: #include <ddeml.h>
                     10: #include <string.h>
                     11: 
                     12: typedef struct {
                     13:     HCONV hConv;
                     14:     DWORD idInst;
                     15:     int cTransactionsInProgress;
                     16: } THREADINFO;
                     17: 
                     18: DWORD TlsIndex;
                     19: 
                     20: /*
                     21:  * This is the default DDEML callback function for ProgHelp
                     22:  */
                     23: HDDEDATA CALLBACK ProgHelpDdeCallback(
                     24: UINT wType,
                     25: UINT wFmt,
                     26: HCONV hConv,
                     27: HSZ hsz1,
                     28: HSZ hsz2,
                     29: HDDEDATA hData,
                     30: DWORD dwData1,
                     31: DWORD dwData2)
                     32: {
                     33:     THREADINFO *pti;
                     34: 
                     35:     switch (wType) {
                     36:     case XTYP_XACT_COMPLETE:
                     37:         pti = TlsGetValue(TlsIndex);
                     38:         pti->cTransactionsInProgress--;
                     39:         break;
                     40:     }
                     41:     return(0);
                     42: }
                     43: 
                     44: 
                     45: /*
                     46:  * This is the DLL init routine called by the system at attach/detatch time.
                     47:  *
                     48:  * We allocate a Tls for each thread that calls this DLL so that their state
                     49:  * can be tracked independently.
                     50:  */
                     51: BOOLEAN APIENTRY ProgHelpInit(
                     52: IN PVOID hmod,
                     53: ULONG Reason,
                     54: IN PCONTEXT pctx OPTIONAL)
                     55: {
                     56:     THREADINFO *pti;
                     57:     UNREFERENCED_PARAMETER(hmod);
                     58:     UNREFERENCED_PARAMETER(pctx);
                     59: 
                     60:     switch (Reason) {
                     61:     case DLL_THREAD_ATTACH:
                     62:     case DLL_PROCESS_ATTACH:
                     63:         TlsIndex = TlsAlloc();
                     64:         pti = (THREADINFO *)LocalAlloc(LPTR, sizeof(THREADINFO));
                     65:         if (!pti) {
                     66:             return(FALSE);
                     67:         }
                     68:         TlsSetValue(TlsIndex, pti);
                     69:         break;
                     70: 
                     71:     case DLL_THREAD_DETACH:
                     72:     case DLL_PROCESS_DETACH:
                     73:         pti = TlsGetValue(TlsIndex);
                     74:         LocalFree(pti);
                     75:         TlsFree(TlsIndex);
                     76:         break;
                     77:     }
                     78:     return TRUE;
                     79: }
                     80: 
                     81: /*
                     82:  * An application must call this API first to establish a conversation
                     83:  * with progman.  DDEML initialization is done automatically if needed.
                     84:  */
                     85: BOOL ConnectToProgman()
                     86: {
                     87:     THREADINFO *pti;
                     88:     HSZ hszProgman;
                     89: 
                     90:     pti = TlsGetValue(TlsIndex);
                     91: 
                     92:     if (!pti->idInst) {
                     93:         if (DdeInitialize(&(pti->idInst), ProgHelpDdeCallback,
                     94:                 APPCMD_CLIENTONLY | CBF_SKIP_ALLNOTIFICATIONS,
                     95:                 0L) != DMLERR_NO_ERROR) {
                     96:             return(FALSE);
                     97:         }
                     98:     }
                     99: 
                    100:     if (pti->hConv == 0) {
                    101:         hszProgman = DdeCreateStringHandle(pti->idInst, "Progman", 0);
                    102:         pti->hConv = DdeConnect(pti->idInst, hszProgman, hszProgman, NULL);
                    103:     }
                    104:     return(pti->hConv != 0);
                    105: }
                    106: 
                    107: /*
                    108:  * This API should be called when operations with progman are complete.
                    109:  * We shutdown DDEML here as well so we don't have to deal with it
                    110:  * at DLL detatch time.  FALSE is returned if there are any transactions
                    111:  * still in progress.  This lets the calling application know that it
                    112:  * must wait awhile longer for progman to complete its processing and
                    113:  * then try disconnecting again later.
                    114:  */
                    115: BOOL DisconnectFromProgman()
                    116: {
                    117:     THREADINFO *pti;
                    118: 
                    119:     pti = TlsGetValue(TlsIndex);
                    120: 
                    121:     if (pti->cTransactionsInProgress) {
                    122:         return(FALSE);
                    123:     }
                    124: 
                    125:     if (!pti->idInst) {
                    126:         return(TRUE);
                    127:     }
                    128: 
                    129:     if (pti->hConv) {
                    130:         DdeDisconnect(pti->hConv);
                    131:         pti->hConv = 0;
                    132:     }
                    133: 
                    134:     DdeUninitialize(pti->idInst);
                    135:     return(TRUE);
                    136: }
                    137: 
                    138: 
                    139: /*
                    140:  * This API sends an ASCII execute string to progman.  It immediately returns
                    141:  * and the results of the execute are not known.  Calling applications should
                    142:  * be aware that these transactions are done asynchronously.  This allows
                    143:  * this API to work under modal-loop conditions.  DisconnectFromProgman()
                    144:  * will not succeed until all transactions are complete.
                    145:  */
                    146: BOOL ProgmanExecuteString(
                    147: LPCSTR pszExec)
                    148: {
                    149:     THREADINFO *pti;
                    150:     DWORD dwResult;
                    151: 
                    152:     pti = TlsGetValue(TlsIndex);
                    153: 
                    154:     if (!pti->idInst || !pti->hConv) {
                    155:         return(FALSE);
                    156:     }
                    157:     if (!DdeClientTransaction((PBYTE)pszExec, strlen(pszExec) + 1,
                    158:             pti->hConv, 0, 0, XTYP_EXECUTE, TIMEOUT_ASYNC, &dwResult)) {
                    159:         return(FALSE);
                    160:     }
                    161:     pti->cTransactionsInProgress++;
                    162:     return(TRUE);
                    163: }
                    164: 
                    165: 
                    166: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.