|
|
1.1.1.3 ! root 1: /*++ BUILD Version: 0001 // Increment this if a change has global effects --*/ 1.1 root 2: 3: /*****************************************************************************\ 4: * * 5: * ddeml.h - DDEML API header file 6: * * 7: * Version 3.10 * * 8: * * 1.1.1.3 ! root 9: * Copyright (c) 1993, Microsoft Corp. All rights reserved. * 1.1 root 10: * * 11: \*****************************************************************************/ 12: #ifndef _INC_DDEMLH 13: #define _INC_DDEMLH 14: 1.1.1.3 ! root 15: #ifdef __cplusplus ! 16: extern "C" { ! 17: #endif /* __cplusplus */ ! 18: 1.1 root 19: /******** public types ********/ 20: 1.1.1.3 ! root 21: typedef DWORD HCONVLIST; ! 22: typedef DWORD HCONV; ! 23: typedef DWORD HSZ; ! 24: typedef DWORD HDDEDATA; ! 25: #define EXPENTRY CALLBACK 1.1 root 26: 27: /* the following structure is for use with XTYP_WILDCONNECT processing. */ 28: 29: typedef struct tagHSZPAIR { 30: HSZ hszSvc; 31: HSZ hszTopic; 32: } HSZPAIR; 33: typedef HSZPAIR FAR *PHSZPAIR; 34: 35: /* The following structure is used by DdeConnect() and DdeConnectList() and 36: by XTYP_CONNECT and XTYP_WILDCONNECT callbacks. */ 37: 38: typedef struct tagCONVCONTEXT { 39: UINT cb; /* set to sizeof(CONVCONTEXT) */ 40: UINT wFlags; /* none currently defined. */ 41: UINT wCountryID; /* country code for topic/item strings used. */ 42: int iCodePage; /* codepage used for topic/item strings. */ 43: DWORD dwLangID; /* language ID for topic/item strings. */ 44: DWORD dwSecurity; /* Private security code. */ 1.1.1.3 ! root 45: SECURITY_QUALITY_OF_SERVICE qos; /* client side's quality of service */ 1.1 root 46: } CONVCONTEXT; 47: typedef CONVCONTEXT FAR *PCONVCONTEXT; 48: 49: 50: /* The following structure is used by DdeQueryConvInfo(): */ 51: 52: typedef struct tagCONVINFO { 53: DWORD cb; /* sizeof(CONVINFO) */ 54: DWORD hUser; /* user specified field */ 55: HCONV hConvPartner; /* hConv on other end or 0 if non-ddemgr partner */ 56: HSZ hszSvcPartner; /* app name of partner if obtainable */ 57: HSZ hszServiceReq; /* AppName requested for connection */ 58: HSZ hszTopic; /* Topic name for conversation */ 59: HSZ hszItem; /* transaction item name or NULL if quiescent */ 60: UINT wFmt; /* transaction format or NULL if quiescent */ 61: UINT wType; /* XTYP_ for current transaction */ 62: UINT wStatus; /* ST_ constant for current conversation */ 63: UINT wConvst; /* XST_ constant for current transaction */ 64: UINT wLastError; /* last transaction error. */ 65: HCONVLIST hConvList; /* parent hConvList if this conversation is in a list */ 66: CONVCONTEXT ConvCtxt; /* conversation context */ 1.1.1.2 root 67: HWND hwnd; /* window handle for this conversation */ 68: HWND hwndPartner; /* partner window handle for this conversation */ 1.1 root 69: } CONVINFO; 70: typedef CONVINFO FAR *PCONVINFO; 71: 72: /***** conversation states (usState) *****/ 73: 74: #define XST_NULL 0 /* quiescent states */ 75: #define XST_INCOMPLETE 1 76: #define XST_CONNECTED 2 77: #define XST_INIT1 3 /* mid-initiation states */ 78: #define XST_INIT2 4 79: #define XST_REQSENT 5 /* active conversation states */ 80: #define XST_DATARCVD 6 81: #define XST_POKESENT 7 82: #define XST_POKEACKRCVD 8 83: #define XST_EXECSENT 9 84: #define XST_EXECACKRCVD 10 85: #define XST_ADVSENT 11 86: #define XST_UNADVSENT 12 87: #define XST_ADVACKRCVD 13 88: #define XST_UNADVACKRCVD 14 89: #define XST_ADVDATASENT 15 90: #define XST_ADVDATAACKRCVD 16 91: 92: /* used in LOWORD(dwData1) of XTYP_ADVREQ callbacks... */ 93: #define CADV_LATEACK 0xFFFF 94: 95: /***** conversation status bits (fsStatus) *****/ 96: 1.1.1.3 ! root 97: #define ST_CONNECTED 0x0001 ! 98: #define ST_ADVISE 0x0002 ! 99: #define ST_ISLOCAL 0x0004 ! 100: #define ST_BLOCKED 0x0008 ! 101: #define ST_CLIENT 0x0010 ! 102: #define ST_TERMINATED 0x0020 ! 103: #define ST_INLIST 0x0040 ! 104: #define ST_BLOCKNEXT 0x0080 ! 105: #define ST_ISSELF 0x0100 1.1 root 106: 107: 108: /* DDE constants for wStatus field */ 109: 1.1.1.3 ! root 110: #define DDE_FACK 0x8000 ! 111: #define DDE_FBUSY 0x4000 ! 112: #define DDE_FDEFERUPD 0x4000 ! 113: #define DDE_FACKREQ 0x8000 ! 114: #define DDE_FRELEASE 0x2000 ! 115: #define DDE_FREQUESTED 0x1000 ! 116: #define DDE_FAPPSTATUS 0x00ff 1.1.1.2 root 117: #define DDE_FNOTPROCESSED 0x0000 118: 1.1.1.3 ! root 119: #define DDE_FACKRESERVED (~(DDE_FACK | DDE_FBUSY | DDE_FAPPSTATUS)) ! 120: #define DDE_FADVRESERVED (~(DDE_FACKREQ | DDE_FDEFERUPD)) ! 121: #define DDE_FDATRESERVED (~(DDE_FACKREQ | DDE_FRELEASE | DDE_FREQUESTED)) ! 122: #define DDE_FPOKRESERVED (~(DDE_FRELEASE)) 1.1 root 123: 124: /***** message filter hook types *****/ 125: 126: #define MSGF_DDEMGR 0x8001 127: 128: /***** codepage constants ****/ 129: 130: #define CP_WINANSI 1004 /* default codepage for windows & old DDE convs. */ 131: #define CP_WINUNICODE 1200 132: 133: /***** transaction types *****/ 134: 135: #define XTYPF_NOBLOCK 0x0002 /* CBR_BLOCK will not work */ 136: #define XTYPF_NODATA 0x0004 /* DDE_FDEFERUPD */ 137: #define XTYPF_ACKREQ 0x0008 /* DDE_FACKREQ */ 138: 139: #define XCLASS_MASK 0xFC00 140: #define XCLASS_BOOL 0x1000 141: #define XCLASS_DATA 0x2000 142: #define XCLASS_FLAGS 0x4000 143: #define XCLASS_NOTIFICATION 0x8000 144: 145: #define XTYP_ERROR (0x0000 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK ) 146: #define XTYP_ADVDATA (0x0010 | XCLASS_FLAGS ) 147: #define XTYP_ADVREQ (0x0020 | XCLASS_DATA | XTYPF_NOBLOCK ) 148: #define XTYP_ADVSTART (0x0030 | XCLASS_BOOL ) 149: #define XTYP_ADVSTOP (0x0040 | XCLASS_NOTIFICATION) 150: #define XTYP_EXECUTE (0x0050 | XCLASS_FLAGS ) 151: #define XTYP_CONNECT (0x0060 | XCLASS_BOOL | XTYPF_NOBLOCK) 152: #define XTYP_CONNECT_CONFIRM (0x0070 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK) 153: #define XTYP_XACT_COMPLETE (0x0080 | XCLASS_NOTIFICATION ) 154: #define XTYP_POKE (0x0090 | XCLASS_FLAGS ) 155: #define XTYP_REGISTER (0x00A0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK) 156: #define XTYP_REQUEST (0x00B0 | XCLASS_DATA ) 157: #define XTYP_DISCONNECT (0x00C0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK) 158: #define XTYP_UNREGISTER (0x00D0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK) 159: #define XTYP_WILDCONNECT (0x00E0 | XCLASS_DATA | XTYPF_NOBLOCK) 160: 161: #define XTYP_MASK 0x00F0 162: #define XTYP_SHIFT 4 /* shift to turn XTYP_ into an index */ 163: 164: /***** Timeout constants *****/ 165: 166: #define TIMEOUT_ASYNC 0xFFFFFFFF 167: 168: /***** Transaction ID constants *****/ 169: 170: #define QID_SYNC 0xFFFFFFFF 171: 172: /****** public strings used in DDE ******/ 173: 1.1.1.3 ! root 174: #ifdef UNICODE ! 175: #define SZDDESYS_TOPIC L"System" ! 176: #define SZDDESYS_ITEM_TOPICS L"Topics" ! 177: #define SZDDESYS_ITEM_SYSITEMS L"SysItems" ! 178: #define SZDDESYS_ITEM_RTNMSG L"ReturnMessage" ! 179: #define SZDDESYS_ITEM_STATUS L"Status" ! 180: #define SZDDESYS_ITEM_FORMATS L"Formats" ! 181: #define SZDDESYS_ITEM_HELP L"Help" ! 182: #define SZDDE_ITEM_ITEMLIST L"TopicItemList" ! 183: #else ! 184: #define SZDDESYS_TOPIC "System" ! 185: #define SZDDESYS_ITEM_TOPICS "Topics" ! 186: #define SZDDESYS_ITEM_SYSITEMS "SysItems" ! 187: #define SZDDESYS_ITEM_RTNMSG "ReturnMessage" ! 188: #define SZDDESYS_ITEM_STATUS "Status" ! 189: #define SZDDESYS_ITEM_FORMATS "Formats" ! 190: #define SZDDESYS_ITEM_HELP "Help" ! 191: #define SZDDE_ITEM_ITEMLIST "TopicItemList" ! 192: #endif 1.1 root 193: 194: 195: /****** API entry points ******/ 196: 197: typedef HDDEDATA CALLBACK FNCALLBACK(UINT wType, UINT wFmt, HCONV hConv, 198: HSZ hsz1, HSZ hsz2, HDDEDATA hData, DWORD dwData1, DWORD dwData2); 1.1.1.3 ! root 199: typedef HDDEDATA (CALLBACK *PFNCALLBACK)(UINT wType, UINT wFmt, HCONV hConv, ! 200: HSZ hsz1, HSZ hsz2, HDDEDATA hData, DWORD dwData1, DWORD dwData2); 1.1 root 201: 202: #define CBR_BLOCK 0xffffffffL 203: 204: /* DLL registration functions */ 205: 206: UINT WINAPI DdeInitializeA(LPDWORD pidInst, PFNCALLBACK pfnCallback, 207: DWORD afCmd, DWORD ulRes); 208: UINT WINAPI DdeInitializeW(LPDWORD pidInst, PFNCALLBACK pfnCallback, 209: DWORD afCmd, DWORD ulRes); 210: #ifdef UNICODE 1.1.1.3 ! root 211: #define DdeInitialize DdeInitializeW 1.1 root 212: #else 1.1.1.3 ! root 213: #define DdeInitialize DdeInitializeA 1.1 root 214: #endif // !UNICODE 215: 216: /* 217: * Callback filter flags for use with standard apps. 218: */ 219: 220: #define CBF_FAIL_SELFCONNECTIONS 0x00001000 221: #define CBF_FAIL_CONNECTIONS 0x00002000 222: #define CBF_FAIL_ADVISES 0x00004000 223: #define CBF_FAIL_EXECUTES 0x00008000 224: #define CBF_FAIL_POKES 0x00010000 225: #define CBF_FAIL_REQUESTS 0x00020000 226: #define CBF_FAIL_ALLSVRXACTIONS 0x0003f000 227: 228: #define CBF_SKIP_CONNECT_CONFIRMS 0x00040000 229: #define CBF_SKIP_REGISTRATIONS 0x00080000 230: #define CBF_SKIP_UNREGISTRATIONS 0x00100000 231: #define CBF_SKIP_DISCONNECTS 0x00200000 232: #define CBF_SKIP_ALLNOTIFICATIONS 0x003c0000 233: 234: /* 235: * Application command flags 236: */ 237: #define APPCMD_CLIENTONLY 0x00000010L 238: #define APPCMD_FILTERINITS 0x00000020L 239: #define APPCMD_MASK 0x00000FF0L 240: 241: /* 242: * Application classification flags 243: */ 244: #define APPCLASS_STANDARD 0x00000000L 245: #define APPCLASS_MASK 0x0000000FL 246: 247: 248: 249: BOOL WINAPI DdeUninitialize(DWORD idInst); 250: 1.1.1.3 ! root 251: /* ! 252: * conversation enumeration functions ! 253: */ 1.1 root 254: 255: HCONVLIST WINAPI DdeConnectList(DWORD idInst, HSZ hszService, HSZ hszTopic, 256: HCONVLIST hConvList, PCONVCONTEXT pCC); 257: HCONV WINAPI DdeQueryNextServer(HCONVLIST hConvList, HCONV hConvPrev); 258: BOOL WINAPI DdeDisconnectList(HCONVLIST hConvList); 259: 1.1.1.3 ! root 260: /* ! 261: * conversation control functions ! 262: */ 1.1 root 263: 264: HCONV WINAPI DdeConnect(DWORD idInst, HSZ hszService, HSZ hszTopic, 265: PCONVCONTEXT pCC); 266: BOOL WINAPI DdeDisconnect(HCONV hConv); 267: HCONV WINAPI DdeReconnect(HCONV hConv); 268: UINT WINAPI DdeQueryConvInfo(HCONV hConv, DWORD idTransaction, PCONVINFO pConvInfo); 269: BOOL WINAPI DdeSetUserHandle(HCONV hConv, DWORD id, DWORD hUser); 270: BOOL WINAPI DdeAbandonTransaction(DWORD idInst, HCONV hConv, DWORD idTransaction); 271: 272: 1.1.1.3 ! root 273: /* ! 274: * app server interface functions ! 275: */ 1.1 root 276: 277: BOOL WINAPI DdePostAdvise(DWORD idInst, HSZ hszTopic, HSZ hszItem); 278: BOOL WINAPI DdeEnableCallback(DWORD idInst, HCONV hConv, UINT wCmd); 1.1.1.3 ! root 279: BOOL WINAPI DdeImpersonateClient(HCONV hConv); 1.1 root 280: 281: #define EC_ENABLEALL 0 282: #define EC_ENABLEONE ST_BLOCKNEXT 283: #define EC_DISABLE ST_BLOCKED 284: #define EC_QUERYWAITING 2 285: 286: 287: HDDEDATA WINAPI DdeNameService(DWORD idInst, HSZ hsz1, HSZ hsz2, UINT afCmd); 288: 289: #define DNS_REGISTER 0x0001 290: #define DNS_UNREGISTER 0x0002 291: #define DNS_FILTERON 0x0004 292: #define DNS_FILTEROFF 0x0008 293: 1.1.1.3 ! root 294: /* ! 295: * app client interface functions ! 296: */ 1.1 root 297: 298: HDDEDATA WINAPI DdeClientTransaction(LPBYTE pData, DWORD cbData, 299: HCONV hConv, HSZ hszItem, UINT wFmt, UINT wType, 300: DWORD dwTimeout, LPDWORD pdwResult); 301: 1.1.1.3 ! root 302: /* ! 303: *data transfer functions ! 304: */ 1.1 root 305: 306: HDDEDATA WINAPI DdeCreateDataHandle(DWORD idInst, LPBYTE pSrc, DWORD cb, 307: DWORD cbOff, HSZ hszItem, UINT wFmt, UINT afCmd); 308: HDDEDATA WINAPI DdeAddData(HDDEDATA hData, LPBYTE pSrc, DWORD cb, DWORD cbOff); 309: DWORD WINAPI DdeGetData(HDDEDATA hData, LPBYTE pDst, DWORD cbMax, DWORD cbOff); 310: LPBYTE WINAPI DdeAccessData(HDDEDATA hData, LPDWORD pcbDataSize); 311: BOOL WINAPI DdeUnaccessData(HDDEDATA hData); 312: BOOL WINAPI DdeFreeDataHandle(HDDEDATA hData); 313: 314: #define HDATA_APPOWNED 0x0001 315: 316: 317: UINT WINAPI DdeGetLastError(DWORD idInst); 318: 319: #define DMLERR_NO_ERROR 0 /* must be 0 */ 320: 321: #define DMLERR_FIRST 0x4000 322: 323: #define DMLERR_ADVACKTIMEOUT 0x4000 324: #define DMLERR_BUSY 0x4001 325: #define DMLERR_DATAACKTIMEOUT 0x4002 326: #define DMLERR_DLL_NOT_INITIALIZED 0x4003 327: #define DMLERR_DLL_USAGE 0x4004 328: #define DMLERR_EXECACKTIMEOUT 0x4005 329: #define DMLERR_INVALIDPARAMETER 0x4006 330: #define DMLERR_LOW_MEMORY 0x4007 331: #define DMLERR_MEMORY_ERROR 0x4008 332: #define DMLERR_NOTPROCESSED 0x4009 333: #define DMLERR_NO_CONV_ESTABLISHED 0x400a 334: #define DMLERR_POKEACKTIMEOUT 0x400b 335: #define DMLERR_POSTMSG_FAILED 0x400c 336: #define DMLERR_REENTRANCY 0x400d 337: #define DMLERR_SERVER_DIED 0x400e 338: #define DMLERR_SYS_ERROR 0x400f 339: #define DMLERR_UNADVACKTIMEOUT 0x4010 340: #define DMLERR_UNFOUND_QUEUE_ID 0x4011 341: 342: #define DMLERR_LAST 0x4011 343: 344: HSZ WINAPI DdeCreateStringHandleA(DWORD idInst, LPSTR psz, int iCodePage); 345: HSZ WINAPI DdeCreateStringHandleW(DWORD idInst, LPWSTR psz, int iCodePage); 346: #ifdef UNICODE 1.1.1.3 ! root 347: #define DdeCreateStringHandle DdeCreateStringHandleW 1.1 root 348: #else 1.1.1.3 ! root 349: #define DdeCreateStringHandle DdeCreateStringHandleA 1.1 root 350: #endif // !UNICODE 351: DWORD WINAPI DdeQueryStringA(DWORD idInst, HSZ hsz, LPSTR psz, DWORD cchMax, int iCodePage); 352: DWORD WINAPI DdeQueryStringW(DWORD idInst, HSZ hsz, LPWSTR psz, DWORD cchMax, int iCodePage); 353: #ifdef UNICODE 1.1.1.3 ! root 354: #define DdeQueryString DdeQueryStringW 1.1 root 355: #else 1.1.1.3 ! root 356: #define DdeQueryString DdeQueryStringA 1.1 root 357: #endif // !UNICODE 358: BOOL WINAPI DdeFreeStringHandle(DWORD idInst, HSZ hsz); 359: BOOL WINAPI DdeKeepStringHandle(DWORD idInst, HSZ hsz); 360: int WINAPI DdeCmpStringHandles(HSZ hsz1, HSZ hsz2); 361: 362: 363: #ifndef NODDEMLSPY 1.1.1.3 ! root 364: /* ! 365: * DDEML public debugging header file info ! 366: */ 1.1 root 367: 368: typedef struct tagDDEML_MSG_HOOK_DATA { // new for NT 369: UINT uiLo; // unpacked lo and hi parts of lParam 370: UINT uiHi; 371: DWORD cbData; // amount of data in message, if any. May be > than 32 bytes. 372: DWORD Data[8]; // data peeking by DDESPY is limited to 32 bytes. 373: } DDEML_MSG_HOOK_DATA, *PDDEML_MSG_HOOK_DATA; 374: 375: 376: typedef struct tagMONMSGSTRUCT { 377: UINT cb; 378: HWND hwndTo; 379: DWORD dwTime; 380: HANDLE hTask; 381: UINT wMsg; 382: WPARAM wParam; 383: LPARAM lParam; 384: DDEML_MSG_HOOK_DATA dmhd; // new for NT 1.1.1.3 ! root 385: } MONMSGSTRUCT, *PMONMSGSTRUCT; 1.1 root 386: 387: typedef struct tagMONCBSTRUCT { 388: UINT cb; 389: DWORD dwTime; 390: HANDLE hTask; 391: DWORD dwRet; 392: UINT wType; 393: UINT wFmt; 394: HCONV hConv; 395: HSZ hsz1; 396: HSZ hsz2; 397: HDDEDATA hData; 398: DWORD dwData1; 399: DWORD dwData2; 400: CONVCONTEXT cc; // new for NT for XTYP_CONNECT callbacks 401: DWORD cbData; // new for NT for data peeking 402: DWORD Data[8]; // new for NT for data peeking 1.1.1.3 ! root 403: } MONCBSTRUCT, *PMONCBSTRUCT; 1.1 root 404: 1.1.1.3 ! root 405: typedef struct tagMONHSZSTRUCTA { 1.1 root 406: UINT cb; 407: BOOL fsAction; /* MH_ value */ 408: DWORD dwTime; 409: HSZ hsz; 410: HANDLE hTask; 1.1.1.3 ! root 411: CHAR str[1]; ! 412: } MONHSZSTRUCTA, *PMONHSZSTRUCTA; ! 413: typedef struct tagMONHSZSTRUCTW { ! 414: UINT cb; ! 415: BOOL fsAction; /* MH_ value */ ! 416: DWORD dwTime; ! 417: HSZ hsz; ! 418: HANDLE hTask; ! 419: WCHAR str[1]; ! 420: } MONHSZSTRUCTW, *PMONHSZSTRUCTW; ! 421: #ifdef UNICODE ! 422: typedef MONHSZSTRUCTW MONHSZSTRUCT; ! 423: typedef PMONHSZSTRUCTW PMONHSZSTRUCT; ! 424: #else ! 425: typedef MONHSZSTRUCTA MONHSZSTRUCT; ! 426: typedef PMONHSZSTRUCTA PMONHSZSTRUCT; ! 427: #endif // UNICODE 1.1 root 428: 429: #define MH_CREATE 1 430: #define MH_KEEP 2 431: #define MH_DELETE 3 432: #define MH_CLEANUP 4 433: 434: typedef struct tagMONERRSTRUCT { 435: UINT cb; 436: UINT wLastError; 437: DWORD dwTime; 438: HANDLE hTask; 1.1.1.3 ! root 439: } MONERRSTRUCT, *PMONERRSTRUCT; 1.1 root 440: 441: typedef struct tagMONLINKSTRUCT { 442: UINT cb; 443: DWORD dwTime; 444: HANDLE hTask; 445: BOOL fEstablished; 446: BOOL fNoData; 447: HSZ hszSvc; 448: HSZ hszTopic; 449: HSZ hszItem; 450: UINT wFmt; 451: BOOL fServer; 452: HCONV hConvServer; 453: HCONV hConvClient; 1.1.1.3 ! root 454: } MONLINKSTRUCT, *PMONLINKSTRUCT; 1.1 root 455: 456: typedef struct tagMONCONVSTRUCT { 457: UINT cb; 458: BOOL fConnect; 459: DWORD dwTime; 460: HANDLE hTask; 461: HSZ hszSvc; 462: HSZ hszTopic; 463: HCONV hConvClient; // Globally unique value != apps local hConv 464: HCONV hConvServer; // Globally unique value != apps local hConv 1.1.1.3 ! root 465: } MONCONVSTRUCT, PMONCONVSTRUCT; 1.1 root 466: 467: #define MAX_MONITORS 4 468: #define APPCLASS_MONITOR 0x00000001L 469: #define XTYP_MONITOR (0x00F0 | XCLASS_NOTIFICATION | XTYPF_NOBLOCK) 470: 471: /* 472: * Callback filter flags for use with MONITOR apps - 0 implies no monitor 473: * callbacks. 474: */ 475: #define MF_HSZ_INFO 0x01000000 476: #define MF_SENDMSGS 0x02000000 477: #define MF_POSTMSGS 0x04000000 478: #define MF_CALLBACKS 0x08000000 479: #define MF_ERRORS 0x10000000 480: #define MF_LINKS 0x20000000 481: #define MF_CONV 0x40000000 482: 483: #define MF_MASK 0xFF000000 484: #endif /* NODDEMLSPY */ 485: 1.1.1.3 ! root 486: #ifdef __cplusplus ! 487: } ! 488: #endif /* __cplusplus */ 1.1 root 489: 490: #endif /* _INC_DDEMLH */ 491: 492:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.