reporterror.c

来自「一个类似windows」· C语言 代码 · 共 626 行 · 第 1/2 页

C
626
字号
/*
 * ReactOS Error Reporting Assistant
 * Copyright (C) 2004-2005 Casper S. Hornstrup <chorns@users.sourceforge.net>
 * Copyright (C) 2003-2004 Peter Willis <psyphreak@phreaker.net>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
/*
 * COPYRIGHT:   See COPYING in the top level directory
 * PROJECT:     ReactOS Error Reporting Assistant
 * FILE:        subsys/system/reporterror/reporterror.c
 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
 *              Thomas Weidenmueller (w3seek@users.sourceforge.net)
 */
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include <string.h>
#include "reporterror.h"

static LPSTR ErrorReportingServerName = "errors.reactos.com";
static HINSTANCE hAppInstance;
static HANDLE hSubmissionThread = NULL;
static HWND hSubmissionNotifyWnd = NULL;
static LONG AbortSubmission = 0;
static LPERROR_REPORT ErrorReport = NULL;

#define WM_ABORT_SUBMISSION (WM_USER + 2)
#define WM_CONTACTING_SERVER (WM_USER + 3)
#define WM_SUBMISSION_COMPLETE (WM_USER + 4)

#define MAX_REQUEST_BUFFER_SIZE 20480

LPSTR
UrlEncode(LPSTR in, LPSTR out)
{
  CHAR buffer[4];
  UCHAR iu;
  size_t i;

  for (i = 0; i < strlen(in); i++)
  {
    iu = (UCHAR)in[i];
    memset(buffer, '\0', sizeof(buffer));
    if ((iu < 33 || iu > 126))
      sprintf(buffer, "%%%02x", iu);
    else
      sprintf(buffer, "%c", iu);
    strcat(out, buffer);
  }
  return out;
}

LPERROR_REPORT
FillErrorReport(HWND hwndDlg)
{
  INT size;
  LPERROR_REPORT errorReport = malloc(sizeof(ERROR_REPORT));

  size = 300;
  errorReport->YourEmail = malloc(size);
  GetDlgItemTextA(hwndDlg,
    IDE_SUBMIT_REPORT_YOUR_EMAIL,
    errorReport->YourEmail,
    size);

  size = 10240;
  errorReport->ProblemDescription = malloc(size);
  GetDlgItemTextA(hwndDlg,
    IDE_SUBMIT_REPORT_PROBLEM_DESCRIPTION,
    errorReport->ProblemDescription,
    size);

  return errorReport;
}

VOID
ReleaseErrorReport(LPERROR_REPORT errorReport)
{
  if (errorReport->YourEmail)
    free(errorReport->YourEmail);
  if (errorReport->ProblemDescription)
    free(errorReport->ProblemDescription);
  free(errorReport);
}

BOOL
ProcessMessage(VOID)
{
  MSG msg;
  if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    return TRUE;
  }
  return FALSE;
}

VOID
ProcessMessages(VOID)
{
  while (ProcessMessage());
}

VOID
InitPropSheetPage(PROPSHEETPAGE *psp, WORD idDlg, DWORD Flags, DLGPROC DlgProc)
{
  ZeroMemory(psp, sizeof(PROPSHEETPAGE));
  psp->dwSize = sizeof(PROPSHEETPAGE);
  psp->dwFlags = PSP_DEFAULT | Flags;
  psp->hInstance = hAppInstance;
  psp->pszTemplate = MAKEINTRESOURCE(idDlg);
  psp->pfnDlgProc = DlgProc;
}

INT_PTR CALLBACK
PageFirstPageProc(
  HWND hwndDlg,
  UINT uMsg,
  WPARAM wParam,
  LPARAM lParam)
{
  switch(uMsg)
  {
    case WM_NOTIFY:
    {
      LPNMHDR pnmh = (LPNMHDR)lParam;
      switch (pnmh->code)
      {
        case PSN_SETACTIVE:
        {
          PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
          break;
        }
        case PSN_WIZNEXT:
        {
          SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_SUBMIT_REPORT);
          return TRUE;
        }
      }
      break;
    }
  }
  return FALSE;
}

INT_PTR CALLBACK
PageSubmitReportProc(
  HWND hwndDlg,
  UINT uMsg,
  WPARAM wParam,
  LPARAM lParam)
{
  switch (uMsg)
  {
    case WM_NOTIFY:
    {
      LPNMHDR pnmh = (LPNMHDR)lParam;
      switch (pnmh->code)
      {
        case PSN_SETACTIVE:
        {
          PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
          break;
        }
        case PSN_WIZNEXT:
        {
          ErrorReport = FillErrorReport(hwndDlg);
          SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_SUBMITTING_REPORT);
          break;
        }
      }
      break;
    }
  }
  return FALSE;
}

VOID
TerminateSubmission(BOOL Wait)
{
  if (hSubmissionThread != NULL)
  {
    if (Wait)
    {
      InterlockedExchange((LONG*)&AbortSubmission, 2);
      WaitForSingleObject(hSubmissionThread, INFINITE);
    }
    else
      InterlockedExchange((LONG*)&AbortSubmission, 1);
  }
}

INT
ConnectToServer(LPSTR host,
  SOCKET *clientSocket,
  LPWSTR errorMessage)
{
	struct sockaddr_in sin;
	struct hostent *hp;
	struct servent *sp;
	INT error;
	WCHAR szMsg[1024];
  SOCKET s;

  *clientSocket = 0;

	hp = gethostbyname(host);
	if (hp == NULL)
  {
    error = WSAGetLastError();
	
	//L"Could not resolve DNS for %S (windows error code %d)
	LoadString( GetModuleHandle(NULL), IDS_DNS_ERROR, (LPTSTR) szMsg, sizeof(szMsg) / sizeof(WCHAR));
    wsprintf(errorMessage, L"Could not resolve DNS for %S (windows error code %d)", host, error);    
    return error;
	}

	s = socket(hp->h_addrtype, SOCK_STREAM, 0);
	if (s < 0)
  {
    error = WSAGetLastError();

	//  L"Could not create socket (windows error code %d)
	LoadString( GetModuleHandle(NULL), IDS_SOCKET_ERROR, (LPTSTR) szMsg, sizeof(szMsg) / sizeof(WCHAR));
    wsprintf(errorMessage, szMsg, error);
    return error;
	}

	memset(&sin, 0, sizeof(sin));
	sin.sin_family = hp->h_addrtype;
	if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
  {
    error = WSAGetLastError();

    //L"Could not resolve DNS for %S (windows error code %d)
	LoadString( GetModuleHandle(NULL), IDS_DNS_ERROR, (LPTSTR) szMsg, sizeof(szMsg) / sizeof(WCHAR));
    wsprintf(errorMessage, L"Could not resolve DNS for %S (windows error code %d)", host, error);    
    closesocket(s);
    return error;
	}

	memcpy((char *)&sin.sin_addr, hp->h_addr, hp->h_length);
	sp = getservbyname("www", "tcp");
	if (sp == NULL)
  {
    error = WSAGetLastError();

	//L"Could not get service (windows error code %d)"

    LoadString( GetModuleHandle(NULL), IDS_GET_SRV_ERROR, (LPTSTR) szMsg, sizeof(szMsg) / sizeof(WCHAR));
    wsprintf(errorMessage, szMsg, error);
    closesocket(s);
    return error;
	}

	sin.sin_port = sp->s_port;

	if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
  {
    error = WSAGetLastError();
	
	//L"Could not connect to server (windows error code %d)"
	LoadString( GetModuleHandle(NULL), IDS_CON_SRV_ERROR, (LPTSTR) szMsg, sizeof(szMsg) / sizeof(WCHAR));
    wsprintf(errorMessage,szMsg , error);
    closesocket(s);
    return error;
	}

  *clientSocket = s;
  return NO_ERROR;
}

VOID
CreateHTTPPostRequest(LPSTR requestBuffer,
  LPSTR hostname,
  LPERROR_REPORT errorReport)
{
  LPSTR parameterBuffer;
  LPSTR urlencodeBuffer;

  parameterBuffer = malloc(MAX_REQUEST_BUFFER_SIZE);
  memset(parameterBuffer, '\0', MAX_REQUEST_BUFFER_SIZE);

  strcat(parameterBuffer, "errorReport=");
  strcat(parameterBuffer, "<ErrorReportRequest>");
  strcat(parameterBuffer, "<YourEmail>");
  strcat(parameterBuffer, errorReport->YourEmail);
  strcat(parameterBuffer, "</YourEmail>");
  strcat(parameterBuffer, "<ProblemDescription>");
  strcat(parameterBuffer, errorReport->ProblemDescription);
  strcat(parameterBuffer, "</ProblemDescription>");
  strcat(parameterBuffer, "</ErrorReportRequest>");
  strcat(parameterBuffer, "\r\n");

  urlencodeBuffer = malloc(MAX_REQUEST_BUFFER_SIZE);
  memset(urlencodeBuffer, '\0', MAX_REQUEST_BUFFER_SIZE);

  UrlEncode(parameterBuffer, urlencodeBuffer);
  sprintf(requestBuffer, "POST /Report.asmx/SubmitErrorReport HTTP/1.1\r\n"

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?