29     { 
UPLOAD_SERVICE_JOTTI, L
"virusscan.jotti.org", INTERNET_DEFAULT_HTTP_PORT, 0, L
"/processupload.php", L
"scanfile" },
 
   30     { 
UPLOAD_SERVICE_CIMA, L
"camas.comodo.com", INTERNET_DEFAULT_HTTP_PORT, 0, L
"/cgi-bin/submit", L
"file" }
 
   33 static HFONT InitializeFont(
 
   38     NONCLIENTMETRICS metrics = { 
sizeof(NONCLIENTMETRICS) };
 
   40     if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &metrics, 0))
 
   42         metrics.lfMessageFont.lfHeight = -15;
 
   46         fontHandle = CreateFontIndirect(&metrics.lfMessageFont);
 
   52         GetObject((HFONT)GetStockObject(DEFAULT_GUI_FONT), 
sizeof(LOGFONT), &font);
 
   56         fontHandle = CreateFontIndirect(&font);
 
   59     SendMessage(hwnd, WM_SETFONT, (WPARAM)fontHandle, 
TRUE);
 
   64 static BOOL ReadRequestString(
 
   65     _In_ HINTERNET Handle,
 
   66     _Out_ _Deref_post_z_cap_(*DataLength) PSTR *Data,
 
   67     _Out_ ULONG *DataLength
 
   72     ULONG allocatedLength;
 
   76     allocatedLength = 
sizeof(buffer);
 
   77     data = (PSTR)PhAllocate(allocatedLength);
 
   83     while (WinHttpReadData(Handle, buffer, 
PAGE_SIZE, &returnLength))
 
   85         if (returnLength == 0)
 
   88         if (allocatedLength < dataLength + returnLength)
 
   91             data = (PSTR)PhReAllocate(data, allocatedLength);
 
   95         memcpy(data + dataLength, buffer, returnLength);
 
   99         dataLength += returnLength;
 
  102     if (allocatedLength < dataLength + 1)
 
  105         data = (PSTR)PhReAllocate(data, allocatedLength);
 
  109     data[dataLength] = 0;
 
  111     *DataLength = dataLength;
 
  117 static VOID RaiseUploadError(
 
  123     if (Context->DialogHandle)
 
  126             Context->DialogHandle,
 
  140     for (i = 0; i < _countof(UploadServiceInfo); i++)
 
  142         if (UploadServiceInfo[i].Id == Id)
 
  143             return &UploadServiceInfo[i];
 
  149 static BOOLEAN PerformSubRequest(
 
  152     _In_ PWSTR ObjectName,
 
  153     _Out_ _Deref_post_z_cap_(*DataLength) PSTR *Data,
 
  154     _Out_opt_ PULONG DataLength
 
  157     BOOLEAN result = 
FALSE;
 
  158     HINTERNET connectHandle = NULL;
 
  159     HINTERNET requestHandle = NULL;
 
  164         if (!(connectHandle = WinHttpConnect(
 
  167             INTERNET_DEFAULT_HTTP_PORT,
 
  171             RaiseUploadError(Context, L
"Unable to connect to the service", GetLastError());
 
  176         if (!(requestHandle = WinHttpOpenRequest(
 
  182             WINHTTP_DEFAULT_ACCEPT_TYPES,
 
  186             RaiseUploadError(Context, L
"Unable to create the request", GetLastError());
 
  191         if (!WinHttpSendRequest(requestHandle, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0))
 
  193             RaiseUploadError(Context, L
"Unable to send the request", GetLastError());
 
  198         if (WinHttpReceiveResponse(requestHandle, NULL))
 
  202             ULONG allocatedLength;
 
  206             allocatedLength = 
sizeof(buffer);
 
  207             data = PhAllocate(allocatedLength);
 
  210             while (WinHttpReadData(requestHandle, buffer, 
PAGE_SIZE, &returnLength))
 
  212                 if (returnLength == 0)
 
  215                 if (allocatedLength < dataLength + returnLength)
 
  217                     allocatedLength *= 2;
 
  218                     data = PhReAllocate(data, allocatedLength);
 
  221                 memcpy(data + dataLength, buffer, returnLength);
 
  222                 dataLength += returnLength;
 
  225             if (allocatedLength < dataLength + 1)
 
  228                 data = PhReAllocate(data, allocatedLength);
 
  232             data[dataLength] = 0;
 
  238                 *DataLength = dataLength;
 
  243             RaiseUploadError(Context, L
"Unable to receive the response", GetLastError());
 
  252             WinHttpCloseHandle(requestHandle);
 
  254             WinHttpCloseHandle(connectHandle);
 
  260 static NTSTATUS HashFileAndResetPosition(
 
  261     _In_ HANDLE FileHandle,
 
  262     _In_ PLARGE_INTEGER FileSize,
 
  263     _In_ ULONG Algorithm,
 
  271     ULONG64 bytesRemaining;
 
  275     bytesRemaining = FileSize->QuadPart;
 
  287     while (bytesRemaining)
 
  317     if (status == STATUS_END_OF_FILE)
 
  318         status = STATUS_SUCCESS;
 
  345 static NTSTATUS UploadFileThreadStart(
 
  349     NTSTATUS status = STATUS_SUCCESS;
 
  350     ULONG httpStatus = 0;
 
  351     ULONG httpStatusLength = 
sizeof(ULONG);
 
  352     ULONG httpPostSeed = 0;
 
  353     ULONG totalUploadLength = 0;
 
  354     ULONG totalUploadedLength = 0;
 
  355     ULONG totalPostHeaderWritten = 0;
 
  356     ULONG totalPostFooterWritten = 0;
 
  357     ULONG totalWriteLength = 0;
 
  358     LARGE_INTEGER timeNow;
 
  359     LARGE_INTEGER timeStart;
 
  360     ULONG64 timeTicks = 0;
 
  361     ULONG64 timeBitsPerSecond = 0;
 
  363     HANDLE fileHandle = INVALID_HANDLE_VALUE;
 
  366     HINTERNET connectHandle = NULL;
 
  367     HINTERNET requestHandle = NULL;
 
  379     serviceInfo = GetUploadServiceInfo(context->
Service);
 
  389             FILE_SHARE_READ | FILE_SHARE_DELETE,
 
  401         if (!(connectHandle = WinHttpConnect(
 
  408             RaiseUploadError(context, L
"Unable to connect to the service", GetLastError());
 
  413         if (!(requestHandle = WinHttpOpenRequest(
 
  419             WINHTTP_DEFAULT_ACCEPT_TYPES,
 
  420             WINHTTP_FLAG_REFRESH | serviceInfo->
HostFlags 
  423             RaiseUploadError(context, L
"Unable to create the request", GetLastError());
 
  438             L
"------------------------%I64u",
 
  443             L
"Content-Type: multipart/form-data; boundary=%s\r\n",
 
  452             L
"Content-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n",
 
  457             L
"Content-Type: application/octet-stream\r\n\r\n" 
  461             L
"\r\n--%s--\r\n\r\n",
 
  466         if (!WinHttpAddRequestHeaders(requestHandle,
 
  469             WINHTTP_ADDREQ_FLAG_REPLACE | WINHTTP_ADDREQ_FLAG_ADD
 
  472             RaiseUploadError(context, L
"Unable to add request headers", GetLastError());
 
  480         if (!WinHttpSendRequest(requestHandle,
 
  481             WINHTTP_NO_ADDITIONAL_HEADERS, 0,
 
  482             WINHTTP_NO_REQUEST_DATA, 0,
 
  486             RaiseUploadError(context, L
"Unable to send the request", GetLastError());
 
  498         if (!WinHttpWriteData(
 
  501             (ULONG)asciiPostData->
Length,
 
  502             &totalPostHeaderWritten
 
  505             RaiseUploadError(context, L
"Unable to write the post header", GetLastError());
 
  527             if (!WinHttpWriteData(requestHandle, buffer, (ULONG)isb.
Information, &totalWriteLength))
 
  529                 RaiseUploadError(context, L
"Unable to upload the file data", GetLastError());
 
  533             totalUploadedLength += totalWriteLength;
 
  538             timeBitsPerSecond = totalUploadedLength / __max(timeTicks, 1);
 
  541                 FLOAT percent = ((FLOAT)totalUploadedLength / context->
TotalFileLength * 100);
 
  548                     totalDownloadedLength->
Buffer,
 
  561                 PostMessage(context->
ProgressHandle, PBM_SETPOS, (INT)percent, 0);
 
  566         if (!WinHttpWriteData(
 
  569             (ULONG)asciiFooterData->
Length,
 
  570             &totalPostFooterWritten
 
  573             RaiseUploadError(context, L
"Unable to write the post footer", GetLastError());
 
  578         if (!WinHttpReceiveResponse(requestHandle, NULL))
 
  580             RaiseUploadError(context, L
"Unable to receive the response", GetLastError());
 
  587             WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
 
  594         if (httpStatus == HTTP_STATUS_OK || httpStatus == HTTP_STATUS_REDIRECT_METHOD || httpStatus == HTTP_STATUS_REDIRECT)
 
  600                     ULONG bufferLength = 0;
 
  603                     if (!WinHttpQueryOption(requestHandle, WINHTTP_OPTION_URL, NULL, &bufferLength))
 
  608                         if (WinHttpQueryOption(requestHandle, WINHTTP_OPTION_URL, buffer->
Buffer, &bufferLength))
 
  620                     PSTR hrefEquals = NULL;
 
  623                     ULONG bufferLength = 0;
 
  626                     if (!ReadRequestString(requestHandle, &buffer, &bufferLength))
 
  628                         RaiseUploadError(context, L
"Unable to complete the request", GetLastError());
 
  633                     hrefEquals = strstr(buffer, 
"href=\"");
 
  637                         quote = strchr(hrefEquals, 
'"');
 
  642                                 L
"http://virusscan.jotti.org%.*S",
 
  650                         PSTR tooManyFiles = strstr(buffer, 
"Too many files");
 
  656                                 L
"Unable to scan the file:\n\n" 
  657                                 L
"Too many files have been scanned from this IP in a short period. " 
  658                                 L
"Please try again later",
 
  669                     PSTR urlEquals = NULL;
 
  672                     ULONG bufferLength = 0;
 
  675                     if (!ReadRequestString(requestHandle, &buffer, &bufferLength))
 
  677                         RaiseUploadError(context, L
"Unable to complete the CIMA request", GetLastError());
 
  683                     urlEquals = strstr(buffer, 
"url=");
 
  688                         quote = strchr(urlEquals, 
'"');
 
  693                                 L
"http://camas.comodo.com%.*S",
 
  705             RaiseUploadError(context, L
"Unable to complete the request", STATUS_FVE_PARTIAL_METADATA);
 
  715             RaiseUploadError(context, L
"Unable to complete the Launch request (please try again after a few minutes)", ERROR_INVALID_DATA);
 
  736         if (httpPostFooter.
String)
 
  741         if (httpPostHeader.
String)
 
  746         if (httpRequestHeaders.
String)
 
  751         if (fileHandle != INVALID_HANDLE_VALUE)
 
  760 static NTSTATUS UploadCheckThreadStart(
 
  764     NTSTATUS status = STATUS_SUCCESS;
 
  765     BOOLEAN fileExists = 
FALSE;
 
  766     LARGE_INTEGER fileSize64;
 
  767     PSTR subRequestBuffer = NULL;
 
  768     HINTERNET connectHandle = NULL;
 
  769     HINTERNET requestHandle = NULL;
 
  773     HANDLE fileHandle = INVALID_HANDLE_VALUE;
 
  777     serviceInfo = GetUploadServiceInfo(context->
Service);
 
  787             FILE_SHARE_READ | FILE_SHARE_DELETE,
 
  802                 if (fileSize64.QuadPart > 128 * 1024 * 1024) 
 
  804                     RaiseUploadError(context, L
"The file is too large (over 128 MB)", ERROR_FILE_TOO_LARGE);
 
  810                 if (fileSize64.QuadPart > 20 * 1024 * 1024) 
 
  812                     RaiseUploadError(context, L
"The file is too large (over 20 MB)", ERROR_FILE_TOO_LARGE);
 
  824             WINHTTP_CURRENT_USER_IE_PROXY_CONFIG proxyConfig = { 0 };
 
  831             WinHttpGetIEProxyConfigForCurrentUser(&proxyConfig);
 
  836                 proxyConfig.lpszProxy != NULL ? WINHTTP_ACCESS_TYPE_NAMED_PROXY : WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
 
  837                 proxyConfig.lpszProxy,
 
  838                 proxyConfig.lpszProxyBypass,
 
  853                 PSTR uploadUrl = NULL;
 
  855                 ULONG bufferLength = 0;
 
  858                 status = HashFileAndResetPosition(fileHandle, &fileSize64, 
HASH_SHA256, hash);
 
  869                 if (!PerformSubRequest(context, serviceInfo->
HostName, subObjectName->
Buffer, &subRequestBuffer, &bufferLength))
 
  872                 if (strstr(subRequestBuffer, 
"\"file_exists\": true"))
 
  877                 uploadUrl = strstr(subRequestBuffer, 
"\"upload_url\": \"https://www.virustotal.com");
 
  880                     RaiseUploadError(context, L
"Unable to complete the request (no upload URL provided)", ERROR_INVALID_DATA);
 
  885                 quote = strchr(uploadUrl, 
'"');
 
  888                     RaiseUploadError(context, L
"Unable to complete the request (invalid upload URL)", ERROR_INVALID_DATA);
 
  901                 PSTR uploadId = NULL;
 
  903                 ULONG bufferLength = 0;
 
  906                 status = HashFileAndResetPosition(fileHandle, &fileSize64, 
HASH_SHA1, hash);
 
  916                 if (!PerformSubRequest(context, serviceInfo->
HostName, subObjectName->
Buffer, &subRequestBuffer, &bufferLength))
 
  919                 if (uploadId = strstr(subRequestBuffer, 
"\"id\":"))
 
  922                     quote = strchr(uploadId, 
'"');
 
  939                 ULONG bufferLength = 0;
 
  942                 ULONG statusLength = 
sizeof(statusLength);
 
  944                 status = HashFileAndResetPosition(fileHandle, &fileSize64, 
HASH_SHA256, hash);
 
  956                 if (!(connectHandle = WinHttpConnect(
 
  959                     INTERNET_DEFAULT_HTTP_PORT,
 
  963                     RaiseUploadError(context, L
"Unable to connect to the CIMA service", GetLastError());
 
  968                 if (!(requestHandle = WinHttpOpenRequest(
 
  974                     WINHTTP_DEFAULT_ACCEPT_TYPES,
 
  978                     RaiseUploadError(context, L
"Unable to create the CIMA request", GetLastError());
 
  983                 if (!WinHttpSendRequest(requestHandle, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0))
 
  985                     RaiseUploadError(context, L
"Unable to send the CIMA request", GetLastError());
 
  990                 if (!WinHttpReceiveResponse(requestHandle, NULL))
 
  992                     RaiseUploadError(context, L
"Unable to recieve the CIMA response", GetLastError());
 
  998                     WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
 
 1005                 if (status == HTTP_STATUS_OK)
 
 1027         if (!
NT_SUCCESS(UploadFileThreadStart(context)))
 
 1037             WinHttpCloseHandle(requestHandle);
 
 1042             WinHttpCloseHandle(connectHandle);
 
 1045         if (fileHandle != INVALID_HANDLE_VALUE)
 
 1047             NtClose(fileHandle);
 
 1054 static INT_PTR CALLBACK UploadDlgProc(
 
 1063     if (uMsg == WM_INITDIALOG)
 
 1066         SetProp(hwndDlg, L
"Context", (HANDLE)context);
 
 1072         if (uMsg == WM_NCDESTROY)
 
 1086             RemoveProp(hwndDlg, L
"Context");
 
 1098             HANDLE dialogThread = NULL;
 
 1099             HWND parentWindow = GetParent(hwndDlg);
 
 1101             PhCenterWindow(hwndDlg, (IsWindowVisible(parentWindow) && !IsIconic(parentWindow)) ? parentWindow : NULL);
 
 1117                 Static_SetText(hwndDlg, L
"Uploading to VirusTotal...");
 
 1120                 Static_SetText(hwndDlg, L
"Uploading to Jotti...");
 
 1123                 Static_SetText(hwndDlg, L
"Uploading to Comodo...");
 
 1127             if (dialogThread = 
PhCreateThread(0, UploadCheckThreadStart, (PVOID)context))
 
 1128                 NtClose(dialogThread);
 
 1133             switch (LOWORD(wParam))
 
 1151                         HANDLE dialogThread = NULL;
 
 1158                         Static_SetText(GetDlgItem(hwndDlg, IDNO), L
"Cancel");
 
 1162                         if (dialogThread = 
PhCreateThread(0, UploadFileThreadStart, (PVOID)context))
 
 1163                             NtClose(dialogThread);
 
 1181     case WM_CTLCOLORBTN:
 
 1182     case WM_CTLCOLORDLG:
 
 1183     case WM_CTLCOLORSTATIC:
 
 1185             HDC hDC = (HDC)wParam;
 
 1186             HWND hwndChild = (HWND)lParam;
 
 1191                 SetTextColor(hDC, RGB(19, 112, 171));
 
 1195             SetBkMode(hDC, TRANSPARENT);
 
 1198             return (INT_PTR)GetSysColorBrush(COLOR_WINDOW);
 
 1205             Static_SetText(GetDlgItem(hwndDlg, IDNO), L
"No");
 
 1208             Static_SetText(context->
MessageHandle, L
"File already analysed.");
 
 1209             Static_SetText(context->
StatusHandle, L
"View existing report?");
 
 1237                 Static_SetText(GetDlgItem(hwndDlg, 
IDC_MESSAGE), L
"Error");
 
 1240             Static_SetText(GetDlgItem(hwndDlg, 
IDC_STATUS), L
"");
 
 1241             Static_SetText(GetDlgItem(hwndDlg, IDNO), L
"Close");
 
 1249 static NTSTATUS PhUploadToDialogThreadStart(
 
 1250     _In_ PVOID Parameter
 
 1261     dialogHandle = CreateDialogParam(
 
 1269     ShowWindow(dialogHandle, SW_SHOW);
 
 1270     SetForegroundWindow(dialogHandle);
 
 1272     while (result = GetMessage(&message, NULL, 0, 0))
 
 1277         if (!IsDialogMessage(dialogHandle, &message))
 
 1279             TranslateMessage(&message);
 
 1280             DispatchMessage(&message);
 
 1287     DestroyWindow(dialogHandle);
 
 1289     return STATUS_SUCCESS;
 
 1297     HANDLE dialogThread = NULL;
 
 1307     if (dialogThread = 
PhCreateThread(0, PhUploadToDialogThreadStart, (PVOID)context))
 
 1308         NtClose(dialogThread);