00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <windows.h>
00027
00028
00029 #define DC_MICROSOFT 0x0000 // Default
00030 #define DC_BORLAND 0x0001 // Borland compat
00031 #define DC_CALL_CDECL 0x0010 // __cdecl
00032 #define DC_CALL_STD 0x0020 // __stdcall
00033 #define DC_RETVAL_MATH4 0x0100 // Return value in ST
00034 #define DC_RETVAL_MATH8 0x0200 // Return value in ST
00035
00036 #define DC_CALL_STD_BO (DC_CALL_STD | DC_BORLAND)
00037 #define DC_CALL_STD_MS (DC_CALL_STD | DC_MICROSOFT)
00038 #define DC_CALL_STD_M8 (DC_CALL_STD | DC_RETVAL_MATH8)
00039
00040 #define DC_FLAG_ARGPTR 0x00000002
00041
00042 #pragma pack(1) // Set struct packing to one byte
00043
00044 typedef union T_RESULT {
00045 int Int;
00046 long Long;
00047 void *Pointer;
00048 float Float;
00049 double Double;
00050 __int64 int64;
00051 } T_RESULT;
00052
00053 typedef struct _DYNAPARM {
00054 DWORD dwFlags;
00055 int nWidth;
00056 union {
00057 DWORD dwArg;
00058 void *pArg;
00059 };
00060 } DYNAPARM;
00061
00062 static
00063 DWORD WINAPI SearchProcAddress(HMODULE hInst, LPSTR szFunction)
00064 {
00065
00066
00067
00068 DWORD dwAddr;
00069 char szName[128];
00070 #pragma warning ( disable : 4311 )
00071 if ((dwAddr = (DWORD)GetProcAddress(hInst, szFunction)) == 0) {
00072
00073 strcpy(szName, szFunction);
00074 strcat(szName, "A");
00075 dwAddr = (DWORD)GetProcAddress(hInst, szName);
00076 }
00077 return dwAddr;
00078 }
00079
00080
00081 static
00082 T_RESULT WINAPI DynaCall(int Flags, DWORD lpFunction,
00083 int nArgs, DYNAPARM Parm[],
00084 LPVOID pRet, int nRetSiz)
00085 {
00086
00087
00088 T_RESULT Res = { 0 };
00089 int i, nInd, nSize;
00090 DWORD dwEAX, dwEDX, dwVal, *pStack, dwStSize = 0;
00091 BYTE *pArg;
00092
00093
00094 _asm mov pStack, esp
00095 _asm sub esp, 0x100
00096
00097
00098
00099 for (i = 0; i < nArgs; i++) {
00100 nInd = (nArgs - 1) - i;
00101
00102 nSize = (Parm[nInd].nWidth + 3) / 4 * 4;
00103 pArg = (BYTE *)Parm[nInd].pArg + nSize - 4;
00104 dwStSize += (DWORD)nSize;
00105 while (nSize > 0) {
00106
00107 if (Parm[nInd].dwFlags & DC_FLAG_ARGPTR) {
00108
00109 dwVal = *(DWORD *)pArg;
00110 pArg -= 4;
00111 }
00112 else {
00113
00114 dwVal = Parm[nInd].dwArg;
00115 }
00116
00117 pStack--;
00118 *pStack = dwVal;
00119 nSize -= 4;
00120 }
00121 }
00122 if ((pRet != NULL) && ((Flags & DC_BORLAND) || (nRetSiz > 8))) {
00123
00124
00125 dwStSize += 4;
00126 pStack--;
00127 *pStack = (DWORD)pRet;
00128 }
00129
00130 _asm add esp, 0x100
00131 _asm sub esp, dwStSize
00132
00133
00134 _asm call [lpFunction]
00135
00136 _asm mov dwEAX, eax
00137 _asm mov dwEDX, edx
00138
00139
00140 if (Flags & DC_CALL_CDECL) {
00141 _asm add esp, dwStSize
00142 }
00143 if (Flags & DC_RETVAL_MATH4) {
00144 _asm fstp dword ptr [Res]
00145 }
00146 else if (Flags & DC_RETVAL_MATH8) {
00147 _asm fstp qword ptr [Res]
00148 }
00149 else if (pRet == NULL) {
00150 _asm mov eax, [dwEAX]
00151 _asm mov DWORD PTR [Res], eax
00152 _asm mov edx, [dwEDX]
00153 _asm mov DWORD PTR [Res + 4], edx
00154 }
00155 else if (((Flags & DC_BORLAND) == 0) && (nRetSiz <= 8)) {
00156
00157 _asm mov ecx, DWORD PTR [pRet]
00158 _asm mov eax, [dwEAX]
00159 _asm mov DWORD PTR [ecx], eax
00160 _asm mov edx, [dwEDX]
00161 _asm mov DWORD PTR [ecx + 4], edx
00162 }
00163 return Res;
00164 }
00165
00166 #include <stdio.h>
00167 #include "../../basext.h"
00168
00169
00170
00171
00172
00173
00174 typedef struct _DllLoaded {
00175 HMODULE hDll;
00176 char *pszName;
00177 struct _DllLoaded *next;
00178 } DllLoaded, *pDllLoaded;
00179
00180 typedef struct _ModuleObject {
00181 pDllLoaded pDllList;
00182 }ModuleObject,*pModuleObject;
00183
00184 besVERSION_NEGOTIATE
00185 return (int)INTERFACE_VERSION;
00186 besEND
00187
00188
00189
00190
00191
00192 besSUB_ERRMSG
00193
00194 switch( iError ){
00195 case 0x00080000: return "ERROR HAS HAPPENED";
00196 }
00197 return "Unknown dyc module error.";
00198 besEND
00199
00200
00201 besSUB_START
00202 pModuleObject p;
00203
00204 besMODULEPOINTER = besALLOC(sizeof(ModuleObject));
00205 if( besMODULEPOINTER == NULL )return COMMAND_ERROR_MEMORY_LOW;
00206 p = besMODULEPOINTER;
00207 p->pDllList = NULL;
00208 return COMMAND_ERROR_SUCCESS;
00209 besEND
00210
00211 besSUB_FINISH
00212 pModuleObject p;
00213 pDllLoaded pDll;
00214
00215 p = (pModuleObject)besMODULEPOINTER;
00216 if( p == NULL )return 0;
00217
00218
00219 pDll = p->pDllList;
00220 while( pDll ){
00221 FreeLibrary(pDll->hDll);
00222 pDll = pDll->next;
00223 }
00224 return 0;
00225 besEND
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 #define LibraryLoaded(pszName) F_LibraryLoaded(pSt,ppModuleInternal,pszName)
00248 static HMODULE F_LibraryLoaded(pSupportTable pSt,
00249 void **ppModuleInternal,
00250 char *pszName){
00251 pDllLoaded pDll,pNew;
00252 pModuleObject p = (pModuleObject)besMODULEPOINTER;
00253
00254 pDll = p->pDllList;
00255
00256 while( pDll ){
00257 if( ! stricmp(pszName,pDll->pszName) )break;
00258 pDll = pDll->next;
00259 }
00260 if( pDll )
00261 return pDll->hDll;
00262
00263 pNew = (pDllLoaded)besALLOC(sizeof(DllLoaded));
00264
00265
00266 if( NULL == pNew )return NULL;
00267
00268
00269 pNew->pszName = besALLOC(strlen(pszName)+1);
00270 if( NULL == pNew->pszName ){
00271 besFREE(pNew);
00272 return NULL;
00273 }
00274
00275
00276 strcpy(pNew->pszName,pszName);
00277
00278
00279 pNew->next = p->pDllList;
00280 p->pDllList = pNew;
00281 pNew->hDll = LoadLibrary(pNew->pszName);
00282 return pNew->hDll;
00283 }
00284
00438 besFUNCTION(dyc)
00439 pModuleObject p;
00440 VARIABLE Argument;
00441 int Flags;
00442 DWORD lpFunction;
00443 int nArgs;
00444 DYNAPARM *Parm;
00445 int nRetSiz;
00446 char *pszFormat;
00447 DWORD cbFormat;
00448 int iParseState;
00449 char cRet;
00450 char szDll[MAX_PATH];
00451 char szFunction[MAX_PATH];
00452 char *pszS;
00453 int i;
00454 HMODULE hDll;
00455 T_RESULT RetVal;
00456 float fTmp;
00457
00458 p = (pModuleObject)besMODULEPOINTER;
00459 besRETURNVALUE = NULL;
00460
00461 Argument = besARGUMENT(1);
00462 besDEREFERENCE(Argument);
00463
00464
00465 if( Argument == NULL )return COMMAND_ERROR_FEW_ARGS;
00466
00467 Argument = besCONVERT2STRING(Argument);
00468 pszFormat = STRINGVALUE(Argument);
00469 cbFormat = STRLEN(Argument);
00470 if( cbFormat < 1 )return COMMAND_ERROR_ARGUMENT_TYPE;
00471 iParseState = 0;
00472 Flags = 0;
00473 while( cbFormat ){
00474 switch( iParseState ){
00475 case 0:
00476 switch( *pszFormat ){
00477 case 'm': case 'M': Flags |= DC_MICROSOFT; break;
00478 case 'b': case 'B': Flags |= DC_BORLAND; break;
00479 case 'c': case 'C': Flags |= DC_CALL_CDECL; break;
00480 case 's': case 'S': Flags |= DC_CALL_STD; break;
00481 case '4': Flags |= DC_RETVAL_MATH4; break;
00482 case '8': Flags |= DC_RETVAL_MATH8; break;
00483 case ',' : iParseState++; break;
00484 }
00485 cbFormat --;
00486 pszFormat++;
00487 break;
00488 case 1:
00489 if( cbFormat < 1 )return COMMAND_ERROR_ARGUMENT_TYPE;
00490 cRet = tolower(*pszFormat);
00491 switch( cRet ){
00492 case 'I': case 'i': nRetSiz = sizeof(int); break;
00493 case 'L': case 'l': nRetSiz = sizeof(long); break;
00494 case 'P': case 'p': nRetSiz = sizeof(void *); break;
00495 case 'F': case 'f': nRetSiz = sizeof(float); break;
00496 case 'D': case 'd': nRetSiz = sizeof(double); break;
00497 case 'V': case 'v': nRetSiz = sizeof(__int64);break;
00498 default: return COMMAND_ERROR_ARGUMENT_RANGE;
00499 }
00500 cbFormat --;
00501 pszFormat++;
00502 if( cbFormat < 1 )return COMMAND_ERROR_ARGUMENT_TYPE;
00503 if( *pszFormat != ',' )return COMMAND_ERROR_ARGUMENT_RANGE;
00504 cbFormat --;
00505 pszFormat++;
00506 iParseState++;
00507 break;
00508 case 2:
00509 case 3:
00510 if( iParseState == 2 )pszS = szDll; else pszS = szFunction;
00511 i = 0;
00512 while( cbFormat && *pszFormat != ',' ){
00513 pszS[i] = *pszFormat;
00514 pszFormat ++;
00515 i++;
00516 cbFormat --;
00517 if( i >= MAX_PATH )return COMMAND_ERROR_ARGUMENT_RANGE;
00518 }
00519 if( cbFormat < 1 )return COMMAND_ERROR_ARGUMENT_RANGE;
00520 cbFormat--;
00521 pszFormat++;
00522 pszS[i] = (char)0;
00523 iParseState++;
00524 break;
00525 case 4:
00526
00527 if( NULL == (hDll = LibraryLoaded(szDll)) )return COMMAND_ERROR_MODULE_NOT_LOADED;
00528
00529
00530
00531 nArgs = cbFormat;
00532 Parm = besALLOC(nArgs*sizeof(DYNAPARM));
00533 if( NULL == Parm )return COMMAND_ERROR_MEMORY_LOW;
00534 i = 0;
00535 while( cbFormat ){
00536 if( i <= besARGNR-1 ){
00537 Argument = besARGUMENT(i+2);
00538 besDEREFERENCE(Argument);
00539 }else{
00540 Argument = NULL;
00541 }
00542 switch( *pszFormat ){
00543 case '1':
00544 Parm[i].nWidth = 1;
00545 Parm[i].dwFlags = 0;
00546 if( NULL == Argument ){
00547 Parm[i].dwArg = 0;
00548 }else
00549 switch( TYPE(Argument) ){
00550 case VTYPE_STRING:
00551 if( STRLEN(Argument) < 1 )
00552 Parm[i].dwArg = 0;
00553 else
00554 memcpy(&(Parm[i].dwArg),STRINGVALUE(Argument),1);
00555 break;
00556 case VTYPE_UNDEF:
00557 case VTYPE_LONG:
00558 case VTYPE_DOUBLE: Parm[i].dwArg = 0xFF & (unsigned long)besGETLONGVALUE(Argument); break;
00559 default: return COMMAND_ERROR_ARGUMENT_RANGE;
00560 }
00561 case '2':
00562 Parm[i].nWidth = 2;
00563 Parm[i].dwFlags = 0;
00564 if( NULL == Argument ){
00565 Parm[i].dwArg = 0;
00566 }else
00567 switch( TYPE(Argument) ){
00568 case VTYPE_STRING:
00569 if( STRLEN(Argument) < 2 )
00570 Parm[i].dwArg = 0;
00571 else
00572 memcpy(&(Parm[i].dwArg),STRINGVALUE(Argument),2);
00573 break;
00574 case VTYPE_UNDEF:
00575 case VTYPE_LONG:
00576 case VTYPE_DOUBLE: Parm[i].dwArg = 0xFFFF & (unsigned long)besGETLONGVALUE(Argument); break;
00577 default: return COMMAND_ERROR_ARGUMENT_RANGE;
00578 }
00579 case '4':
00580 Parm[i].nWidth = 4;
00581 Parm[i].dwFlags = 0;
00582 if( NULL == Argument ){
00583 Parm[i].dwArg = 0;
00584 }else
00585 switch( TYPE(Argument) ){
00586 case VTYPE_STRING:
00587 if( STRLEN(Argument) < 4 )
00588 Parm[i].dwArg = 0;
00589 else
00590 memcpy(&(Parm[i].dwArg),STRINGVALUE(Argument),4);
00591 break;
00592 case VTYPE_UNDEF:
00593 case VTYPE_LONG:
00594 case VTYPE_DOUBLE: Parm[i].dwArg = (long)besGETLONGVALUE(Argument); break;
00595 default: return COMMAND_ERROR_ARGUMENT_RANGE;
00596 }
00597 case '8':
00598 Argument = besCONVERT2STRING(Argument);
00599 if( STRLEN(Argument) < 8 )return COMMAND_ERROR_ARGUMENT_RANGE;
00600 Parm[i].nWidth = 8;
00601 Parm[i].dwFlags = DC_FLAG_ARGPTR;
00602 Parm[i].pArg = STRINGVALUE(Argument);
00603 break;
00604
00605 case 'c': case 'C':
00606 Parm[i].nWidth = 1;
00607 Parm[i].dwFlags = 0;
00608 if( NULL == Argument ){
00609 Parm[i].dwArg = 0;
00610 }else
00611 switch( TYPE(Argument) ){
00612 case VTYPE_STRING:
00613 if( STRLEN(Argument) < 1 )
00614 Parm[i].dwArg = 0;
00615 else
00616 Parm[i].dwArg = *STRINGVALUE(Argument);
00617 break;
00618 case VTYPE_UNDEF:
00619 case VTYPE_LONG:
00620 case VTYPE_DOUBLE: Parm[i].dwArg = (char)besGETLONGVALUE(Argument); break;
00621 default: return COMMAND_ERROR_ARGUMENT_RANGE;
00622 }
00623 case 's': case 'S':
00624 Parm[i].nWidth = 2;
00625 Parm[i].dwFlags = 0;
00626 Parm[i].dwArg = (short)besGETLONGVALUE(Argument); break;
00627 break;
00628
00629 case 'f': case 'F':
00630 Parm[i].nWidth = 4;
00631 Parm[i].dwFlags = 0;
00632 fTmp = (float)besGETDOUBLEVALUE(Argument);
00633 memcpy(&(Parm[i].dwArg) , &fTmp, sizeof(float)) ; break;
00634 break;
00635
00636 case 'h': case 'H':
00637 case 'p': case 'P':
00638 case 'l': case 'L':
00639 Parm[i].nWidth = 4;
00640 Parm[i].dwFlags = 0;
00641 Parm[i].dwArg = (DWORD)besGETLONGVALUE(Argument); break;
00642 break;
00643
00644 case 'z': case 'Z':
00645 Parm[i].nWidth = 4;
00646 Parm[i].dwFlags = 0;
00647 Argument = besCONVERT2STRING(Argument);
00648 Parm[i].pArg = STRINGVALUE(Argument); break;
00649 break;
00650
00651 case 'd': case 'D':
00652 Argument = besCONVERT2DOUBLE(Argument);
00653 Parm[i].nWidth = 8;
00654 Parm[i].dwFlags = DC_FLAG_ARGPTR;
00655 Parm[i].pArg = & (DOUBLEVALUE(Argument));
00656 break;
00657 default: return COMMAND_ERROR_ARGUMENT_RANGE;
00658 }
00659 i++;
00660 cbFormat--;
00661 pszFormat++;
00662 }
00663 break;
00664 }
00665 }
00666 lpFunction = (DWORD)SearchProcAddress(hDll,szFunction);
00667 if( lpFunction == 0 )return COMMAND_ERROR_MODULE_FUNCTION;
00668 RetVal = DynaCall(Flags,lpFunction,nArgs,Parm,NULL,0);
00669 switch( cRet ){
00670 case 'i':
00671 besALLOC_RETURN_LONG;
00672 LONGVALUE(besRETURNVALUE) = (long)RetVal.Int;
00673 break;
00674 case 'l':
00675 besALLOC_RETURN_LONG;
00676 LONGVALUE(besRETURNVALUE) = RetVal.Long;
00677 break;
00678 case 'p':
00679 besALLOC_RETURN_LONG;
00680 LONGVALUE(besRETURNVALUE) = (long)RetVal.Pointer;
00681 break;
00682 case 'f':
00683 besALLOC_RETURN_DOUBLE;
00684 DOUBLEVALUE(besRETURNVALUE) = (double)RetVal.Float;
00685 break;
00686 case 'd':
00687 besALLOC_RETURN_DOUBLE;
00688 DOUBLEVALUE(besRETURNVALUE) = (double)RetVal.Double;
00689 break;
00690 case 'v':
00691 besALLOC_RETURN_STRING(8);
00692 memcpy(STRINGVALUE(besRETURNVALUE),&(RetVal.int64),8);
00693 break;
00694 }
00695
00696 return COMMAND_ERROR_SUCCESS;
00697 besEND
00698
00699
00700 SLFST DYC_SLFST[] ={
00701
00702 { "versmodu" , versmodu },
00703 { "bootmodu" , bootmodu },
00704 { "finimodu" , finimodu },
00705 { "emsgmodu" , emsgmodu },
00706 { "dyc" , dyc },
00707 { NULL , NULL }
00708 };