00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <stdio.h>
00020 #include "../../basext.h"
00021
00022 #include <windows.h>
00023 #include <winbase.h>
00024 #include <winreg.h>
00025 #include <tlhelp32.h>
00026 #include <winsvc.h>
00027
00028 #include <stdio.h>
00029 #include <winnt.h>
00030 #include <winioctl.h>
00031 #include <string.h>
00032 #include <tchar.h>
00033
00053 besVERSION_NEGOTIATE
00054
00055 return (int)INTERFACE_VERSION;
00056
00057 besEND
00058
00059 besSUB_START
00060
00061 besEND
00062
00063 besSUB_FINISH
00064
00065 besEND
00066
00067 #define NT_ERROR_INVALID_KEY 0x00081001
00068 #define NT_ERROR_NOT_DELETED 0x00081002
00069 #define NT_ERROR_REGISTRY 0x00081003
00070 #define NT_ERROR_NOT_SET 0x00081004
00071
00072
00073
00074
00075 #define STRING_BUFFER_LENGTH 256
00076
00077 static int ChopHive(VARIABLE Argument,
00078 unsigned long *pLen,
00079 PHKEY phKey){
00080
00081 #define IFK(Y) if( STRLEN(Argument) >= (*pLen = strlen(#Y)) && ! memcmp(STRINGVALUE(Argument),#Y,*pLen) ){\
00082 *phKey = Y;\
00083 }else
00084
00085 IFK(HKEY_CLASSES_ROOT)
00086 IFK(HKEY_CURRENT_CONFIG)
00087 IFK(HKEY_CURRENT_USER)
00088 IFK(HKEY_LOCAL_MACHINE)
00089 IFK(HKEY_USERS)
00090 IFK(HKEY_PERFORMANCE_DATA)
00091 #undef IFK
00092 #define IFK(Y,X) if( STRLEN(Argument) >= (*pLen = strlen(#Y)) && ! memcmp(STRINGVALUE(Argument),#Y,*pLen) ){\
00093 *phKey = X;\
00094 }else
00095 IFK(HKCR,HKEY_CLASSES_ROOT)
00096 IFK(HKCC,HKEY_CURRENT_CONFIG)
00097 IFK(HKCU,HKEY_CURRENT_USER)
00098 IFK(HKLM,HKEY_LOCAL_MACHINE)
00099 IFK(HKU ,HKEY_USERS)
00100 IFK(HKPD,HKEY_PERFORMANCE_DATA)
00101
00102 { return 0; }
00103 return 1;
00104 }
00105
00145 besFUNCTION(regread)
00146 VARIABLE Argument;
00147 HKEY hKey,hRes;
00148 unsigned long sLen;
00149 char *s,*r,*pszSubKey;
00150 LONG Ret;
00151 char *pszData,szDummy;
00152 DWORD dwType;
00153 DWORD cbData;
00154 unsigned char swap;
00155
00156 besRETURNVALUE = NULL;
00157 if( besARGNR < 1 )return EX_ERROR_TOO_FEW_ARGUMENTS;
00158
00159 Argument = besARGUMENT(1);
00160 besDEREFERENCE(Argument);
00161 Argument = besCONVERT2STRING(Argument);
00162 if( ! ChopHive(Argument,&sLen,&hKey) )
00163 return NT_ERROR_INVALID_KEY;
00164
00165 besCONVERT2ZCHAR(Argument,s);
00166 pszSubKey = s + sLen + 1;
00167 sLen = STRLEN(Argument) - sLen;
00168 r = s + STRLEN(Argument);
00169 while( sLen && *r != '\\' ){
00170 sLen --;
00171 r--;
00172 }
00173
00174 if( sLen ){
00175 *r = (char)0;
00176 r++;
00177 }else{
00178 besFREE(s);
00179 return NT_ERROR_INVALID_KEY;
00180 }
00181
00182 Ret = RegOpenKeyEx(hKey,pszSubKey,0,KEY_READ,&hRes);
00183
00184 if( Ret != ERROR_SUCCESS ){
00185 besFREE(s);
00186 return COMMAND_ERROR_SUCCESS;
00187 }
00188
00189 cbData = 0;
00190 Ret = RegQueryValueEx(hRes,r,NULL,&dwType,&szDummy,&cbData);
00191 if( Ret == ERROR_MORE_DATA ){
00192 pszData = besALLOC(cbData);
00193 if( pszData == NULL ){
00194 besFREE(s);
00195 return COMMAND_ERROR_MEMORY_LOW;
00196 }
00197 }else{
00198 pszData = besALLOC(cbData=1);
00199 if( pszData == NULL ){
00200 besFREE(s);
00201 return COMMAND_ERROR_MEMORY_LOW;
00202 }
00203 }
00204 Ret = RegQueryValueEx(hRes,r,NULL,&dwType,pszData,&cbData);
00205 RegCloseKey(hRes);
00206 besFREE(s);
00207
00208 if( Ret != ERROR_SUCCESS ){
00209 besFREE(pszData);
00210 return COMMAND_ERROR_SUCCESS;
00211 }
00212
00213 switch( dwType ){
00214 case REG_DWORD_BIG_ENDIAN:
00215 if( cbData < 4 ){
00216 besFREE(pszData);
00217 return NT_ERROR_REGISTRY;
00218 }
00219 swap = pszData[0]; pszData[0] = pszData[3]; pszData[3] = swap;
00220 swap = pszData[1]; pszData[1] = pszData[2]; pszData[2] = swap;
00221
00222 case REG_DWORD:
00223 besALLOC_RETURN_LONG;
00224 memcpy(& LONGVALUE(besRETURNVALUE),pszData,sizeof(DWORD));
00225 besFREE(pszData);
00226 return COMMAND_ERROR_SUCCESS;
00227 case REG_BINARY:
00228 case REG_MULTI_SZ:
00229 case REG_SZ:
00230 besALLOC_RETURN_STRING(cbData);
00231 memcpy(STRINGVALUE(besRETURNVALUE),pszData,cbData);
00232 besFREE(pszData);
00233 return COMMAND_ERROR_SUCCESS;
00234
00235 case REG_LINK:
00236 case REG_NONE:
00237 case REG_RESOURCE_LIST:
00238 besFREE(pszData);
00239 return COMMAND_ERROR_SUCCESS;
00240 }
00241 besFREE(pszData);
00242
00243 besEND
00244
00258 besFUNCTION(regdel)
00259 VARIABLE Argument;
00260 HKEY hKey,hRes;
00261 unsigned long sLen;
00262 char *s,*r,*pszSubKey;
00263 LONG Ret;
00264
00265 besRETURNVALUE = NULL;
00266 if( besARGNR < 1 )return EX_ERROR_TOO_FEW_ARGUMENTS;
00267
00268 Argument = besARGUMENT(1);
00269 besDEREFERENCE(Argument);
00270 Argument = besCONVERT2STRING(Argument);
00271 if( ! ChopHive(Argument,&sLen,&hKey) )
00272 return NT_ERROR_INVALID_KEY;
00273
00274 besCONVERT2ZCHAR(Argument,s);
00275 pszSubKey = s + sLen + 1;
00276
00277
00278 Ret = RegDeleteKey(hKey,pszSubKey);
00279 if( Ret == ERROR_SUCCESS ){
00280 besFREE(s);
00281 return COMMAND_ERROR_SUCCESS;
00282 }
00283
00284
00285 sLen = STRLEN(Argument) - sLen;
00286 r = s + STRLEN(Argument);
00287 while( sLen && *r != '\\' ){
00288 sLen --;
00289 r--;
00290 }
00291
00292 if( sLen ){
00293 *r = (char)0;
00294 r++;
00295 }else{
00296 besFREE(s);
00297 return NT_ERROR_INVALID_KEY;
00298 }
00299
00300 Ret = RegOpenKeyEx(hKey,pszSubKey,0,KEY_WRITE,&hRes);
00301 if( Ret != ERROR_SUCCESS ){
00302 besFREE(s);
00303 return NT_ERROR_NOT_DELETED;
00304 }
00305 Ret = RegDeleteValue(hRes,r);
00306 besFREE(s);
00307 RegCloseKey(hRes);
00308 if( Ret != ERROR_SUCCESS ){
00309 return NT_ERROR_NOT_DELETED;
00310 }
00311 return COMMAND_ERROR_SUCCESS;
00312
00313 besEND
00314
00327 besFUNCTION(regwrite)
00328 VARIABLE Argument;
00329 HKEY hKey,hRes;
00330 unsigned long sLen;
00331 char *s,*r,*pszSubKey;
00332 LONG Ret;
00333
00334 besRETURNVALUE = NULL;
00335 if( besARGNR < 2 )return EX_ERROR_TOO_FEW_ARGUMENTS;
00336
00337 Argument = besARGUMENT(1);
00338 besDEREFERENCE(Argument);
00339 Argument = besCONVERT2STRING(Argument);
00340 if( ! ChopHive(Argument,&sLen,&hKey) )
00341 return COMMAND_ERROR_SUCCESS;
00342
00343 besCONVERT2ZCHAR(Argument,s);
00344 pszSubKey = s + sLen + 1;
00345 sLen = STRLEN(Argument) - sLen;
00346 r = s + STRLEN(Argument);
00347 while( sLen && *r != '\\' ){
00348 sLen --;
00349 r--;
00350 }
00351
00352 if( sLen ){
00353 *r = (char)0;
00354 r++;
00355 }else{
00356 besFREE(s);
00357 return COMMAND_ERROR_SUCCESS;
00358 }
00359
00360 Ret = RegOpenKeyEx(hKey,pszSubKey,0,KEY_WRITE,&hRes);
00361 if( Ret != ERROR_SUCCESS ){
00362 besFREE(s);
00363 return NT_ERROR_INVALID_KEY;
00364 }
00365
00366
00367 Argument = besARGUMENT(2);
00368 besDEREFERENCE(Argument);
00369 switch( TYPE(Argument) ){
00370 case VTYPE_DOUBLE:
00371 Argument = besCONVERT2LONG(Argument);
00372 case VTYPE_LONG:
00373 Ret = RegSetValueEx(hRes,r,0,REG_DWORD, (char *)& LONGVALUE(Argument),sizeof(long));
00374 break;
00375 case VTYPE_STRING:
00376 Ret = RegSetValueEx(hRes,r,0,REG_BINARY,STRINGVALUE(Argument),STRLEN(Argument));
00377 }
00378 besFREE(s);
00379 if( Ret == ERROR_SUCCESS )return COMMAND_ERROR_SUCCESS;
00380 return NT_ERROR_NOT_SET;
00381 besEND
00382
00490 besFUNCTION(msgbox)
00491 char *pszTitle,*pszCaption;
00492 char *pszButtons,*pszStyle;
00493 long lDefault;
00494 int iError;
00495 int iMsgResult;
00496 UINT uType;
00497
00498 iError = besGETARGS "zz[zzi]", &pszTitle, &pszCaption, &pszButtons , &pszStyle , &lDefault besGETARGE;
00499
00500 if( iError )return iError;
00501
00502 uType = MB_OK;
00503
00504 if( ! strcmp(pszButtons,"ARI") )uType = MB_ABORTRETRYIGNORE;
00505 else if( ! stricmp(pszButtons,"OK") )uType = MB_OK;
00506 else if( ! stricmp(pszButtons,"O") )uType = MB_OK;
00507 else if( ! stricmp(pszButtons,"OC") )uType = MB_OKCANCEL;
00508 else if( ! stricmp(pszButtons,"RC") )uType = MB_RETRYCANCEL;
00509 else if( ! stricmp(pszButtons,"YN") )uType = MB_YESNO;
00510 else if( ! stricmp(pszButtons,"YNC"))uType = MB_YESNOCANCEL;
00511 else
00512
00513 if( ! stricmp(pszButtons,"AbortRetryIgnore") )uType = MB_ABORTRETRYIGNORE;
00514 else if( ! stricmp(pszButtons,"Ok") )uType = MB_OK;
00515 else if( ! stricmp(pszButtons,"OkCancel") )uType = MB_OKCANCEL;
00516 else if( ! stricmp(pszButtons,"RetryCancel") )uType = MB_RETRYCANCEL;
00517 else if( ! stricmp(pszButtons,"YesNo") )uType = MB_YESNO;
00518 else if( ! stricmp(pszButtons,"YesNoCancel") )uType = MB_YESNOCANCEL;
00519
00520 if( ! stricmp(pszStyle,"Exclamation") )uType |= MB_ICONEXCLAMATION;
00521 else if( ! stricmp(pszStyle,"Ex") )uType |= MB_ICONEXCLAMATION;
00522 else if( ! stricmp(pszStyle,"Warning") )uType |= MB_ICONWARNING;
00523 else if( ! stricmp(pszStyle,"W") )uType |= MB_ICONWARNING;
00524 else if( ! stricmp(pszStyle,"Information") )uType |= MB_ICONINFORMATION;
00525 else if( ! stricmp(pszStyle,"Info") )uType |= MB_ICONINFORMATION;
00526 else if( ! stricmp(pszStyle,"I") )uType |= MB_ICONINFORMATION;
00527 else if( ! stricmp(pszStyle,"Asterix") )uType |= MB_ICONASTERISK;
00528 else if( ! stricmp(pszStyle,"A") )uType |= MB_ICONASTERISK;
00529 else if( ! stricmp(pszStyle,"*") )uType |= MB_ICONASTERISK;
00530 else if( ! stricmp(pszStyle,"Question") )uType |= MB_ICONQUESTION;
00531 else if( ! stricmp(pszStyle,"Q") )uType |= MB_ICONQUESTION;
00532 else if( ! stricmp(pszStyle,"?") )uType |= MB_ICONQUESTION;
00533 else if( ! stricmp(pszStyle,"Stop") )uType |= MB_ICONSTOP;
00534 else if( ! stricmp(pszStyle,"S") )uType |= MB_ICONSTOP;
00535 else if( ! stricmp(pszStyle,"Error") )uType |= MB_ICONERROR;
00536 else if( ! stricmp(pszStyle,"E") )uType |= MB_ICONERROR;
00537 else if( ! stricmp(pszStyle,"Hand") )uType |= MB_ICONHAND;
00538 else if( ! stricmp(pszStyle,"H") )uType |= MB_ICONHAND;
00539
00540 switch( lDefault ){
00541 case 1: uType |= MB_DEFBUTTON1; break;
00542 case 2: uType |= MB_DEFBUTTON2; break;
00543 case 3: uType |= MB_DEFBUTTON3; break;
00544 case 4: uType |= MB_DEFBUTTON4; break;
00545 }
00546
00547 iMsgResult = MessageBoxEx(NULL,pszTitle,pszCaption,uType,
00548 MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US));
00549
00550 besFREE(pszTitle);
00551 besFREE(pszCaption);
00552 besFREE(pszButtons);
00553 besFREE(pszStyle);
00554
00555 besALLOC_RETURN_STRING(1);
00556 switch( iMsgResult ){
00557 case IDABORT : *STRINGVALUE(besRETURNVALUE) = 'A'; break;
00558 case IDCANCEL : *STRINGVALUE(besRETURNVALUE) = 'C'; break;
00559 case IDIGNORE : *STRINGVALUE(besRETURNVALUE) = 'I'; break;
00560 case IDNO : *STRINGVALUE(besRETURNVALUE) = 'N'; break;
00561 case IDOK : *STRINGVALUE(besRETURNVALUE) = 'O'; break;
00562 case IDRETRY : *STRINGVALUE(besRETURNVALUE) = 'R'; break;
00563 case IDYES : *STRINGVALUE(besRETURNVALUE) = 'Y'; break;
00564 default : *STRINGVALUE(besRETURNVALUE) = ' '; break;
00565 }
00566
00567 besEND
00568
00603 besFUNCTION(shutdown_nt)
00604 HANDLE hToken;
00605 TOKEN_PRIVILEGES tkp;
00606 BOOL fResult;
00607 int iError;
00608 char *pszComputerName,*pszMessage;
00609 long lTimeout,lBruteForce,lReboot;
00610
00611 iError = besGETARGS "[zz]iii", &pszComputerName, &pszMessage, &lTimeout, &lBruteForce, &lReboot besGETARGE;
00612
00613 if(!OpenProcessToken(GetCurrentProcess(),
00614 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
00615 return COMMAND_ERROR_EXTENSION_SPECIFIC;
00616
00617 LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid);
00618
00619 tkp.PrivilegeCount = 1;
00620 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
00621
00622 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);
00623
00624 if(GetLastError() != ERROR_SUCCESS)
00625 return COMMAND_ERROR_EXTENSION_SPECIFIC;
00626
00627 fResult = InitiateSystemShutdown(pszComputerName,
00628 pszMessage,
00629 (DWORD)lTimeout,
00630 (BOOL)(lBruteForce != 0),
00631 (BOOL)(lReboot != 0));
00632 if( pszComputerName )besFREE(pszComputerName);
00633 if( pszMessage )besFREE(pszMessage);
00634
00635 if(!fResult)
00636 return COMMAND_ERROR_EXTENSION_SPECIFIC;
00637
00638 tkp.Privileges[0].Attributes = 0;
00639 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);
00640
00641 if(GetLastError() != ERROR_SUCCESS)
00642 return COMMAND_ERROR_EXTENSION_SPECIFIC;
00643 besEND
00674 besFUNCTION(proclist)
00675 HANDLE th;
00676 unsigned long lProcCount;
00677 PROCESSENTRY32 pe;
00678 VARIABLE Argument;
00679 LEFTVALUE Lval;
00680 VARIABLE vPROC;
00681 int i;
00682 unsigned long __refcount_;
00683
00684 Argument = besARGUMENT(1);
00685 besLEFTVALUE(Argument,Lval);
00686
00687 if( Lval == NULL )return COMMAND_ERROR_EXTENSION_SPECIFIC;
00688
00689 th = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
00690 if( th == INVALID_HANDLE_VALUE )return COMMAND_ERROR_EXTENSION_SPECIFIC;
00691
00692
00693 pe.dwSize = sizeof(PROCESSENTRY32);
00694 lProcCount = 0;
00695 if( Process32First(th,&pe) ){
00696 lProcCount++;
00697 while( Process32Next(th,&pe) ){
00698 lProcCount++;
00699 pe.dwSize = sizeof(PROCESSENTRY32);
00700 }
00701 }
00702
00703 if( Lval && *Lval ){ besRELEASE(*Lval); }
00704 if( lProcCount == 0 )return COMMAND_ERROR_SUCCESS;
00705
00706 *Lval = besNEWARRAY(0,lProcCount-1);
00707 if( *Lval == NULL )return COMMAND_ERROR_MEMORY_LOW;
00708
00709 lProcCount = 0;
00710 Process32First(th,&pe);
00711 do{
00712 vPROC = (*Lval)->Value.aValue[lProcCount] = besNEWARRAY(0,8);
00713 if( vPROC == NULL )return COMMAND_ERROR_MEMORY_LOW;
00714 for( i=0 ; i < 8 ; i++ ){
00715 vPROC->Value.aValue[i] = besNEWLONG;
00716 if( vPROC->Value.aValue[i] == NULL )return COMMAND_ERROR_MEMORY_LOW;
00717 }
00718 LONGVALUE(vPROC->Value.aValue[0]) = pe.cntUsage;
00719 LONGVALUE(vPROC->Value.aValue[1]) = pe.th32ProcessID;
00720 LONGVALUE(vPROC->Value.aValue[2]) = pe.th32DefaultHeapID;
00721 LONGVALUE(vPROC->Value.aValue[3]) = pe.th32ModuleID;
00722 LONGVALUE(vPROC->Value.aValue[4]) = pe.cntThreads;
00723 LONGVALUE(vPROC->Value.aValue[5]) = pe.th32ParentProcessID;
00724 LONGVALUE(vPROC->Value.aValue[6]) = pe.pcPriClassBase;
00725 LONGVALUE(vPROC->Value.aValue[7]) = pe.dwFlags;
00726 vPROC->Value.aValue[8] = besNEWSTRING(strlen(pe.szExeFile));
00727 if( vPROC->Value.aValue[8] == NULL )return COMMAND_ERROR_MEMORY_LOW;
00728 memcpy(STRINGVALUE(vPROC->Value.aValue[8]),pe.szExeFile,STRLEN(vPROC->Value.aValue[8]));
00729
00730 lProcCount++;
00731 pe.dwSize = sizeof(PROCESSENTRY32);
00732 }while( Process32Next(th,&pe) );
00733
00734 CloseHandle(th);
00735 besEND
00736
00755 besFUNCTION(nt_startservice)
00756 char *pszServiceName;
00757 int iError;
00758 SC_HANDLE hManager,hService;
00759 SERVICE_STATUS SSTAT;
00760
00761 iError = besGETARGS "z", &pszServiceName besGETARGE;
00762 if( iError )return iError;
00763 hManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
00764 if( hManager == NULL )return COMMAND_ERROR_EXTENSION_SPECIFIC;
00765 hService = OpenService(hManager,pszServiceName,SERVICE_START|SERVICE_QUERY_STATUS);
00766 besFREE(pszServiceName);
00767 if( hService == NULL ){
00768 iError = GetLastError();
00769 return COMMAND_ERROR_EXTENSION_SPECIFIC;
00770 }
00771 memset(&SSTAT,0,sizeof(SSTAT));
00772 if( ! QueryServiceStatus(hService,&SSTAT) ){
00773 iError = GetLastError();
00774 return COMMAND_ERROR_EXTENSION_SPECIFIC;
00775 }
00776
00777
00778 if( SSTAT.dwCurrentState == SERVICE_START_PENDING ||
00779 SSTAT.dwCurrentState == SERVICE_RUNNING ||
00780 SSTAT.dwCurrentState == SERVICE_CONTINUE_PENDING )return COMMAND_ERROR_SUCCESS;
00781 iError = StartService(hService,0,NULL);
00782 CloseServiceHandle(hService);
00783 CloseServiceHandle(hManager);
00784 if( iError == 0 )iError = GetLastError(); else iError = 0;
00785 if( iError == 0 || iError == ERROR_SERVICE_ALREADY_RUNNING )return COMMAND_ERROR_SUCCESS;
00786 return COMMAND_ERROR_EXTENSION_SPECIFIC;
00787 besEND
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797 static int ControlNtService(pSupportTable pSt,
00798 void **ppModuleInternal,
00799 pFixSizeMemoryObject pParameters,
00800 DWORD dwControl
00801 ){
00802 char *pszServiceName;
00803 int iError;
00804 SC_HANDLE hManager,hService;
00805 SERVICE_STATUS SSTAT;
00806
00807 iError = besGETARGS "z", &pszServiceName besGETARGE;
00808 if( iError )return iError;
00809 hManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
00810 if( hManager == NULL )return COMMAND_ERROR_EXTENSION_SPECIFIC;
00811 hService = OpenService(hManager,pszServiceName,SERVICE_ALL_ACCESS);
00812 besFREE(pszServiceName);
00813 if( hService == NULL )return COMMAND_ERROR_EXTENSION_SPECIFIC;
00814 memset(&SSTAT,0,sizeof(SSTAT));
00815 iError = ControlService(hService,dwControl,&SSTAT);
00816
00817 CloseServiceHandle(hService);
00818 CloseServiceHandle(hManager);
00819 if( iError == 0 )iError = GetLastError(); else iError = 0;
00820 if( iError )return COMMAND_ERROR_EXTENSION_SPECIFIC;
00821 return COMMAND_ERROR_SUCCESS;
00822 }
00823
00824 #define CONTROL_NT_SERVICE(X) ControlNtService(pSt,ppModuleInternal,pParameters,X)
00825
00844 besFUNCTION(nt_stopservice)
00845 return CONTROL_NT_SERVICE(SERVICE_CONTROL_STOP);
00846 besEND
00847
00865 besFUNCTION(nt_pauseservice)
00866 return CONTROL_NT_SERVICE(SERVICE_CONTROL_PAUSE);
00867 besEND
00868
00886 besFUNCTION(nt_continueservice)
00887 return CONTROL_NT_SERVICE(SERVICE_CONTROL_CONTINUE);
00888 besEND
00889
00918 static int lnw(char *,char *);
00919 static int CreateJunction( char *LinkDirectory, char *LinkTarget );
00920
00921 besFUNCTION(nt_hardlink)
00922 char *pszFileName,*pszNewName;
00923 int iError;
00924
00925 iError = besGETARGS "zz", &pszFileName,&pszNewName besGETARGE;
00926 if( iError )return iError;
00927
00928 iError = (GetFileAttributes(pszFileName) & FILE_ATTRIBUTE_DIRECTORY) ?
00929 CreateJunction(pszNewName,pszFileName)
00930 :
00931 lnw(pszFileName,pszNewName);
00932
00933 if( iError )return COMMAND_ERROR_EXTENSION_SPECIFIC;
00934 return COMMAND_ERROR_SUCCESS;
00935 besEND
00936
00937
00938 void enableprivs(){
00939 HANDLE hToken;
00940 byte buf[sizeof(TOKEN_PRIVILEGES) * 2];
00941 TOKEN_PRIVILEGES *tkp = ( (TOKEN_PRIVILEGES *) buf );
00942
00943 if ( ! OpenProcessToken( GetCurrentProcess(),
00944 TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) )
00945 return;
00946
00947
00948
00949 if ( !LookupPrivilegeValue( NULL, SE_BACKUP_NAME, &tkp->Privileges[0].Luid ) )
00950 return;
00951
00952 if ( !LookupPrivilegeValue( NULL, SE_RESTORE_NAME, &tkp->Privileges[1].Luid ) )
00953 return;
00954
00955 tkp->PrivilegeCount = 2;
00956 tkp->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
00957 tkp->Privileges[1].Attributes = SE_PRIVILEGE_ENABLED;
00958
00959 AdjustTokenPrivileges( hToken, FALSE, tkp, sizeof( *tkp ),
00960 NULL, NULL );
00961 }
00962
00963
00964
00965 static int lnw(char *pszSource, char *pszDestination){
00966 HANDLE fh;
00967 static char buf1[MAX_PATH];
00968 static wchar_t buf2[MAX_PATH * 2];
00969 char *p;
00970 void *ctx = NULL;
00971 WIN32_STREAM_ID wsi;
00972 DWORD numwritten;
00973 BOOL bSourceIsReadOnly;
00974 DWORD attrib;
00975
00976 enableprivs();
00977 attrib = GetFileAttributes(pszSource);
00978 if( INVALID_FILE_ATTRIBUTES == attrib ){
00979 return 1;
00980 }
00981
00982 bSourceIsReadOnly = FALSE;
00983 if( attrib & FILE_ATTRIBUTE_READONLY ){
00984 bSourceIsReadOnly = TRUE;
00985
00986 SetFileAttributes(pszSource,attrib & ~FILE_ATTRIBUTE_READONLY);
00987 }
00988 if( attrib & FILE_ATTRIBUTE_DIRECTORY ){
00989 return 1;
00990 }
00991
00992 fh = CreateFile( pszSource, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
00993 FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_POSIX_SEMANTICS, NULL );
00994 if ( fh == INVALID_HANDLE_VALUE || fh == NULL ){
00995 if( bSourceIsReadOnly ){
00996 SetFileAttributes(pszSource,attrib);
00997 }
00998 return 1;
00999 }
01000
01001 GetFullPathName( pszDestination, MAX_PATH, buf1, &p );
01002
01003 wsi.dwStreamId = BACKUP_LINK;
01004 wsi.dwStreamAttributes = 0;
01005 wsi.dwStreamNameSize = 0;
01006 wsi.Size.QuadPart = strlen( buf1 ) * 2 + 2;
01007 MultiByteToWideChar( CP_ACP, 0, buf1, (int)strlen( buf1 ) + 1, buf2, MAX_PATH );
01008
01009 if( ! BackupWrite( fh, (byte *) &wsi, 20, &numwritten, FALSE, FALSE, &ctx ) ){
01010 return 1;
01011 }
01012 if( numwritten != 20 ){
01013 return 1;
01014 }
01015
01016 if( ! BackupWrite( fh, (byte *) buf2, wsi.Size.LowPart, &numwritten, FALSE, FALSE, &ctx ) ){
01017 return 1;
01018 }
01019 if( numwritten != wsi.Size.LowPart ){
01020 return 1;
01021 }
01022
01023
01024 if( ! BackupWrite( fh, (byte *) &buf1[0], 0, &numwritten, TRUE, FALSE, &ctx ) ){
01025 return 1;
01026 }
01027
01028 CloseHandle( fh );
01029 if( bSourceIsReadOnly ){
01030 SetFileAttributes(pszSource,attrib);
01031 }
01032 return 0;
01033 }
01034
01035 typedef struct _REPARSE_DATA_BUFFER {
01036 DWORD ReparseTag;
01037 WORD ReparseDataLength;
01038 WORD Reserved;
01039 union {
01040 struct {
01041 WORD SubstituteNameOffset;
01042 WORD SubstituteNameLength;
01043 WORD PrintNameOffset;
01044 WORD PrintNameLength;
01045 WCHAR PathBuffer[1024];
01046 } SymbolicLinkReparseBuffer;
01047 struct {
01048 WORD SubstituteNameOffset;
01049 WORD SubstituteNameLength;
01050 WORD PrintNameOffset;
01051 WORD PrintNameLength;
01052 WCHAR PathBuffer[1024];
01053 } MountPointReparseBuffer;
01054 struct {
01055 BYTE DataBuffer[1024];
01056 } GenericReparseBuffer;
01057 };
01058 } REPARSE_DATA_BUFFER;
01059
01060 #define REPARSE_MOUNTPOINT_HEADER_SIZE 8
01061
01062 #ifndef FSCTL_SET_REPARSE_POINT
01063 # define FSCTL_SET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
01064 # define FSCTL_GET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS)
01065 # define FSCTL_DELETE_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 43, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
01066 #endif
01067
01068 void PrintWin32Error( DWORD x){}
01069
01070 #define toUnicode(FROM,TO) \
01071 MultiByteToWideChar(CP_ACP, \
01072 0, \
01073 (char *)FROM, \
01074 strlen((char *)FROM)+1,\
01075 TO, \
01076 sizeof(TO))
01077
01078 static int CreateJunction(char *LinkDirectory, char *LinkTarget){
01079 REPARSE_DATA_BUFFER reparseBuffer;
01080 char directoryFileName[MAX_PATH];
01081 char targetFileName[MAX_PATH];
01082 char targetNativeFileName[MAX_PATH];
01083 WCHAR wtargetNativeFileName[MAX_PATH];
01084 PTCHAR filePart;
01085 HANDLE hFile;
01086 DWORD returnedLength;
01087 size_t slen;
01088 REPARSE_DATA_BUFFER *reparseInfo = (REPARSE_DATA_BUFFER *) &reparseBuffer;
01089
01090
01091 if( !GetFullPathName( LinkTarget, MAX_PATH, targetFileName, &filePart ) ){
01092 return 1;
01093 }
01094
01095
01096 if( !GetFullPathName( LinkDirectory, MAX_PATH, directoryFileName, &filePart) ){
01097 return 1;
01098 }
01099
01100
01101 sprintf( targetNativeFileName, "\\??\\%s" , targetFileName );
01102 slen = strlen(targetNativeFileName);
01103 if ( (targetNativeFileName[slen-1] == _T('\\')) &&
01104 (targetNativeFileName[slen-2] != _T(':'))) {
01105 targetNativeFileName[slen-1] = 0;
01106 }
01107
01108
01109 CreateDirectory( LinkDirectory, NULL );
01110 hFile = CreateFile( LinkDirectory, GENERIC_WRITE, 0,
01111 NULL, OPEN_EXISTING,
01112 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL );
01113 if( hFile == INVALID_HANDLE_VALUE ) {
01114 return 1;
01115 }
01116
01117 toUnicode(targetNativeFileName,wtargetNativeFileName);
01118
01119
01120 memset( reparseInfo, 0, sizeof( REPARSE_DATA_BUFFER ));
01121 reparseInfo->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
01122 reparseInfo->SymbolicLinkReparseBuffer.SubstituteNameLength =
01123 wcslen(wtargetNativeFileName) * sizeof(WCHAR);
01124 reparseInfo->Reserved = 0;
01125 reparseInfo->SymbolicLinkReparseBuffer.PrintNameLength = 0;
01126 reparseInfo->SymbolicLinkReparseBuffer.PrintNameOffset =
01127 reparseInfo->SymbolicLinkReparseBuffer.SubstituteNameLength
01128 + sizeof(WCHAR);
01129 memcpy(reparseInfo->SymbolicLinkReparseBuffer.PathBuffer, wtargetNativeFileName,
01130 sizeof(WCHAR)
01131 + reparseInfo->SymbolicLinkReparseBuffer.SubstituteNameLength);
01132 reparseInfo->ReparseDataLength =
01133 reparseInfo->SymbolicLinkReparseBuffer.SubstituteNameLength + 12;
01134
01135
01136 if( !DeviceIoControl(hFile, FSCTL_SET_REPARSE_POINT, reparseInfo,
01137 reparseInfo->ReparseDataLength
01138 + REPARSE_MOUNTPOINT_HEADER_SIZE,
01139 NULL, 0, &returnedLength, NULL)) {
01140
01141 CloseHandle( hFile );
01142 RemoveDirectory( LinkDirectory );
01143 return 1;
01144 }
01145 return 0;
01146 }
01147
01148