Sync with trunk head (part 1 of 2)

svn path=/branches/header-work/; revision=46262
This commit is contained in:
Amine Khaldi
2010-03-18 15:37:13 +00:00
143 changed files with 15887 additions and 8167 deletions
+19 -3
View File
@@ -126,7 +126,6 @@ InitializeTabCtrl(HWND hwndDlg, PDXDIAG_CONTEXT pContext)
pContext->hDialogs[4] = CreateDialogParamW(hInst, MAKEINTRESOURCEW(IDD_HELP_DIALOG), hTabCtrlWnd, HelpPageWndProc, (LPARAM)pContext);
/* insert tab ctrl items */
InsertTabCtrlItem(hTabCtrlWnd, 0, MAKEINTRESOURCEW(IDS_SYSTEM_DIALOG));
InitializeDisplayAdapters(pContext);
InitializeDirectSoundPage(pContext);
@@ -188,8 +187,19 @@ DxDiagWndProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
if (LOWORD(wParam) == IDC_BUTTON_NEXT)
{
//TODO
/* handle next button */
INT CurSel;
/* retrieve current page */
CurSel = TabCtrl_GetCurSel(hTabCtrlWnd);
CurSel++;
/* enable/disable next button */
EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_NEXT),
(CurSel != TabCtrl_GetItemCount(hTabCtrlWnd) - 1));
/* switch to next page */
SendMessageW(hTabCtrlWnd, TCM_SETCURSEL, CurSel, 0L);
return TRUE;
}
@@ -210,6 +220,12 @@ DxDiagWndProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
pnmh = (LPNMHDR)lParam;
if ((pnmh->hwndFrom == hTabCtrlWnd) && (pnmh->idFrom == IDC_TAB_CONTROL) && (pnmh->code == TCN_SELCHANGE))
{
INT CurSel = TabCtrl_GetCurSel(hTabCtrlWnd);
/* enable/disable next button */
EnableWindow(GetDlgItem(hwndDlg, IDC_BUTTON_NEXT),
(CurSel != TabCtrl_GetItemCount(hTabCtrlWnd) - 1));
TabCtrl_OnSelChange(pContext);
}
break;
+2 -3
View File
@@ -17,7 +17,6 @@ GetRegValue(HKEY hBaseKey, LPWSTR SubKey, LPWSTR ValueName, DWORD Type, LPWSTR R
DWORD dwType;
DWORD dwSize;
if (RegOpenKeyExW(hBaseKey, SubKey, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
return FALSE;
@@ -25,10 +24,10 @@ GetRegValue(HKEY hBaseKey, LPWSTR SubKey, LPWSTR ValueName, DWORD Type, LPWSTR R
res = RegQueryValueExW(hKey, ValueName, NULL, &dwType, (LPBYTE)Result, &dwSize);
RegCloseKey(hKey);
if (dwType != Type)
if (res != ERROR_SUCCESS)
return FALSE;
if (res != ERROR_SUCCESS)
if (dwType != Type)
return FALSE;
if (Size == sizeof(DWORD))
+6 -6
View File
@@ -8,35 +8,35 @@ Description = The most popular and one of the best free Web Browsers out there.
Size = 7.1M
Category = 5
URLSite = http://www.mozilla.com/en-US/
URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/latest-3.0/win32/en-US/Firefox%20Setup%203.0.17.exe
URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/latest-3.0/win32/en-US/Firefox%20Setup%203.0.18.exe
CDPath = none
[Section.0407]
Description = Der populärste und einer der besten freien Webbrowser.
Size = 6.9M
URLSite = http://www.mozilla-europe.org/de/
URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/latest-3.0/win32/de/Firefox%20Setup%203.0.17.exe
URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/latest-3.0/win32/de/Firefox%20Setup%203.0.18.exe
[Section.040a]
Description = El más popular y uno de los mejores navegadores web gratuitos que hay.
Size = 7.0M
URLSite = http://www.mozilla-europe.org/es/
URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/latest-3.0/win32/es-ES/Firefox%20Setup%203.0.17.exe
URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/latest-3.0/win32/es-ES/Firefox%20Setup%203.0.18.exe
[Section.0414]
Description = Mest populære og best også gratis nettleserene der ute.
Size = 6.9M
URLSite = http://www.mozilla-europe.org/no/
URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/latest-3.0/win32/nb-NO/Firefox%20Setup%203.0.17.exe
URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/latest-3.0/win32/nb-NO/Firefox%20Setup%203.0.18.exe
[Section.0415]
Description = Najpopularniejsza i jedna z najlepszych darmowych przeglądarek internetowych.
Size = 7.8M
URLSite = http://www.mozilla-europe.org/pl/
URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/latest-3.0/win32/pl/Firefox%20Setup%203.0.17.exe
URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/latest-3.0/win32/pl/Firefox%20Setup%203.0.18.exe
[Section.0419]
Description = Один из самых популярных и лучших бесплатных браузеров.
Size = 7.4M
URLSite = http://www.mozilla-europe.org/ru/
URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/latest-3.0/win32/ru/Firefox%20Setup%203.0.17.exe
URLDownload = http://releases.mozilla.org/pub/mozilla.org/firefox/releases/latest-3.0/win32/ru/Firefox%20Setup%203.0.18.exe
@@ -8,23 +8,23 @@ Description = THE Open Source Office Suite.
Size = 127MB
Category = 6
URLSite = http://www.openoffice.org/
URLDownload = http://ftp.plusline.de/OpenOffice/stable/2.4.3/OOo_2.4.3_Win32Intel_install_en-US.exe
URLDownload = ftp://archive.services.openoffice.org/pub/openoffice-archive/stable/2.4.3/OOo_2.4.3_Win32Intel_install_en-US.exe
CDPath = none
[Section.0407]
Description = DIE Open Source Office Suite.
URLSite = http://de.openoffice.org/
Size = 114.2MB
URLDownload = http://ftp.tu-chemnitz.de/pub/openoffice/localized/de/2.4.3/OOo_2.4.3_Win32Intel_install_de.exe
URLDownload = ftp://archive.services.openoffice.org/pub/openoffice-archive/localized/de/2.4.3/OOo_2.4.3_Win32Intel_install_de.exe
[Section.040a]
Description = La suite de ofimática de código abierto.
URLSite = http://es.openoffice.org/
Size = 113.9MB
URLDownload = http://ftp.tu-chemnitz.de/pub/openoffice/localized/es/2.4.3/OOo_2.4.3_Win32Intel_install_es.exe
URLDownload = ftp://archive.services.openoffice.org/pub/openoffice-archive/localized/es/2.4.3/OOo_2.4.3_Win32Intel_install_es.exe
[Section.0415]
URLSite = http://pl.openoffice.org/
Description = Otwarty pakiet biurowy.
URLDownload = http://ftp.tu-chemnitz.de/pub/openoffice/localized/pl/2.4.2/OOo_2.4.2_Win32Intel_install_pl.exe
URLDownload = ftp://archive.services.openoffice.org/pub/openoffice-archive/localized/pl/2.4.2/OOo_2.4.2_Win32Intel_install_pl.exe
Size = 113.9M
@@ -2,30 +2,30 @@
[Section]
Name = OpenOffice 3.0
Version = 3.1.1
Version = 3.2.0
Licence = LGPL
Description = THE Open Source Office Suite.
Size = 134.3MB
Size = 135.4MB
Category = 6
URLSite = http://www.openoffice.org/
URLDownload = http://ftp.tu-chemnitz.de/pub/openoffice/stable/3.1.1/OOo_3.1.1_Win32Intel_install_en-US.exe
URLDownload = http://ftp.tu-chemnitz.de/pub/openoffice/stable/3.2.0/OOo_3.2.0_Win32Intel_install_en-US.exe
CDPath = none
[Section.0407]
Description = DIE Open Source Office Suite.
URLSite = http://de.openoffice.org/
Size = 142.9MB
URLDownload = http://ftp.tu-chemnitz.de/pub/openoffice/localized/de/3.1.1/OOo_3.1.1_Win32Intel_install_de.exe
Size = 145.8MB
URLDownload = http://ftp.tu-chemnitz.de/pub/openoffice/localized/de/3.2.0/OOo_3.2.0_Win32Intel_install_de.exe
[Section.040a]
Description = La suite de ofimática de código abierto.
URLSite = http://es.openoffice.org/
Version = 3.1.0
Size = 130.0MB
URLDownload = http://ftp.tu-chemnitz.de/pub/openoffice/localized/es/3.1.0/OOo_3.1.0_Win32Intel_install_es.exe
Size = 119.4MB
URLDownload = http://ftp.tu-chemnitz.de/pub/openoffice/localized/es/3.2.0/OOo_3.2.0_Win32Intel_install_es.exe
[Section.0415]
Description = Otwarty pakiet biurowy.
URLSite = http://pl.openoffice.org/
Size = 147.1MB
URLDownload = http://ftp.tu-chemnitz.de/pub/openoffice/localized/pl/3.1.1/OOo_3.1.1_Win32Intel_install_pl.exe
Size = 133.2MB
URLDownload = http://ftp.tu-chemnitz.de/pub/openoffice/localized/pl/3.2.0/OOo_3.2.0_Win32Intel_install_pl.exe
+2 -2
View File
@@ -2,13 +2,13 @@
[Section]
Name = SciTE
Version = 2.02
Version = 2.03
Licence = Freeware
Description = SciTE is a SCIntilla based Text Editor. Originally built to demonstrate Scintilla, it has grown to be a generally useful editor with facilities for building and running programs.
Size = 0.6M
Category = 7
URLSite = http://www.scintilla.org/
URLDownload = http://ovh.dl.sourceforge.net/sourceforge/scintilla/Sc202.exe
URLDownload = http://ovh.dl.sourceforge.net/sourceforge/scintilla/Sc203.exe
CDPath = none
[Section.0407]
+64 -21
View File
@@ -21,20 +21,76 @@ static SERVICE_TABLE_ENTRYW ServiceTable[2] =
{ NULL, NULL }
};
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE ServiceStatusHandle;
BOOL onLiveCD = FALSE; // On livecd events will go to debug output only
HANDLE MyHeap = NULL;
/* FUNCTIONS ****************************************************************/
static VOID
UpdateServiceStatus(DWORD dwState)
{
ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ServiceStatus.dwCurrentState = dwState;
ServiceStatus.dwControlsAccepted = 0;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
if (dwState == SERVICE_START_PENDING ||
dwState == SERVICE_STOP_PENDING ||
dwState == SERVICE_PAUSE_PENDING ||
dwState == SERVICE_CONTINUE_PENDING)
ServiceStatus.dwWaitHint = 10000;
else
ServiceStatus.dwWaitHint = 0;
SetServiceStatus(ServiceStatusHandle,
&ServiceStatus);
}
static DWORD WINAPI
ServiceControlHandler(DWORD dwControl,
DWORD dwEventType,
LPVOID lpEventData,
LPVOID lpContext)
{
/* FIXME */
DPRINT1("ServiceControlHandler() called (control code %lu)\n", dwControl);
return ERROR_SUCCESS;
DPRINT("ServiceControlHandler() called\n");
switch (dwControl)
{
case SERVICE_CONTROL_STOP:
DPRINT(" SERVICE_CONTROL_STOP received\n");
UpdateServiceStatus(SERVICE_STOPPED);
return ERROR_SUCCESS;
case SERVICE_CONTROL_PAUSE:
DPRINT(" SERVICE_CONTROL_PAUSE received\n");
UpdateServiceStatus(SERVICE_PAUSED);
return ERROR_SUCCESS;
case SERVICE_CONTROL_CONTINUE:
DPRINT(" SERVICE_CONTROL_CONTINUE received\n");
UpdateServiceStatus(SERVICE_RUNNING);
return ERROR_SUCCESS;
case SERVICE_CONTROL_INTERROGATE:
DPRINT(" SERVICE_CONTROL_INTERROGATE received\n");
SetServiceStatus(ServiceStatusHandle,
&ServiceStatus);
return ERROR_SUCCESS;
case SERVICE_CONTROL_SHUTDOWN:
DPRINT(" SERVICE_CONTROL_SHUTDOWN received\n");
UpdateServiceStatus(SERVICE_STOPPED);
return ERROR_SUCCESS;
default :
DPRINT1(" Control %lu received\n");
return ERROR_CALL_NOT_IMPLEMENTED;
}
}
@@ -83,8 +139,6 @@ static VOID CALLBACK
ServiceMain(DWORD argc,
LPWSTR *argv)
{
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE ServiceStatusHandle;
DWORD dwError;
UNREFERENCED_PARAMETER(argc);
@@ -102,31 +156,20 @@ ServiceMain(DWORD argc,
return;
}
ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = 0;
ServiceStatus.dwWin32ExitCode = NO_ERROR;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 2000;
SetServiceStatus(ServiceStatusHandle,
&ServiceStatus);
UpdateServiceStatus(SERVICE_START_PENDING);
dwError = ServiceInit();
if (dwError != ERROR_SUCCESS)
{
DPRINT1("Service stopped\n");
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
DPRINT("Service stopped (dwError: %lu\n", dwError);
UpdateServiceStatus(SERVICE_START_PENDING);
}
else
{
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
DPRINT("Service started\n");
UpdateServiceStatus(SERVICE_RUNNING);
}
SetServiceStatus(ServiceStatusHandle,
&ServiceStatus);
DPRINT("ServiceMain() done\n");
}
+6 -4
View File
@@ -44,7 +44,8 @@ typedef struct _IO_ERROR_LPC
#define ELF_LOGFILE_ARCHIVE_SET 8
/* FIXME: MSDN reads that the following two structs are in winnt.h. Are they? */
typedef struct _EVENTLOGHEADER {
typedef struct _EVENTLOGHEADER
{
ULONG HeaderSize;
ULONG Signature;
ULONG MajorVersion;
@@ -59,7 +60,8 @@ typedef struct _EVENTLOGHEADER {
ULONG EndHeaderSize;
} EVENTLOGHEADER, *PEVENTLOGHEADER;
typedef struct _EVENTLOGEOF {
typedef struct _EVENTLOGEOF
{
ULONG RecordSizeBeginning;
ULONG Ones;
ULONG Twos;
@@ -72,13 +74,13 @@ typedef struct _EVENTLOGEOF {
ULONG RecordSizeEnd;
} EVENTLOGEOF, *PEVENTLOGEOF;
typedef struct
typedef struct _EVENT_OFFSET_INFO
{
ULONG EventNumber;
ULONG EventOffset;
} EVENT_OFFSET_INFO, *PEVENT_OFFSET_INFO;
typedef struct
typedef struct _LOGFILE
{
HANDLE hFile;
EVENTLOGHEADER Header;
+43 -48
View File
@@ -480,45 +480,29 @@ NTSTATUS ElfrOpenELA(
DWORD MinorVersion,
IELF_HANDLE *LogHandle)
{
UNICODE_STRING UNCServerNameW = { 0, 0, NULL };
UNICODE_STRING ModuleNameW = { 0, 0, NULL };
UNICODE_STRING RegModuleNameW = { 0, 0, NULL };
NTSTATUS Status;
UNICODE_STRING ModuleNameW;
if (UNCServerName &&
!RtlCreateUnicodeStringFromAsciiz(&UNCServerNameW, UNCServerName))
{
return STATUS_NO_MEMORY;
}
if ((MajorVersion != 1) || (MinorVersion != 1))
return STATUS_INVALID_PARAMETER;
if (ModuleName &&
!RtlAnsiStringToUnicodeString(&ModuleNameW, (PANSI_STRING)ModuleName, TRUE))
{
RtlFreeUnicodeString(&UNCServerNameW);
return STATUS_NO_MEMORY;
}
/* RegModuleName must be an empty string */
if (RegModuleName->Length > 0)
return STATUS_INVALID_PARAMETER;
if (RegModuleName &&
!RtlAnsiStringToUnicodeString(&RegModuleNameW, (PANSI_STRING)RegModuleName, TRUE))
{
RtlFreeUnicodeString(&UNCServerNameW);
RtlFreeUnicodeString(&ModuleNameW);
return STATUS_NO_MEMORY;
}
RtlAnsiStringToUnicodeString(&ModuleNameW, (PANSI_STRING)ModuleName, TRUE);
Status = ElfrOpenELW(
UNCServerName ? UNCServerNameW.Buffer : NULL,
ModuleName ? (PRPC_UNICODE_STRING)&ModuleNameW : NULL,
RegModuleName ? (PRPC_UNICODE_STRING)&RegModuleNameW : NULL,
MajorVersion,
MinorVersion,
LogHandle);
/* FIXME: Must verify that caller has read access */
*LogHandle = ElfCreateEventLogHandle(ModuleNameW.Buffer, FALSE);
RtlFreeUnicodeString(&UNCServerNameW);
RtlFreeUnicodeString(&ModuleNameW);
RtlFreeUnicodeString(&RegModuleNameW);
return Status;
if (*LogHandle == NULL)
{
return STATUS_INVALID_PARAMETER;
}
return STATUS_SUCCESS;
}
@@ -531,45 +515,32 @@ NTSTATUS ElfrRegisterEventSourceA(
DWORD MinorVersion,
IELF_HANDLE *LogHandle)
{
UNICODE_STRING UNCServerNameW = { 0, 0, NULL };
UNICODE_STRING ModuleNameW = { 0, 0, NULL };
if (UNCServerName &&
!RtlCreateUnicodeStringFromAsciiz(&UNCServerNameW, UNCServerName))
{
return STATUS_NO_MEMORY;
}
if (ModuleName &&
!RtlAnsiStringToUnicodeString(&ModuleNameW, (PANSI_STRING)ModuleName, TRUE))
{
RtlFreeUnicodeString(&UNCServerNameW);
return STATUS_NO_MEMORY;
}
/* RegModuleName must be an empty string */
if (RegModuleName->Length > 0)
{
RtlFreeUnicodeString(&UNCServerNameW);
RtlFreeUnicodeString(&ModuleNameW);
return STATUS_INVALID_PARAMETER;
}
if ((MajorVersion != 1) || (MinorVersion != 1))
{
RtlFreeUnicodeString(&UNCServerNameW);
RtlFreeUnicodeString(&ModuleNameW);
return STATUS_INVALID_PARAMETER;
}
/*FIXME: UNCServerName must specify the server or empty for local */
/*FIXME: Must verify that caller has write access */
/* FIXME: Must verify that caller has write access */
*LogHandle = ElfCreateEventLogHandle(ModuleNameW.Buffer,
TRUE);
RtlFreeUnicodeString(&UNCServerNameW);
RtlFreeUnicodeString(&ModuleNameW);
return STATUS_SUCCESS;
@@ -661,8 +632,32 @@ NTSTATUS ElfrGetLogInformation(
DWORD cbBufSize,
DWORD *pcbBytesNeeded)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
NTSTATUS Status = STATUS_SUCCESS;
/* FIXME: check handle first */
switch (InfoLevel)
{
case EVENTLOG_FULL_INFO:
{
LPEVENTLOG_FULL_INFORMATION efi = (LPEVENTLOG_FULL_INFORMATION)Buffer;
*pcbBytesNeeded = sizeof(EVENTLOG_FULL_INFORMATION);
if (cbBufSize < sizeof(EVENTLOG_FULL_INFORMATION))
{
return STATUS_BUFFER_TOO_SMALL;
}
efi->dwFull = 0; /* FIXME */
}
break;
default:
Status = STATUS_INVALID_LEVEL;
break;
}
return Status;
}
+1
View File
@@ -3,6 +3,7 @@
<group xmlns:xi="http://www.w3.org/2001/XInclude">
<property name="BASEADDRESS_REGTESTS" value="0x07000000" />
<property name="BASEADDRESS_NOTIFYHOOK" value="0x08000000" />
<property name="BASEADDRESS_FAULTREP" value="0x107A0000" />
<property name="BASEADDRESS_QMGRPRXY" value="0x1f710000" />
<property name="BASEADDRESS_CRYPTDLG" value="0x209c0000" />
<property name="BASEADDRESS_COMCAT" value="0x20a50000" />
+1
View File
@@ -286,6 +286,7 @@ dll\win32\dwmapi\dwmapi.dll 1
dll\win32\devmgr\devmgr.dll 1
dll\win32\dhcpcsvc\dhcpcsvc.dll 1
dll\win32\dnsapi\dnsapi.dll 1
dll\win32\faultrep\faultrep.dll 1
dll\win32\fmifs\fmifs.dll 1
dll\win32\fusion\fusion.dll 1
dll\win32\gdi32\gdi32.dll 1
+2 -2
View File
@@ -232,7 +232,7 @@ WinLdrLoadDeviceDriver(PLOADER_PARAMETER_BLOCK LoaderBlock,
PVOID DriverBase;
// Separate the path to file name and directory path
sprintf(DriverPath, "%S", FilePath->Buffer);
snprintf(DriverPath, sizeof(DriverPath), "%wZ", FilePath);
DriverNamePos = strrchr(DriverPath, '\\');
if (DriverNamePos != NULL)
{
@@ -261,7 +261,7 @@ WinLdrLoadDeviceDriver(PLOADER_PARAMETER_BLOCK LoaderBlock,
}
// It's not loaded, we have to load it
sprintf(FullPath,"%s%S", BootPath, FilePath->Buffer);
snprintf(FullPath, sizeof(FullPath), "%s%wZ", BootPath, FilePath);
Status = WinLdrLoadImage(FullPath, LoaderBootDriver, &DriverBase);
if (!Status)
return FALSE;
+104 -14
View File
@@ -42,12 +42,25 @@ public:
HRESULT STDMETHODCALLTYPE KsQueryExtendedSize(OUT ULONG* ExtendedSize);
HRESULT STDMETHODCALLTYPE KsSetMediaType(IN const AM_MEDIA_TYPE* AmMediaType);
CKsDataTypeHandler() : m_Ref(0){};
virtual ~CKsDataTypeHandler(){};
CKsDataTypeHandler() : m_Ref(0), m_Type(0){};
virtual ~CKsDataTypeHandler()
{
if (m_Type)
{
if (m_Type->pbFormat)
CoTaskMemFree(m_Type->pbFormat);
if (m_Type->pUnk)
m_Type->pUnk->Release();
CoTaskMemFree(m_Type);
}
};
protected:
//CMediaType * m_Type;
LONG m_Ref;
AM_MEDIA_TYPE * m_Type;
};
@@ -85,8 +98,68 @@ STDMETHODCALLTYPE
CKsDataTypeHandler::KsIsMediaTypeInRanges(
IN PVOID DataRanges)
{
OutputDebugString("UNIMPLEMENTED\n");
return E_NOTIMPL;
PKSMULTIPLE_ITEM DataList;
PKSDATARANGE DataRange;
ULONG Index;
HRESULT hr = S_FALSE;
OutputDebugStringW(L"CKsDataTypeHandler::KsIsMediaTypeInRanges\n");
DataList = (PKSMULTIPLE_ITEM)DataRanges;
DataRange = (PKSDATARANGE)(DataList + 1);
for(Index = 0; Index < DataList->Count; Index++)
{
BOOL bMatch = FALSE;
if (DataRange->FormatSize >= sizeof(KSDATARANGE))
{
bMatch = IsEqualGUID(DataRange->MajorFormat, GUID_NULL);
}
if (!bMatch && DataRange->FormatSize >= sizeof(KSDATARANGE_AUDIO))
{
bMatch = IsEqualGUID(DataRange->MajorFormat, MEDIATYPE_Audio);
}
if (bMatch)
{
if (IsEqualGUID(DataRange->SubFormat, m_Type->subtype) ||
IsEqualGUID(DataRange->SubFormat, GUID_NULL))
{
if (IsEqualGUID(DataRange->Specifier, m_Type->formattype) ||
IsEqualGUID(DataRange->Specifier, GUID_NULL))
{
if (!IsEqualGUID(m_Type->formattype, FORMAT_WaveFormatEx) && !IsEqualGUID(DataRange->Specifier, FORMAT_WaveFormatEx))
{
//found match
hr = S_OK;
break;
}
if (DataRange->FormatSize >= sizeof(KSDATARANGE_AUDIO) && m_Type->cbFormat >= sizeof(WAVEFORMATEX))
{
LPWAVEFORMATEX Format = (LPWAVEFORMATEX)m_Type->pbFormat;
PKSDATARANGE_AUDIO AudioRange = (PKSDATARANGE_AUDIO)DataRange;
if (Format->nSamplesPerSec >= AudioRange->MinimumSampleFrequency &&
Format->nSamplesPerSec <= AudioRange->MaximumSampleFrequency &&
Format->wBitsPerSample >= AudioRange->MinimumSampleFrequency &&
Format->wBitsPerSample <= AudioRange->MaximumBitsPerSample &&
Format->nChannels <= AudioRange->MaximumChannels)
{
// found match
hr = S_OK;
break;
}
}
}
}
}
DataRange = (PKSDATARANGE)(((ULONG_PTR)DataRange + DataRange->FormatSize + 7) & ~7);
}
return S_OK;
}
HRESULT
@@ -106,7 +179,6 @@ CKsDataTypeHandler::KsQueryExtendedSize(
{
/* no header extension required */
*ExtendedSize = 0;
return NOERROR;
}
@@ -115,19 +187,38 @@ STDMETHODCALLTYPE
CKsDataTypeHandler::KsSetMediaType(
IN const AM_MEDIA_TYPE* AmMediaType)
{
#if 0
OutputDebugString("CKsDataTypeHandler::KsSetMediaType\n");
if (m_Type)
{
/* media type can only be set once */
return E_FAIL;
}
#endif
/*
* TODO: allocate CMediaType and copy parameters
*/
OutputDebugString("UNIMPLEMENTED\n");
return E_NOTIMPL;
m_Type = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
if (!m_Type)
return E_OUTOFMEMORY;
CopyMemory(m_Type, AmMediaType, sizeof(AM_MEDIA_TYPE));
if (m_Type->cbFormat)
{
m_Type->pbFormat = (BYTE*)CoTaskMemAlloc(m_Type->cbFormat);
if (!m_Type->pbFormat)
{
CoTaskMemFree(m_Type);
return E_OUTOFMEMORY;
}
CopyMemory(m_Type->pbFormat, AmMediaType->pbFormat, m_Type->cbFormat);
}
if (m_Type->pUnk)
m_Type->pUnk->AddRef();
return S_OK;
}
HRESULT
@@ -138,7 +229,6 @@ CKsDataTypeHandler_Constructor (
LPVOID * ppv)
{
OutputDebugStringW(L"CKsDataTypeHandler_Constructor\n");
CKsDataTypeHandler * handler = new CKsDataTypeHandler();
if (!handler)
+402 -22
View File
@@ -1,20 +1,21 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS WDM Streaming ActiveMovie Proxy
* FILE: dll/directx/ksproxy/input_cpp.cpp
* FILE: dll/directx/ksproxy/input_pin.cpp
* PURPOSE: InputPin of Proxy Filter
*
* PROGRAMMERS: Johannes Anderwald ([email protected])
*/
#include "precomp.h"
const GUID IID_IKsPinEx = {0x7bb38260L, 0xd19c, 0x11d2, {0xb3, 0x8a, 0x00, 0xa0, 0xc9, 0x5e, 0xc2, 0x2e}};
const GUID IID_IKsPinPipe = {0xe539cd90, 0xa8b4, 0x11d1, {0x81, 0x89, 0x00, 0xa0, 0xc9, 0x06, 0x28, 0x02}};
const GUID IID_IKsPinEx = {0x7bb38260L, 0xd19c, 0x11d2, {0xb3, 0x8a, 0x00, 0xa0, 0xc9, 0x5e, 0xc2, 0x2e}};
#ifndef _MSC_VER
const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
#endif
#ifndef _MSC_VER
KSPIN_INTERFACE StandardPinInterface =
{
{STATIC_KSINTERFACESETID_Standard},
@@ -52,15 +53,13 @@ class CInputPin : public IPin,
public IKsControl,
public IKsObject,
public IKsPinEx,
public IMemInputPin
/*
public IQualityControl,
public IMemInputPin,
public IKsPinPipe,
public ISpecifyPropertyPages,
public IStreamBuilder,
public IKsPinFactory,
public IKsAggregateControl
*/
public IStreamBuilder,
public IKsAggregateControl,
public IQualityControl,
public ISpecifyPropertyPages
{
public:
STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
@@ -81,6 +80,19 @@ public:
return m_Ref;
}
//IKsPinPipe
HRESULT STDMETHODCALLTYPE KsGetPinFramingCache(PKSALLOCATOR_FRAMING_EX *FramingEx, PFRAMING_PROP FramingProp, FRAMING_CACHE_OPS Option);
HRESULT STDMETHODCALLTYPE KsSetPinFramingCache(PKSALLOCATOR_FRAMING_EX FramingEx, PFRAMING_PROP FramingProp, FRAMING_CACHE_OPS Option);
IPin* STDMETHODCALLTYPE KsGetConnectedPin();
IKsAllocatorEx* STDMETHODCALLTYPE KsGetPipe(KSPEEKOPERATION Operation);
HRESULT STDMETHODCALLTYPE KsSetPipe(IKsAllocatorEx *KsAllocator);
ULONG STDMETHODCALLTYPE KsGetPipeAllocatorFlag();
HRESULT STDMETHODCALLTYPE KsSetPipeAllocatorFlag(ULONG Flag);
GUID STDMETHODCALLTYPE KsGetPinBusCache();
HRESULT STDMETHODCALLTYPE KsSetPinBusCache(GUID Bus);
PWCHAR STDMETHODCALLTYPE KsGetPinName();
PWCHAR STDMETHODCALLTYPE KsGetFilterName();
//IPin methods
HRESULT STDMETHODCALLTYPE Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt);
HRESULT STDMETHODCALLTYPE ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt);
@@ -98,6 +110,9 @@ public:
HRESULT STDMETHODCALLTYPE EndFlush();
HRESULT STDMETHODCALLTYPE NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
// ISpecifyPropertyPages
HRESULT STDMETHODCALLTYPE GetPages(CAUUID *pPages);
//IKsObject methods
HANDLE STDMETHODCALLTYPE KsGetObjectHandle();
@@ -136,11 +151,26 @@ public:
HRESULT STDMETHODCALLTYPE ReceiveMultiple(IMediaSample **pSamples, long nSamples, long *nSamplesProcessed);
HRESULT STDMETHODCALLTYPE ReceiveCanBlock( void);
//IKsPinFactory
HRESULT STDMETHODCALLTYPE KsPinFactory(ULONG* PinFactory);
//IStreamBuilder
HRESULT STDMETHODCALLTYPE Render(IPin *ppinOut, IGraphBuilder *pGraph);
HRESULT STDMETHODCALLTYPE Backout(IPin *ppinOut, IGraphBuilder *pGraph);
//IKsAggregateControl
HRESULT STDMETHODCALLTYPE KsAddAggregate(IN REFGUID AggregateClass);
HRESULT STDMETHODCALLTYPE KsRemoveAggregate(REFGUID AggregateClass);
//IQualityControl
HRESULT STDMETHODCALLTYPE Notify(IBaseFilter *pSelf, Quality q);
HRESULT STDMETHODCALLTYPE SetSink(IQualityControl *piqc);
//---------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CheckFormat(const AM_MEDIA_TYPE *pmt);
HRESULT STDMETHODCALLTYPE CreatePin(const AM_MEDIA_TYPE *pmt);
HRESULT STDMETHODCALLTYPE CreatePinHandle(PKSPIN_MEDIUM Medium, PKSPIN_INTERFACE Interface, const AM_MEDIA_TYPE *pmt);
CInputPin(IBaseFilter * ParentFilter, LPCWSTR PinName, HANDLE hFilter, ULONG PinId, KSPIN_COMMUNICATION Communication) : m_Ref(0), m_ParentFilter(ParentFilter), m_PinName(PinName), m_hFilter(hFilter), m_hPin(0), m_PinId(PinId), m_MemAllocator(0), m_IoCount(0), m_Communication(Communication), m_Pin(0), m_ReadOnly(0){};
CInputPin(IBaseFilter * ParentFilter, LPCWSTR PinName, HANDLE hFilter, ULONG PinId, KSPIN_COMMUNICATION Communication);
virtual ~CInputPin(){};
protected:
@@ -157,8 +187,42 @@ protected:
KSPIN_MEDIUM m_Medium;
IPin * m_Pin;
BOOL m_ReadOnly;
IKsInterfaceHandler * m_InterfaceHandler;
IKsAllocatorEx * m_KsAllocatorEx;
ULONG m_PipeAllocatorFlag;
BOOL m_bPinBusCacheInitialized;
GUID m_PinBusCache;
LPWSTR m_FilterName;
FRAMING_PROP m_FramingProp[4];
PKSALLOCATOR_FRAMING_EX m_FramingEx[4];
};
CInputPin::CInputPin(
IBaseFilter * ParentFilter,
LPCWSTR PinName,
HANDLE hFilter,
ULONG PinId,
KSPIN_COMMUNICATION Communication) : m_Ref(0),
m_ParentFilter(ParentFilter),
m_PinName(PinName),
m_hFilter(hFilter),
m_hPin(INVALID_HANDLE_VALUE),
m_PinId(PinId),
m_MemAllocator(0),
m_IoCount(0),
m_Communication(Communication),
m_Pin(0),
m_ReadOnly(0),
m_InterfaceHandler(0),
m_KsAllocatorEx(0),
m_PipeAllocatorFlag(0),
m_bPinBusCacheInitialized(0),
m_FilterName(0)
{
ZeroMemory(m_FramingProp, sizeof(m_FramingProp));
ZeroMemory(m_FramingEx, sizeof(m_FramingEx));
}
HRESULT
STDMETHODCALLTYPE
CInputPin::QueryInterface(
@@ -205,7 +269,44 @@ CInputPin::QueryInterface(
reinterpret_cast<IKsPinEx*>(*Output)->AddRef();
return NOERROR;
}
else if (IsEqualGUID(refiid, IID_IKsPinPipe))
{
*Output = (IKsPinPipe*)(this);
reinterpret_cast<IKsPinPipe*>(*Output)->AddRef();
return NOERROR;
}
else if (IsEqualGUID(refiid, IID_IKsPinFactory))
{
*Output = (IKsPinFactory*)(this);
reinterpret_cast<IKsPinFactory*>(*Output)->AddRef();
return NOERROR;
}
#if 0
else if (IsEqualGUID(refiid, IID_IStreamBuilder))
{
*Output = (IStreamBuilder*)(this);
reinterpret_cast<IStreamBuilder*>(*Output)->AddRef();
return NOERROR;
}
#endif
else if (IsEqualGUID(refiid, IID_IKsAggregateControl))
{
*Output = (IKsAggregateControl*)(this);
reinterpret_cast<IKsAggregateControl*>(*Output)->AddRef();
return NOERROR;
}
else if (IsEqualGUID(refiid, IID_IQualityControl))
{
*Output = (IQualityControl*)(this);
reinterpret_cast<IQualityControl*>(*Output)->AddRef();
return NOERROR;
}
else if (IsEqualGUID(refiid, IID_ISpecifyPropertyPages))
{
*Output = (ISpecifyPropertyPages*)(this);
reinterpret_cast<ISpecifyPropertyPages*>(*Output)->AddRef();
return NOERROR;
}
WCHAR Buffer[MAX_PATH];
LPOLESTR lpstr;
@@ -216,6 +317,249 @@ CInputPin::QueryInterface(
return E_NOINTERFACE;
}
//-------------------------------------------------------------------
// IQualityControl interface
//
HRESULT
STDMETHODCALLTYPE
CInputPin::Notify(
IBaseFilter *pSelf,
Quality q)
{
OutputDebugStringW(L"CInputPin::Notify NotImplemented\n");
return E_NOTIMPL;
}
HRESULT
STDMETHODCALLTYPE
CInputPin::SetSink(
IQualityControl *piqc)
{
OutputDebugStringW(L"CInputPin::SetSink NotImplemented\n");
return E_NOTIMPL;
}
//-------------------------------------------------------------------
// IKsAggregateControl interface
//
HRESULT
STDMETHODCALLTYPE
CInputPin::KsAddAggregate(
IN REFGUID AggregateClass)
{
OutputDebugStringW(L"CInputPin::KsAddAggregate NotImplemented\n");
return E_NOTIMPL;
}
HRESULT
STDMETHODCALLTYPE
CInputPin::KsRemoveAggregate(
REFGUID AggregateClass)
{
OutputDebugStringW(L"CInputPin::KsRemoveAggregate NotImplemented\n");
return E_NOTIMPL;
}
//-------------------------------------------------------------------
// IStreamBuilder
//
HRESULT
STDMETHODCALLTYPE
CInputPin::Render(
IPin *ppinOut,
IGraphBuilder *pGraph)
{
OutputDebugStringW(L"CInputPin::Render\n");
return S_OK;
}
HRESULT
STDMETHODCALLTYPE
CInputPin::Backout(
IPin *ppinOut,
IGraphBuilder *pGraph)
{
OutputDebugStringW(L"CInputPin::Backout\n");
return S_OK;
}
//-------------------------------------------------------------------
// IKsPinFactory
//
HRESULT
STDMETHODCALLTYPE
CInputPin::KsPinFactory(
ULONG* PinFactory)
{
OutputDebugStringW(L"CInputPin::KsPinFactory\n");
*PinFactory = m_PinId;
return S_OK;
}
//-------------------------------------------------------------------
// IKsPinPipe
//
HRESULT
STDMETHODCALLTYPE
CInputPin::KsGetPinFramingCache(
PKSALLOCATOR_FRAMING_EX *FramingEx,
PFRAMING_PROP FramingProp,
FRAMING_CACHE_OPS Option)
{
if (Option > Framing_Cache_Write || Option < Framing_Cache_ReadLast)
{
// invalid argument
return E_INVALIDARG;
}
// get framing properties
*FramingProp = m_FramingProp[Option];
*FramingEx = m_FramingEx[Option];
return NOERROR;
}
HRESULT
STDMETHODCALLTYPE
CInputPin::KsSetPinFramingCache(
PKSALLOCATOR_FRAMING_EX FramingEx,
PFRAMING_PROP FramingProp,
FRAMING_CACHE_OPS Option)
{
ULONG Index;
ULONG RefCount = 0;
if (m_FramingEx[Option])
{
for(Index = 1; Index < 4; Index++)
{
if (m_FramingEx[Index] == m_FramingEx[Option])
RefCount++;
}
if (RefCount == 1)
{
// existing framing is only used once
CoTaskMemFree(m_FramingEx[Option]);
}
}
// store framing
m_FramingEx[Option] = FramingEx;
m_FramingProp[Option] = *FramingProp;
return S_OK;
}
IPin*
STDMETHODCALLTYPE
CInputPin::KsGetConnectedPin()
{
return m_Pin;
}
IKsAllocatorEx*
STDMETHODCALLTYPE
CInputPin::KsGetPipe(
KSPEEKOPERATION Operation)
{
if (Operation == KsPeekOperation_AddRef)
{
if (m_KsAllocatorEx)
m_KsAllocatorEx->AddRef();
}
return m_KsAllocatorEx;
}
HRESULT
STDMETHODCALLTYPE
CInputPin::KsSetPipe(
IKsAllocatorEx *KsAllocator)
{
if (KsAllocator)
KsAllocator->AddRef();
if (m_KsAllocatorEx)
m_KsAllocatorEx->Release();
m_KsAllocatorEx = KsAllocator;
return NOERROR;
}
ULONG
STDMETHODCALLTYPE
CInputPin::KsGetPipeAllocatorFlag()
{
return m_PipeAllocatorFlag;
}
HRESULT
STDMETHODCALLTYPE
CInputPin::KsSetPipeAllocatorFlag(
ULONG Flag)
{
m_PipeAllocatorFlag = Flag;
return NOERROR;
}
GUID
STDMETHODCALLTYPE
CInputPin::KsGetPinBusCache()
{
if (!m_bPinBusCacheInitialized)
{
CopyMemory(&m_PinBusCache, &m_Medium.Set, sizeof(GUID));
m_bPinBusCacheInitialized = TRUE;
}
return m_PinBusCache;
}
HRESULT
STDMETHODCALLTYPE
CInputPin::KsSetPinBusCache(
GUID Bus)
{
CopyMemory(&m_PinBusCache, &Bus, sizeof(GUID));
return NOERROR;
}
PWCHAR
STDMETHODCALLTYPE
CInputPin::KsGetPinName()
{
return (PWCHAR)m_PinName;
}
PWCHAR
STDMETHODCALLTYPE
CInputPin::KsGetFilterName()
{
return m_FilterName;
}
//-------------------------------------------------------------------
// ISpecifyPropertyPages
//
HRESULT
STDMETHODCALLTYPE
CInputPin::GetPages(CAUUID *pPages)
{
if (!pPages)
return E_POINTER;
pPages->cElems = 0;
pPages->pElems = NULL;
return S_OK;
}
//-------------------------------------------------------------------
// IMemInputPin
@@ -299,7 +643,6 @@ CInputPin::ReceiveCanBlock( void)
return S_FALSE;
}
//-------------------------------------------------------------------
// IKsPin
//
@@ -641,16 +984,17 @@ CInputPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt)
if (m_Pin)
{
// already connected
return VFW_E_ALREADY_CONNECTED;
}
// first check format
hr = CheckFormat(pmt);
if (FAILED(hr))
{
// format is not supported
return hr;
if (FAILED(CheckFormat(pmt)))
return hr;
}
hr = CreatePin(pmt);
if (FAILED(hr))
@@ -658,9 +1002,8 @@ CInputPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt)
return hr;
}
//FIXME create pin
m_Pin = pConnector;
m_Pin->AddRef();
m_Pin = pConnector;
m_Pin->AddRef();
return S_OK;
}
@@ -828,6 +1171,7 @@ CInputPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
return E_NOTIMPL;
}
//-------------------------------------------------------------------
HRESULT
STDMETHODCALLTYPE
@@ -900,6 +1244,7 @@ CInputPin::CreatePin(
PKSMULTIPLE_ITEM InterfaceList;
PKSPIN_MEDIUM Medium;
PKSPIN_INTERFACE Interface;
IKsInterfaceHandler * InterfaceHandler;
HRESULT hr;
// query for pin medium
@@ -938,8 +1283,43 @@ CInputPin::CreatePin(
Interface = &StandardPinInterface;
}
// now create pin
hr = CreatePinHandle(Medium, Interface, pmt);
if (m_Communication != KSPIN_COMMUNICATION_BRIDGE && m_Communication != KSPIN_COMMUNICATION_NONE)
{
// now load the IKsInterfaceHandler plugin
hr = CoCreateInstance(Interface->Set, NULL, CLSCTX_INPROC_SERVER, IID_IKsInterfaceHandler, (void**)&InterfaceHandler);
if (FAILED(hr))
{
// failed to load interface handler plugin
OutputDebugStringW(L"CInputPin::CreatePin failed to load InterfaceHandlerPlugin\n");
CoTaskMemFree(MediumList);
CoTaskMemFree(InterfaceList);
return hr;
}
// now set the pin
hr = InterfaceHandler->KsSetPin((IKsPin*)this);
if (FAILED(hr))
{
// failed to load interface handler plugin
OutputDebugStringW(L"CInputPin::CreatePin failed to initialize InterfaceHandlerPlugin\n");
InterfaceHandler->Release();
CoTaskMemFree(MediumList);
CoTaskMemFree(InterfaceList);
return hr;
}
// store interface handler
m_InterfaceHandler = InterfaceHandler;
// now create pin
hr = CreatePinHandle(Medium, Interface, pmt);
if (FAILED(hr))
{
m_InterfaceHandler->Release();
m_InterfaceHandler = InterfaceHandler;
}
}
// free medium / interface / dataformat
CoTaskMemFree(MediumList);
+363 -18
View File
@@ -35,14 +35,27 @@ public:
HRESULT STDMETHODCALLTYPE KsProcessMediaSamples(IKsDataTypeHandler *KsDataTypeHandler, IMediaSample** SampleList, PLONG SampleCount, KSIOOPERATION IoOperation, PKSSTREAM_SEGMENT *StreamSegment);
HRESULT STDMETHODCALLTYPE KsCompleteIo(PKSSTREAM_SEGMENT StreamSegment);
CKsInterfaceHandler() : m_Ref(0), m_Handle(NULL){};
CKsInterfaceHandler() : m_Ref(0), m_Handle(NULL), m_Pin(0){};
virtual ~CKsInterfaceHandler(){};
protected:
LONG m_Ref;
HANDLE m_Handle;
IKsPinEx * m_Pin;
};
typedef struct
{
KSSTREAM_SEGMENT StreamSegment;
IMediaSample * MediaSample[64];
ULONG SampleCount;
ULONG ExtendedSize;
PKSSTREAM_HEADER StreamHeader;
OVERLAPPED Overlapped;
}KSSTREAM_SEGMENT_EXT, *PKSSTREAM_SEGMENT_EXT;
HRESULT
STDMETHODCALLTYPE
CKsInterfaceHandler::QueryInterface(
@@ -66,22 +79,43 @@ CKsInterfaceHandler::KsSetPin(
{
HRESULT hr;
IKsObject * KsObject;
IKsPinEx * Pin;
// check if IKsObject is supported
hr = KsPin->QueryInterface(IID_IKsObject, (void**)&KsObject);
// get IKsPinEx interface
hr = KsPin->QueryInterface(IID_IKsPinEx, (void**)&Pin);
if (SUCCEEDED(hr))
{
// get pin handle
m_Handle = KsObject->KsGetObjectHandle();
// check if IKsObject is supported
hr = KsPin->QueryInterface(IID_IKsObject, (void**)&KsObject);
// release IKsObject interface
KsObject->Release();
if (!m_Handle)
if (SUCCEEDED(hr))
{
// expected a file handle
return E_UNEXPECTED;
// get pin handle
m_Handle = KsObject->KsGetObjectHandle();
// release IKsObject interface
KsObject->Release();
if (!m_Handle)
{
// expected a file handle
hr = E_UNEXPECTED;
Pin->Release();
}
else
{
if (m_Pin)
{
// release old interface
m_Pin->Release();
}
m_Pin = Pin;
}
}
else
{
//release IKsPinEx interface
Pin->Release();
}
}
@@ -96,19 +130,330 @@ CKsInterfaceHandler::KsProcessMediaSamples(
IMediaSample** SampleList,
PLONG SampleCount,
KSIOOPERATION IoOperation,
PKSSTREAM_SEGMENT *StreamSegment)
PKSSTREAM_SEGMENT *OutStreamSegment)
{
OutputDebugString("UNIMPLEMENTED\n");
return E_NOTIMPL;
PKSSTREAM_SEGMENT_EXT StreamSegment;
ULONG ExtendedSize, Index, BytesReturned;
HRESULT hr = S_OK;
OutputDebugString("CKsInterfaceHandler::KsProcessMediaSamples\n");
// sanity check
assert(*SampleCount);
if (*SampleCount == 0 || *SampleCount < 0)
return E_FAIL;
// zero stream segment
*OutStreamSegment = NULL;
// allocate stream segment
StreamSegment = (PKSSTREAM_SEGMENT_EXT)CoTaskMemAlloc(sizeof(KSSTREAM_SEGMENT_EXT));
if (!StreamSegment)
return E_OUTOFMEMORY;
// zero stream segment
ZeroMemory(StreamSegment, sizeof(KSSTREAM_SEGMENT_EXT));
//allocate event
StreamSegment->StreamSegment.CompletionEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!StreamSegment->StreamSegment.CompletionEvent)
{
// failed to create event
CoTaskMemFree(StreamSegment);
return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError());
}
// increase our own reference count
AddRef();
// setup stream segment
StreamSegment->StreamSegment.KsDataTypeHandler = KsDataTypeHandler;
StreamSegment->StreamSegment.KsInterfaceHandler = (IKsInterfaceHandler*)this;
StreamSegment->StreamSegment.IoOperation = IoOperation;
StreamSegment->Overlapped.hEvent = StreamSegment->StreamSegment.CompletionEvent;
// ge extension size
ExtendedSize = 0;
if (KsDataTypeHandler)
{
// query extension size
KsDataTypeHandler->KsQueryExtendedSize(&ExtendedSize);
if (ExtendedSize)
{
// increment reference count
KsDataTypeHandler->AddRef();
}
else
{
// no need for the datatype handler
StreamSegment->StreamSegment.KsDataTypeHandler = NULL;
}
}
StreamSegment->ExtendedSize = ExtendedSize;
StreamSegment->SampleCount = (ULONG)*SampleCount;
// calculate stream header size count
ULONG StreamHeaderSize = StreamSegment->SampleCount * (sizeof(KSSTREAM_HEADER) + ExtendedSize);
// allocate stream header
StreamSegment->StreamHeader = (PKSSTREAM_HEADER)CoTaskMemAlloc(StreamHeaderSize);
if (!StreamSegment->StreamHeader)
{
// not enough memory
CloseHandle(StreamSegment->StreamSegment.CompletionEvent);
if (StreamSegment->StreamSegment.KsDataTypeHandler)
StreamSegment->StreamSegment.KsDataTypeHandler->Release();
// free stream segment
CoTaskMemFree(StreamSegment);
//release our reference count
Release();
return E_OUTOFMEMORY;
}
// zero stream headers
ZeroMemory(StreamSegment->StreamHeader, StreamHeaderSize);
PKSSTREAM_HEADER CurStreamHeader = StreamSegment->StreamHeader;
// initialize all stream headers
for(Index = 0; Index < StreamSegment->SampleCount; Index++)
{
if (ExtendedSize)
{
// initialize extended size
hr = KsDataTypeHandler->KsPrepareIoOperation(SampleList[Index], (CurStreamHeader + 1), IoOperation);
// sanity check
assert(hr == NOERROR);
}
// query for IMediaSample2 interface
IMediaSample2 * MediaSample;
AM_SAMPLE2_PROPERTIES Properties;
hr = SampleList[Index]->QueryInterface(IID_IMediaSample2, (void**)&MediaSample);
if (SUCCEEDED(hr))
{
//get properties
hr = MediaSample->GetProperties(sizeof(AM_SAMPLE2_PROPERTIES), (BYTE*)&Properties);
//release IMediaSample2 interface
MediaSample->Release();
}
else
{
// get properties
hr = SampleList[Index]->GetPointer((BYTE**)&Properties.pbBuffer);
assert(hr == NOERROR);
hr = SampleList[Index]->GetTime(&Properties.tStart, &Properties.tStop);
assert(hr == NOERROR);
Properties.dwSampleFlags = 0;
if (SampleList[Index]->IsDiscontinuity() == S_OK)
Properties.dwSampleFlags |= AM_SAMPLE_DATADISCONTINUITY;
if (SampleList[Index]->IsPreroll() == S_OK)
Properties.dwSampleFlags |= AM_SAMPLE_PREROLL;
if (SampleList[Index]->IsSyncPoint() == S_OK)
Properties.dwSampleFlags |= AM_SAMPLE_SPLICEPOINT;
}
WCHAR Buffer[100];
swprintf(Buffer, L"BufferLength %lu Property Buffer %p ExtendedSize %u lActual %u\n", Properties.cbBuffer, Properties.pbBuffer, ExtendedSize, Properties.lActual);
OutputDebugStringW(Buffer);
CurStreamHeader->Size = sizeof(KSSTREAM_HEADER) + ExtendedSize;
CurStreamHeader->PresentationTime.Denominator = 1;
CurStreamHeader->PresentationTime.Numerator = 1;
CurStreamHeader->FrameExtent = Properties.cbBuffer;
CurStreamHeader->Data = Properties.pbBuffer;
if (IoOperation == KsIoOperation_Write)
{
// set flags
CurStreamHeader->OptionsFlags = Properties.dwSampleFlags;
CurStreamHeader->DataUsed = Properties.lActual;
// increment reference count
SampleList[Index]->AddRef();
}
// store sample in stream segment
StreamSegment->MediaSample[Index] = SampleList[Index];
// move to next header
CurStreamHeader = (PKSSTREAM_HEADER)((ULONG_PTR)CurStreamHeader + CurStreamHeader->Size);
}
// submit to device
m_Pin->KsIncrementPendingIoCount();
if (DeviceIoControl(m_Handle,
IoOperation == KsIoOperation_Write ? IOCTL_KS_WRITE_STREAM : IOCTL_KS_READ_STREAM,
NULL, 0,
StreamSegment->StreamHeader,
StreamHeaderSize,
&BytesReturned,
&StreamSegment->Overlapped))
{
// signal completion
SetEvent(StreamSegment->StreamSegment.CompletionEvent);
hr = S_OK;
*OutStreamSegment = (PKSSTREAM_SEGMENT)StreamSegment;
}
else
{
if (GetLastError() == ERROR_IO_PENDING)
{
*OutStreamSegment = (PKSSTREAM_SEGMENT)StreamSegment;
hr = S_OK;
}
}
return hr;
}
HRESULT
STDMETHODCALLTYPE
CKsInterfaceHandler::KsCompleteIo(
PKSSTREAM_SEGMENT StreamSegment)
PKSSTREAM_SEGMENT InStreamSegment)
{
OutputDebugString("UNIMPLEMENTED\n");
return E_NOTIMPL;
PKSSTREAM_SEGMENT_EXT StreamSegment;
PKSSTREAM_HEADER CurStreamHeader;
DWORD dwError = ERROR_SUCCESS, BytesReturned;
BOOL bOverlapped;
ULONG Index;
HRESULT hr;
IMediaSample2 * MediaSample;
AM_SAMPLE2_PROPERTIES Properties;
REFERENCE_TIME Start, Stop;
OutputDebugStringW(L"CKsInterfaceHandler::KsCompleteIo\n");
// get private stream segment
StreamSegment = (PKSSTREAM_SEGMENT_EXT)InStreamSegment;
// get result
bOverlapped = GetOverlappedResult(m_Handle, &StreamSegment->Overlapped, &BytesReturned, FALSE);
dwError = GetLastError();
CurStreamHeader = StreamSegment->StreamHeader;
//iterate through all stream headers
for(Index = 0; Index < StreamSegment->SampleCount; Index++)
{
if (!bOverlapped)
{
// operation failed
m_Pin->KsNotifyError(StreamSegment->MediaSample[Index], MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, dwError));
}
// query IMediaSample2 interface
hr = StreamSegment->MediaSample[Index]->QueryInterface(IID_IMediaSample2, (void**)&MediaSample);
if (SUCCEEDED(hr))
{
// media sample properties
hr = MediaSample->GetProperties(sizeof(AM_SAMPLE2_PROPERTIES), (BYTE*)&Properties);
if (SUCCEEDED(hr))
{
//update media sample properties
Properties.dwTypeSpecificFlags = CurStreamHeader->TypeSpecificFlags;
Properties.dwSampleFlags |= (CurStreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TIMEDISCONTINUITY);
MediaSample->SetProperties(sizeof(AM_SAMPLE2_PROPERTIES), (BYTE*)&Properties);
}
// release IMediaSample2 interface
MediaSample->Release();
}
// was an extended header used
if (StreamSegment->ExtendedSize)
{
// unprepare stream header extension
StreamSegment->StreamSegment.KsDataTypeHandler->KsCompleteIoOperation(StreamSegment->MediaSample[Index], (CurStreamHeader + 1), StreamSegment->StreamSegment.IoOperation, bOverlapped == FALSE);
}
Start = 0;
Stop = 0;
if (bOverlapped && StreamSegment->StreamSegment.IoOperation == KsIoOperation_Read)
{
// update common media sample details
StreamSegment->MediaSample[Index]->SetSyncPoint((CurStreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_SPLICEPOINT));
StreamSegment->MediaSample[Index]->SetPreroll((CurStreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_PREROLL));
StreamSegment->MediaSample[Index]->SetDiscontinuity((CurStreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_DATADISCONTINUITY));
if (CurStreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TIMEVALID)
{
// use valid timestamp
Start = CurStreamHeader->PresentationTime.Time;
if (CurStreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_DURATIONVALID)
{
Stop = CurStreamHeader->PresentationTime.Time + CurStreamHeader->Duration;
}
}
}
// now set time
hr = StreamSegment->MediaSample[Index]->SetTime(&Start, &Stop);
if (FAILED(hr))
{
// use start time
StreamSegment->MediaSample[Index]->SetTime(&Start, &Start);
}
// set valid data length
StreamSegment->MediaSample[Index]->SetActualDataLength(CurStreamHeader->DataUsed);
if (StreamSegment->StreamSegment.IoOperation == KsIoOperation_Read)
{
if (bOverlapped)
{
// deliver sample
m_Pin->KsDeliver(StreamSegment->MediaSample[Index], CurStreamHeader->OptionsFlags);
}
}
else if (StreamSegment->StreamSegment.IoOperation == KsIoOperation_Write)
{
// release media sample reference
StreamSegment->MediaSample[Index]->Release();
}
CurStreamHeader = (PKSSTREAM_HEADER)((ULONG_PTR)CurStreamHeader + CurStreamHeader->Size);
}
// delete stream headers
CoTaskMemFree(StreamSegment->StreamHeader);
if (StreamSegment->StreamSegment.KsDataTypeHandler)
{
// release reference
StreamSegment->StreamSegment.KsDataTypeHandler->Release();
}
// decrement pending i/o count
m_Pin->KsDecrementPendingIoCount();
//notify of completion
m_Pin->KsMediaSamplesCompleted(InStreamSegment);
//destroy stream segment
CoTaskMemFree(StreamSegment);
//release reference to ourselves
Release();
// done
// Event handle is closed by caller
return S_OK;
}
HRESULT
+1 -1
View File
@@ -13,10 +13,10 @@
const GUID CLSID_KsClockForwarder = {0x877e4351, 0x6fea, 0x11d0, {0xb8, 0x63, 0x00, 0xaa, 0x00, 0xa2, 0x16, 0xa1}};
const GUID CLSID_KsQualityForwarder = {0xe05592e4, 0xc0b5, 0x11d0, {0xa4, 0x39, 0x00, 0xa0, 0xc9, 0x22, 0x31, 0x96}};
const GUID CLSID_KsIBasicAudioInterfaceHandler = {0xb9f8ac3e, 0x0f71, 0x11d2, {0xb7, 0x2c, 0x00, 0xc0, 0x4f, 0xb6, 0xbd, 0x3d}};
#ifndef _MSC_VER
const GUID CLSID_KsIBasicAudioInterfaceHandler = {0xb9f8ac3e, 0x0f71, 0x11d2, {0xb7, 0x2c, 0x00, 0xc0, 0x4f, 0xb6, 0xbd, 0x3d}};
const GUID KSPROPSETID_Pin = {0x8C134960, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}};
const GUID KSINTERFACESETID_Standard = {STATIC_KSINTERFACESETID_Standard};
const GUID CLSID_Proxy = {0x17CCA71B, 0xECD7, 0x11D0, {0xB9, 0x08, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
+1
View File
@@ -33,6 +33,7 @@
<file>interface.cpp</file>
<file>ksproxy.cpp</file>
<file>ksproxy.rc</file>
<file>node.cpp</file>
<file>output_pin.cpp</file>
<file>proxy.cpp</file>
<file>qualityforward.cpp</file>
+157
View File
@@ -0,0 +1,157 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS WDM Streaming ActiveMovie Proxy
* FILE: dll/directx/ksproxy/node.cpp
* PURPOSE: Control Node
*
* PROGRAMMERS: Johannes Anderwald ([email protected])
*/
#include "precomp.h"
class CKsNode : public IKsControl
{
public:
STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
STDMETHODIMP_(ULONG) AddRef()
{
InterlockedIncrement(&m_Ref);
return m_Ref;
}
STDMETHODIMP_(ULONG) Release()
{
InterlockedDecrement(&m_Ref);
if (!m_Ref)
{
delete this;
return 0;
}
return m_Ref;
}
//IKsControl
HRESULT STDMETHODCALLTYPE KsProperty(PKSPROPERTY Property, ULONG PropertyLength, LPVOID PropertyData, ULONG DataLength, ULONG* BytesReturned);
HRESULT STDMETHODCALLTYPE KsMethod(PKSMETHOD Method, ULONG MethodLength, LPVOID MethodData, ULONG DataLength, ULONG* BytesReturned);
HRESULT STDMETHODCALLTYPE KsEvent(PKSEVENT Event, ULONG EventLength, LPVOID EventData, ULONG DataLength, ULONG* BytesReturned);
CKsNode(IUnknown * pUnkOuter, HANDLE Handle) : m_Ref(0), m_pUnkOuter(pUnkOuter), m_Handle(Handle){};
virtual ~CKsNode()
{
CloseHandle(m_Handle);
};
protected:
LONG m_Ref;
IUnknown * m_pUnkOuter;
HANDLE m_Handle;
};
HRESULT
STDMETHODCALLTYPE
CKsNode::QueryInterface(
IN REFIID refiid,
OUT PVOID* Output)
{
if (IsEqualGUID(refiid, IID_IUnknown) ||
IsEqualGUID(refiid, IID_IKsControl))
{
*Output = PVOID(this);
reinterpret_cast<IUnknown*>(*Output)->AddRef();
return NOERROR;
}
return E_NOINTERFACE;
}
//-------------------------------------------------------------------
// IKsControl
//
HRESULT
STDMETHODCALLTYPE
CKsNode::KsProperty(
PKSPROPERTY Property,
ULONG PropertyLength,
LPVOID PropertyData,
ULONG DataLength,
ULONG* BytesReturned)
{
assert(m_Handle != 0);
return KsSynchronousDeviceControl(m_Handle, IOCTL_KS_PROPERTY, (PVOID)Property, PropertyLength, (PVOID)PropertyData, DataLength, BytesReturned);
}
HRESULT
STDMETHODCALLTYPE
CKsNode::KsMethod(
PKSMETHOD Method,
ULONG MethodLength,
LPVOID MethodData,
ULONG DataLength,
ULONG* BytesReturned)
{
assert(m_Handle != 0);
return KsSynchronousDeviceControl(m_Handle, IOCTL_KS_METHOD, (PVOID)Method, MethodLength, (PVOID)MethodData, DataLength, BytesReturned);
}
HRESULT
STDMETHODCALLTYPE
CKsNode::KsEvent(
PKSEVENT Event,
ULONG EventLength,
LPVOID EventData,
ULONG DataLength,
ULONG* BytesReturned)
{
assert(m_Handle != 0);
if (EventLength)
return KsSynchronousDeviceControl(m_Handle, IOCTL_KS_ENABLE_EVENT, (PVOID)Event, EventLength, (PVOID)EventData, DataLength, BytesReturned);
else
return KsSynchronousDeviceControl(m_Handle, IOCTL_KS_DISABLE_EVENT, (PVOID)Event, EventLength, NULL, 0, BytesReturned);
}
HRESULT
WINAPI
CKsNode_Constructor(
IUnknown * pUnkOuter,
HANDLE ParentHandle,
ULONG NodeId,
ACCESS_MASK DesiredAccess,
REFIID riid,
LPVOID * ppv)
{
HRESULT hr;
HANDLE handle;
KSNODE_CREATE NodeCreate;
OutputDebugStringW(L"CKsNode_Constructor\n");
//setup request
NodeCreate.CreateFlags = 0;
NodeCreate.Node = NodeId;
hr = KsCreateTopologyNode(ParentHandle, &NodeCreate, DesiredAccess, &handle);
if (hr != NOERROR)
{
OutputDebugString("CKsNode_Constructor failed to open device\n");
return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, hr);
}
CKsNode * quality = new CKsNode(pUnkOuter, handle);
if (!quality)
{
// free clock handle
CloseHandle(handle);
return E_OUTOFMEMORY;
}
if (FAILED(quality->QueryInterface(riid, ppv)))
{
/* not supported */
delete quality;
return E_NOINTERFACE;
}
return NOERROR;
}
+760 -23
View File
@@ -1,33 +1,29 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS WDM Streaming ActiveMovie Proxy
* FILE: dll/directx/ksproxy/input_cpp.cpp
* PURPOSE: InputPin of Proxy Filter
* FILE: dll/directx/ksproxy/output_pin.cpp
* PURPOSE: OutputPin of Proxy Filter
*
* PROGRAMMERS: Johannes Anderwald ([email protected])
*/
#include "precomp.h"
#ifndef _MSC_VER
const GUID IID_IKsPinFactory = {0xCD5EBE6BL, 0x8B6E, 0x11D1, {0x8A, 0xE0, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
#endif
class COutputPin : public IPin,
public IKsObject,
public IKsPropertySet,
public IStreamBuilder,
public IKsPinFactory,
public ISpecifyPropertyPages,
// public IKsPinPipe,
public IKsControl
/*
public IQualityControl,
public IKsPinEx,
public IKsAggregateControl
public IMediaSeeking,
public IAMStreamConfig,
public IMemAllocatorNotifyCallbackTemp
*/
public IKsPinEx,
public IKsPinPipe,
public IKsControl,
public IKsAggregateControl,
public IQualityControl,
public IMediaSeeking,
public IAMBufferNegotiation,
public IAMStreamConfig,
public IMemAllocatorNotifyCallbackTemp
{
public:
STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
@@ -48,6 +44,23 @@ public:
return m_Ref;
}
//IKsPin
HRESULT STDMETHODCALLTYPE KsQueryMediums(PKSMULTIPLE_ITEM* MediumList);
HRESULT STDMETHODCALLTYPE KsQueryInterfaces(PKSMULTIPLE_ITEM* InterfaceList);
HRESULT STDMETHODCALLTYPE KsCreateSinkPinHandle(KSPIN_INTERFACE& Interface, KSPIN_MEDIUM& Medium);
HRESULT STDMETHODCALLTYPE KsGetCurrentCommunication(KSPIN_COMMUNICATION *Communication, KSPIN_INTERFACE *Interface, KSPIN_MEDIUM *Medium);
HRESULT STDMETHODCALLTYPE KsPropagateAcquire();
HRESULT STDMETHODCALLTYPE KsDeliver(IMediaSample* Sample, ULONG Flags);
HRESULT STDMETHODCALLTYPE KsMediaSamplesCompleted(PKSSTREAM_SEGMENT StreamSegment);
IMemAllocator * STDMETHODCALLTYPE KsPeekAllocator(KSPEEKOPERATION Operation);
HRESULT STDMETHODCALLTYPE KsReceiveAllocator(IMemAllocator *MemAllocator);
HRESULT STDMETHODCALLTYPE KsRenegotiateAllocator();
LONG STDMETHODCALLTYPE KsIncrementPendingIoCount();
LONG STDMETHODCALLTYPE KsDecrementPendingIoCount();
HRESULT STDMETHODCALLTYPE KsQualityNotify(ULONG Proportion, REFERENCE_TIME TimeDelta);
// IKsPinEx
VOID STDMETHODCALLTYPE KsNotifyError(IMediaSample* Sample, HRESULT hr);
//IKsPinPipe
HRESULT STDMETHODCALLTYPE KsGetPinFramingCache(PKSALLOCATOR_FRAMING_EX *FramingEx, PFRAMING_PROP FramingProp, FRAMING_CACHE_OPS Option);
HRESULT STDMETHODCALLTYPE KsSetPinFramingCache(PKSALLOCATOR_FRAMING_EX FramingEx, PFRAMING_PROP FramingProp, FRAMING_CACHE_OPS Option);
@@ -101,6 +114,46 @@ public:
//IKsPinFactory
HRESULT STDMETHODCALLTYPE KsPinFactory(ULONG* PinFactory);
//IKsAggregateControl
HRESULT STDMETHODCALLTYPE KsAddAggregate(IN REFGUID AggregateClass);
HRESULT STDMETHODCALLTYPE KsRemoveAggregate(REFGUID AggregateClass);
//IQualityControl
HRESULT STDMETHODCALLTYPE Notify(IBaseFilter *pSelf, Quality q);
HRESULT STDMETHODCALLTYPE SetSink(IQualityControl *piqc);
//IMediaSeeking
HRESULT STDMETHODCALLTYPE GetCapabilities(DWORD *pCapabilities);
HRESULT STDMETHODCALLTYPE CheckCapabilities(DWORD *pCapabilities);
HRESULT STDMETHODCALLTYPE IsFormatSupported(const GUID *pFormat);
HRESULT STDMETHODCALLTYPE QueryPreferredFormat(GUID *pFormat);
HRESULT STDMETHODCALLTYPE GetTimeFormat(GUID *pFormat);
HRESULT STDMETHODCALLTYPE IsUsingTimeFormat(const GUID *pFormat);
HRESULT STDMETHODCALLTYPE SetTimeFormat(const GUID *pFormat);
HRESULT STDMETHODCALLTYPE GetDuration(LONGLONG *pDuration);
HRESULT STDMETHODCALLTYPE GetStopPosition(LONGLONG *pStop);
HRESULT STDMETHODCALLTYPE GetCurrentPosition(LONGLONG *pCurrent);
HRESULT STDMETHODCALLTYPE ConvertTimeFormat(LONGLONG *pTarget, const GUID *pTargetFormat, LONGLONG Source, const GUID *pSourceFormat);
HRESULT STDMETHODCALLTYPE SetPositions(LONGLONG *pCurrent, DWORD dwCurrentFlags, LONGLONG *pStop, DWORD dwStopFlags);
HRESULT STDMETHODCALLTYPE GetPositions(LONGLONG *pCurrent, LONGLONG *pStop);
HRESULT STDMETHODCALLTYPE GetAvailable(LONGLONG *pEarliest, LONGLONG *pLatest);
HRESULT STDMETHODCALLTYPE SetRate(double dRate);
HRESULT STDMETHODCALLTYPE GetRate(double *pdRate);
HRESULT STDMETHODCALLTYPE GetPreroll(LONGLONG *pllPreroll);
//IAMBufferNegotiation
HRESULT STDMETHODCALLTYPE SuggestAllocatorProperties(const ALLOCATOR_PROPERTIES *pprop);
HRESULT STDMETHODCALLTYPE GetAllocatorProperties(ALLOCATOR_PROPERTIES *pprop);
//IAMStreamConfig
HRESULT STDMETHODCALLTYPE SetFormat(AM_MEDIA_TYPE *pmt);
HRESULT STDMETHODCALLTYPE GetFormat(AM_MEDIA_TYPE **ppmt);
HRESULT STDMETHODCALLTYPE GetNumberOfCapabilities(int *piCount, int *piSize);
HRESULT STDMETHODCALLTYPE GetStreamCaps(int iIndex, AM_MEDIA_TYPE **ppmt, BYTE *pSCC);
//IMemAllocatorNotifyCallbackTemp
HRESULT STDMETHODCALLTYPE NotifyRelease();
COutputPin(IBaseFilter * ParentFilter, LPCWSTR PinName, ULONG PinId);
virtual ~COutputPin();
@@ -112,6 +165,20 @@ protected:
ULONG m_PinId;
IKsObject * m_KsObjectParent;
IPin * m_Pin;
IKsAllocatorEx * m_KsAllocatorEx;
ULONG m_PipeAllocatorFlag;
BOOL m_bPinBusCacheInitialized;
GUID m_PinBusCache;
LPWSTR m_FilterName;
FRAMING_PROP m_FramingProp[4];
PKSALLOCATOR_FRAMING_EX m_FramingEx[4];
IMemAllocator * m_MemAllocator;
LONG m_IoCount;
KSPIN_COMMUNICATION m_Communication;
KSPIN_INTERFACE m_Interface;
KSPIN_MEDIUM m_Medium;
IMediaSeeking * m_FilterMediaSeeking;
};
COutputPin::~COutputPin()
@@ -123,13 +190,32 @@ COutputPin::~COutputPin()
COutputPin::COutputPin(
IBaseFilter * ParentFilter,
LPCWSTR PinName,
ULONG PinId) : m_Ref(0), m_ParentFilter(ParentFilter), m_PinName(PinName), m_hPin(0), m_PinId(PinId), m_KsObjectParent(0), m_Pin(0)
ULONG PinId) : m_Ref(0),
m_ParentFilter(ParentFilter),
m_PinName(PinName),
m_hPin(INVALID_HANDLE_VALUE),
m_PinId(PinId),
m_KsObjectParent(0),
m_Pin(0),
m_KsAllocatorEx(0),
m_PipeAllocatorFlag(0),
m_bPinBusCacheInitialized(0),
m_FilterName(0),
m_MemAllocator(0),
m_IoCount(0),
m_Communication(KSPIN_COMMUNICATION_NONE),
m_FilterMediaSeeking(0)
{
HRESULT hr;
hr = m_ParentFilter->QueryInterface(IID_IKsObject, (LPVOID*)&m_KsObjectParent);
assert(hr == S_OK);
hr = m_ParentFilter->QueryInterface(IID_IMediaSeeking, (LPVOID*)&m_FilterMediaSeeking);
assert(hr == S_OK);
ZeroMemory(m_FramingProp, sizeof(m_FramingProp));
ZeroMemory(m_FramingEx, sizeof(m_FramingEx));
};
HRESULT
@@ -142,50 +228,102 @@ COutputPin::QueryInterface(
if (IsEqualGUID(refiid, IID_IUnknown) ||
IsEqualGUID(refiid, IID_IPin))
{
OutputDebugStringW(L"COutputPin::QueryInterface IID_IPin\n");
*Output = PVOID(this);
reinterpret_cast<IUnknown*>(*Output)->AddRef();
return NOERROR;
}
else if (IsEqualGUID(refiid, IID_IKsObject))
{
OutputDebugStringW(L"COutputPin::QueryInterface IID_IKsObject\n");
*Output = (IKsObject*)(this);
reinterpret_cast<IKsObject*>(*Output)->AddRef();
return NOERROR;
}
else if (IsEqualGUID(refiid, IID_IKsPin) || IsEqualGUID(refiid, IID_IKsPinEx))
{
*Output = (IKsPinEx*)(this);
reinterpret_cast<IKsPinEx*>(*Output)->AddRef();
return NOERROR;
}
else if (IsEqualGUID(refiid, IID_IKsPinPipe))
{
*Output = (IKsPinPipe*)(this);
reinterpret_cast<IKsPinPipe*>(*Output)->AddRef();
return NOERROR;
}
else if (IsEqualGUID(refiid, IID_IKsAggregateControl))
{
*Output = (IKsAggregateControl*)(this);
reinterpret_cast<IKsAggregateControl*>(*Output)->AddRef();
return NOERROR;
}
else if (IsEqualGUID(refiid, IID_IQualityControl))
{
*Output = (IQualityControl*)(this);
reinterpret_cast<IQualityControl*>(*Output)->AddRef();
return NOERROR;
}
else if (IsEqualGUID(refiid, IID_IKsPropertySet))
{
OutputDebugStringW(L"COutputPin::QueryInterface IID_IKsPropertySet\n");
DebugBreak();
*Output = (IKsPropertySet*)(this);
reinterpret_cast<IKsPropertySet*>(*Output)->AddRef();
return NOERROR;
}
else if (IsEqualGUID(refiid, IID_IKsControl))
{
OutputDebugStringW(L"COutputPin::QueryInterface IID_IKsControl\n");
*Output = (IKsControl*)(this);
reinterpret_cast<IKsControl*>(*Output)->AddRef();
return NOERROR;
}
#if 0
else if (IsEqualGUID(refiid, IID_IStreamBuilder))
{
*Output = (IStreamBuilder*)(this);
reinterpret_cast<IStreamBuilder*>(*Output)->AddRef();
return NOERROR;
}
#endif
else if (IsEqualGUID(refiid, IID_IKsPinFactory))
{
OutputDebugStringW(L"COutputPin::QueryInterface IID_IKsPinFactory\n");
*Output = (IKsPinFactory*)(this);
reinterpret_cast<IKsPinFactory*>(*Output)->AddRef();
return NOERROR;
}
else if (IsEqualGUID(refiid, IID_ISpecifyPropertyPages))
{
OutputDebugStringW(L"COutputPin::QueryInterface IID_ISpecifyPropertyPages\n");
*Output = (ISpecifyPropertyPages*)(this);
reinterpret_cast<ISpecifyPropertyPages*>(*Output)->AddRef();
return NOERROR;
}
else if (IsEqualGUID(refiid, IID_IBaseFilter))
else if (IsEqualGUID(refiid, IID_IMediaSeeking))
{
OutputDebugStringW(L"COutputPin::QueryInterface query IID_IBaseFilter\n");
DebugBreak();
*Output = (IMediaSeeking*)(this);
reinterpret_cast<IMediaSeeking*>(*Output)->AddRef();
return NOERROR;
}
else if (IsEqualGUID(refiid, IID_IAMBufferNegotiation))
{
*Output = (IAMBufferNegotiation*)(this);
reinterpret_cast<IAMBufferNegotiation*>(*Output)->AddRef();
return NOERROR;
}
else if (IsEqualGUID(refiid, IID_IAMStreamConfig))
{
*Output = (IAMStreamConfig*)(this);
reinterpret_cast<IAMStreamConfig*>(*Output)->AddRef();
return NOERROR;
}
else if (IsEqualGUID(refiid, IID_IMemAllocatorNotifyCallbackTemp))
{
*Output = (IMemAllocatorNotifyCallbackTemp*)(this);
reinterpret_cast<IMemAllocatorNotifyCallbackTemp*>(*Output)->AddRef();
return NOERROR;
}
WCHAR Buffer[MAX_PATH];
@@ -198,6 +336,580 @@ COutputPin::QueryInterface(
return E_NOINTERFACE;
}
//-------------------------------------------------------------------
// IAMBufferNegotiation interface
//
HRESULT
STDMETHODCALLTYPE
COutputPin::SuggestAllocatorProperties(
const ALLOCATOR_PROPERTIES *pprop)
{
OutputDebugStringW(L"COutputPin::SuggestAllocatorProperties NotImplemented\n");
return E_NOTIMPL;
}
HRESULT
STDMETHODCALLTYPE
COutputPin::GetAllocatorProperties(
ALLOCATOR_PROPERTIES *pprop)
{
OutputDebugStringW(L"COutputPin::GetAllocatorProperties NotImplemented\n");
return E_NOTIMPL;
}
//-------------------------------------------------------------------
// IAMStreamConfig interface
//
HRESULT
STDMETHODCALLTYPE
COutputPin::SetFormat(
AM_MEDIA_TYPE *pmt)
{
OutputDebugStringW(L"COutputPin::SetFormat NotImplemented\n");
return E_NOTIMPL;
}
HRESULT
STDMETHODCALLTYPE
COutputPin::GetFormat(AM_MEDIA_TYPE **ppmt)
{
OutputDebugStringW(L"COutputPin::GetFormat NotImplemented\n");
return E_NOTIMPL;
}
HRESULT
STDMETHODCALLTYPE
COutputPin::GetNumberOfCapabilities(
int *piCount,
int *piSize)
{
OutputDebugStringW(L"COutputPin::GetNumberOfCapabilities NotImplemented\n");
return E_NOTIMPL;
}
HRESULT
STDMETHODCALLTYPE
COutputPin::GetStreamCaps(
int iIndex,
AM_MEDIA_TYPE **ppmt,
BYTE *pSCC)
{
OutputDebugStringW(L"COutputPin::GetStreamCaps NotImplemented\n");
return E_NOTIMPL;
}
//-------------------------------------------------------------------
// IMemAllocatorNotifyCallbackTemp interface
//
HRESULT
STDMETHODCALLTYPE
COutputPin::NotifyRelease()
{
OutputDebugStringW(L"COutputPin::NotifyRelease NotImplemented\n");
return E_NOTIMPL;
}
//-------------------------------------------------------------------
// IMediaSeeking interface
//
HRESULT
STDMETHODCALLTYPE
COutputPin::GetCapabilities(
DWORD *pCapabilities)
{
return m_FilterMediaSeeking->GetCapabilities(pCapabilities);
}
HRESULT
STDMETHODCALLTYPE
COutputPin::CheckCapabilities(
DWORD *pCapabilities)
{
return m_FilterMediaSeeking->CheckCapabilities(pCapabilities);
}
HRESULT
STDMETHODCALLTYPE
COutputPin::IsFormatSupported(
const GUID *pFormat)
{
return m_FilterMediaSeeking->IsFormatSupported(pFormat);
}
HRESULT
STDMETHODCALLTYPE
COutputPin::QueryPreferredFormat(
GUID *pFormat)
{
return m_FilterMediaSeeking->QueryPreferredFormat(pFormat);
}
HRESULT
STDMETHODCALLTYPE
COutputPin::GetTimeFormat(
GUID *pFormat)
{
return m_FilterMediaSeeking->GetTimeFormat(pFormat);
}
HRESULT
STDMETHODCALLTYPE
COutputPin::IsUsingTimeFormat(
const GUID *pFormat)
{
return m_FilterMediaSeeking->IsUsingTimeFormat(pFormat);
}
HRESULT
STDMETHODCALLTYPE
COutputPin::SetTimeFormat(
const GUID *pFormat)
{
return m_FilterMediaSeeking->SetTimeFormat(pFormat);
}
HRESULT
STDMETHODCALLTYPE
COutputPin::GetDuration(
LONGLONG *pDuration)
{
return m_FilterMediaSeeking->GetDuration(pDuration);
}
HRESULT
STDMETHODCALLTYPE
COutputPin::GetStopPosition(
LONGLONG *pStop)
{
return m_FilterMediaSeeking->GetStopPosition(pStop);
}
HRESULT
STDMETHODCALLTYPE
COutputPin::GetCurrentPosition(
LONGLONG *pCurrent)
{
return m_FilterMediaSeeking->GetCurrentPosition(pCurrent);
}
HRESULT
STDMETHODCALLTYPE
COutputPin::ConvertTimeFormat(
LONGLONG *pTarget,
const GUID *pTargetFormat,
LONGLONG Source,
const GUID *pSourceFormat)
{
return m_FilterMediaSeeking->ConvertTimeFormat(pTarget, pTargetFormat, Source, pSourceFormat);
}
HRESULT
STDMETHODCALLTYPE
COutputPin::SetPositions(
LONGLONG *pCurrent,
DWORD dwCurrentFlags,
LONGLONG *pStop,
DWORD dwStopFlags)
{
return m_FilterMediaSeeking->SetPositions(pCurrent, dwCurrentFlags, pStop, dwStopFlags);
}
HRESULT
STDMETHODCALLTYPE
COutputPin::GetPositions(
LONGLONG *pCurrent,
LONGLONG *pStop)
{
return m_FilterMediaSeeking->GetPositions(pCurrent, pStop);
}
HRESULT
STDMETHODCALLTYPE
COutputPin::GetAvailable(
LONGLONG *pEarliest,
LONGLONG *pLatest)
{
return m_FilterMediaSeeking->GetAvailable(pEarliest, pLatest);
}
HRESULT
STDMETHODCALLTYPE
COutputPin::SetRate(
double dRate)
{
return m_FilterMediaSeeking->SetRate(dRate);
}
HRESULT
STDMETHODCALLTYPE
COutputPin::GetRate(
double *pdRate)
{
return m_FilterMediaSeeking->GetRate(pdRate);
}
HRESULT
STDMETHODCALLTYPE
COutputPin::GetPreroll(
LONGLONG *pllPreroll)
{
return m_FilterMediaSeeking->GetPreroll(pllPreroll);
}
//-------------------------------------------------------------------
// IQualityControl interface
//
HRESULT
STDMETHODCALLTYPE
COutputPin::Notify(
IBaseFilter *pSelf,
Quality q)
{
OutputDebugStringW(L"COutputPin::Notify NotImplemented\n");
return E_NOTIMPL;
}
HRESULT
STDMETHODCALLTYPE
COutputPin::SetSink(
IQualityControl *piqc)
{
OutputDebugStringW(L"COutputPin::SetSink NotImplemented\n");
return E_NOTIMPL;
}
//-------------------------------------------------------------------
// IKsAggregateControl interface
//
HRESULT
STDMETHODCALLTYPE
COutputPin::KsAddAggregate(
IN REFGUID AggregateClass)
{
OutputDebugStringW(L"COutputPin::KsAddAggregate NotImplemented\n");
return E_NOTIMPL;
}
HRESULT
STDMETHODCALLTYPE
COutputPin::KsRemoveAggregate(
REFGUID AggregateClass)
{
OutputDebugStringW(L"COutputPin::KsRemoveAggregate NotImplemented\n");
return E_NOTIMPL;
}
//-------------------------------------------------------------------
// IKsPin
//
HRESULT
STDMETHODCALLTYPE
COutputPin::KsQueryMediums(
PKSMULTIPLE_ITEM* MediumList)
{
HANDLE hFilter = m_KsObjectParent->KsGetObjectHandle();
return KsGetMultiplePinFactoryItems(hFilter, m_PinId, KSPROPERTY_PIN_MEDIUMS, (PVOID*)MediumList);
}
HRESULT
STDMETHODCALLTYPE
COutputPin::KsQueryInterfaces(
PKSMULTIPLE_ITEM* InterfaceList)
{
HANDLE hFilter = m_KsObjectParent->KsGetObjectHandle();
return KsGetMultiplePinFactoryItems(hFilter, m_PinId, KSPROPERTY_PIN_INTERFACES, (PVOID*)InterfaceList);
}
HRESULT
STDMETHODCALLTYPE
COutputPin::KsCreateSinkPinHandle(
KSPIN_INTERFACE& Interface,
KSPIN_MEDIUM& Medium)
{
OutputDebugStringW(L"COutputPin::KsCreateSinkPinHandle NotImplemented\n");
return E_NOTIMPL;
}
HRESULT
STDMETHODCALLTYPE
COutputPin::KsGetCurrentCommunication(
KSPIN_COMMUNICATION *Communication,
KSPIN_INTERFACE *Interface,
KSPIN_MEDIUM *Medium)
{
if (Communication)
{
*Communication = m_Communication;
}
if (Interface)
{
if (!m_hPin)
return VFW_E_NOT_CONNECTED;
CopyMemory(Interface, &m_Interface, sizeof(KSPIN_INTERFACE));
}
if (Medium)
{
if (!m_hPin)
return VFW_E_NOT_CONNECTED;
CopyMemory(Medium, &m_Medium, sizeof(KSPIN_MEDIUM));
}
return NOERROR;
}
HRESULT
STDMETHODCALLTYPE
COutputPin::KsPropagateAcquire()
{
OutputDebugStringW(L"COutputPin::KsPropagateAcquire NotImplemented\n");
return E_NOTIMPL;
}
HRESULT
STDMETHODCALLTYPE
COutputPin::KsDeliver(
IMediaSample* Sample,
ULONG Flags)
{
return E_FAIL;
}
HRESULT
STDMETHODCALLTYPE
COutputPin::KsMediaSamplesCompleted(PKSSTREAM_SEGMENT StreamSegment)
{
return NOERROR;
}
IMemAllocator *
STDMETHODCALLTYPE
COutputPin::KsPeekAllocator(KSPEEKOPERATION Operation)
{
if (Operation == KsPeekOperation_AddRef)
{
// add reference on allocator
m_MemAllocator->AddRef();
}
return m_MemAllocator;
}
HRESULT
STDMETHODCALLTYPE
COutputPin::KsReceiveAllocator(IMemAllocator *MemAllocator)
{
if (MemAllocator)
{
MemAllocator->AddRef();
}
if (m_MemAllocator)
{
m_MemAllocator->Release();
}
m_MemAllocator = MemAllocator;
return NOERROR;
}
HRESULT
STDMETHODCALLTYPE
COutputPin::KsRenegotiateAllocator()
{
return E_FAIL;
}
LONG
STDMETHODCALLTYPE
COutputPin::KsIncrementPendingIoCount()
{
return InterlockedIncrement((volatile LONG*)&m_IoCount);
}
LONG
STDMETHODCALLTYPE
COutputPin::KsDecrementPendingIoCount()
{
return InterlockedDecrement((volatile LONG*)&m_IoCount);
}
HRESULT
STDMETHODCALLTYPE
COutputPin::KsQualityNotify(
ULONG Proportion,
REFERENCE_TIME TimeDelta)
{
OutputDebugStringW(L"COutputPin::KsQualityNotify NotImplemented\n");
return E_NOTIMPL;
}
//-------------------------------------------------------------------
// IKsPinEx
//
VOID
STDMETHODCALLTYPE
COutputPin::KsNotifyError(
IMediaSample* Sample,
HRESULT hr)
{
OutputDebugStringW(L"COutputPin::KsNotifyError NotImplemented\n");
}
//-------------------------------------------------------------------
// IKsPinPipe
//
HRESULT
STDMETHODCALLTYPE
COutputPin::KsGetPinFramingCache(
PKSALLOCATOR_FRAMING_EX *FramingEx,
PFRAMING_PROP FramingProp,
FRAMING_CACHE_OPS Option)
{
if (Option > Framing_Cache_Write || Option < Framing_Cache_ReadLast)
{
// invalid argument
return E_INVALIDARG;
}
// get framing properties
*FramingProp = m_FramingProp[Option];
*FramingEx = m_FramingEx[Option];
return NOERROR;
}
HRESULT
STDMETHODCALLTYPE
COutputPin::KsSetPinFramingCache(
PKSALLOCATOR_FRAMING_EX FramingEx,
PFRAMING_PROP FramingProp,
FRAMING_CACHE_OPS Option)
{
ULONG Index;
ULONG RefCount = 0;
if (m_FramingEx[Option])
{
for(Index = 1; Index < 4; Index++)
{
if (m_FramingEx[Index] == m_FramingEx[Option])
RefCount++;
}
if (RefCount == 1)
{
// existing framing is only used once
CoTaskMemFree(m_FramingEx[Option]);
}
}
// store framing
m_FramingEx[Option] = FramingEx;
m_FramingProp[Option] = *FramingProp;
return S_OK;
}
IPin*
STDMETHODCALLTYPE
COutputPin::KsGetConnectedPin()
{
return m_Pin;
}
IKsAllocatorEx*
STDMETHODCALLTYPE
COutputPin::KsGetPipe(
KSPEEKOPERATION Operation)
{
if (Operation == KsPeekOperation_AddRef)
{
if (m_KsAllocatorEx)
m_KsAllocatorEx->AddRef();
}
return m_KsAllocatorEx;
}
HRESULT
STDMETHODCALLTYPE
COutputPin::KsSetPipe(
IKsAllocatorEx *KsAllocator)
{
if (KsAllocator)
KsAllocator->AddRef();
if (m_KsAllocatorEx)
m_KsAllocatorEx->Release();
m_KsAllocatorEx = KsAllocator;
return NOERROR;
}
ULONG
STDMETHODCALLTYPE
COutputPin::KsGetPipeAllocatorFlag()
{
return m_PipeAllocatorFlag;
}
HRESULT
STDMETHODCALLTYPE
COutputPin::KsSetPipeAllocatorFlag(
ULONG Flag)
{
m_PipeAllocatorFlag = Flag;
return NOERROR;
}
GUID
STDMETHODCALLTYPE
COutputPin::KsGetPinBusCache()
{
if (!m_bPinBusCacheInitialized)
{
CopyMemory(&m_PinBusCache, &m_Medium.Set, sizeof(GUID));
m_bPinBusCacheInitialized = TRUE;
}
return m_PinBusCache;
}
HRESULT
STDMETHODCALLTYPE
COutputPin::KsSetPinBusCache(
GUID Bus)
{
CopyMemory(&m_PinBusCache, &Bus, sizeof(GUID));
return NOERROR;
}
PWCHAR
STDMETHODCALLTYPE
COutputPin::KsGetPinName()
{
return (PWCHAR)m_PinName;
}
PWCHAR
STDMETHODCALLTYPE
COutputPin::KsGetFilterName()
{
return m_FilterName;
}
//-------------------------------------------------------------------
// ISpecifyPropertyPages
//
@@ -226,6 +938,7 @@ STDMETHODCALLTYPE
COutputPin::KsPinFactory(
ULONG* PinFactory)
{
OutputDebugStringW(L"COutputPin::KsPinFactory\n");
*PinFactory = m_PinId;
return S_OK;
}
@@ -241,6 +954,7 @@ COutputPin::Render(
IPin *ppinOut,
IGraphBuilder *pGraph)
{
OutputDebugStringW(L"COutputPin::Render\n");
return S_OK;
}
@@ -250,6 +964,7 @@ COutputPin::Backout(
IPin *ppinOut,
IGraphBuilder *pGraph)
{
OutputDebugStringW(L"COutputPin::Backout\n");
return S_OK;
}
//-------------------------------------------------------------------
@@ -259,6 +974,7 @@ HANDLE
STDMETHODCALLTYPE
COutputPin::KsGetObjectHandle()
{
OutputDebugStringW(L"COutputPin::KsGetObjectHandle\n");
assert(m_hPin);
return m_hPin;
}
@@ -276,6 +992,7 @@ COutputPin::KsProperty(
ULONG* BytesReturned)
{
assert(m_hPin != 0);
OutputDebugStringW(L"COutputPin::KsProperty\n");
return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_PROPERTY, (PVOID)Property, PropertyLength, (PVOID)PropertyData, DataLength, BytesReturned);
}
@@ -289,6 +1006,7 @@ COutputPin::KsMethod(
ULONG* BytesReturned)
{
assert(m_hPin != 0);
OutputDebugStringW(L"COutputPin::KsMethod\n");
return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_METHOD, (PVOID)Method, MethodLength, (PVOID)MethodData, DataLength, BytesReturned);
}
@@ -303,6 +1021,8 @@ COutputPin::KsEvent(
{
assert(m_hPin != 0);
OutputDebugStringW(L"COutputPin::KsEvent\n");
if (EventLength)
return KsSynchronousDeviceControl(m_hPin, IOCTL_KS_ENABLE_EVENT, (PVOID)Event, EventLength, (PVOID)EventData, DataLength, BytesReturned);
else
@@ -325,6 +1045,8 @@ COutputPin::Set(
{
ULONG BytesReturned;
OutputDebugStringW(L"COutputPin::Set\n");
if (cbInstanceData)
{
PKSPROPERTY Property = (PKSPROPERTY)CoTaskMemAlloc(sizeof(KSPROPERTY) + cbInstanceData);
@@ -367,6 +1089,8 @@ COutputPin::Get(
{
ULONG BytesReturned;
OutputDebugStringW(L"COutputPin::Get\n");
if (cbInstanceData)
{
PKSPROPERTY Property = (PKSPROPERTY)CoTaskMemAlloc(sizeof(KSPROPERTY) + cbInstanceData);
@@ -406,6 +1130,8 @@ COutputPin::QuerySupported(
KSPROPERTY Property;
ULONG BytesReturned;
OutputDebugStringW(L"COutputPin::QuerySupported\n");
Property.Set = guidPropSet;
Property.Id = dwPropID;
Property.Flags = KSPROPERTY_TYPE_SETSUPPORT;
@@ -470,12 +1196,15 @@ HRESULT
STDMETHODCALLTYPE
COutputPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt)
{
OutputDebugStringW(L"COutputPin::ReceiveConnection\n");
return E_UNEXPECTED;
}
HRESULT
STDMETHODCALLTYPE
COutputPin::Disconnect( void)
{
OutputDebugStringW(L"COutputPin::Disconnect\n");
if (!m_Pin)
{
// pin was not connected
@@ -495,6 +1224,8 @@ HRESULT
STDMETHODCALLTYPE
COutputPin::ConnectedTo(IPin **pPin)
{
OutputDebugStringW(L"COutputPin::ConnectedTo\n");
if (!pPin)
return E_POINTER;
@@ -520,6 +1251,8 @@ HRESULT
STDMETHODCALLTYPE
COutputPin::QueryPinInfo(PIN_INFO *pInfo)
{
OutputDebugStringW(L"COutputPin::QueryPinInfo\n");
wcscpy(pInfo->achName, m_PinName);
pInfo->dir = PINDIR_OUTPUT;
pInfo->pFilter = m_ParentFilter;
@@ -531,6 +1264,8 @@ HRESULT
STDMETHODCALLTYPE
COutputPin::QueryDirection(PIN_DIRECTION *pPinDir)
{
OutputDebugStringW(L"COutputPin::QueryDirection\n");
if (pPinDir)
{
*pPinDir = PINDIR_OUTPUT;
@@ -543,6 +1278,8 @@ HRESULT
STDMETHODCALLTYPE
COutputPin::QueryId(LPWSTR *Id)
{
OutputDebugStringW(L"COutputPin::QueryId\n");
*Id = (LPWSTR)CoTaskMemAlloc((wcslen(m_PinName)+1)*sizeof(WCHAR));
if (!*Id)
return E_OUTOFMEMORY;
@@ -580,10 +1317,10 @@ COutputPin::EnumMediaTypes(IEnumMediaTypes **ppEnum)
// query media type count
hr = KsGetMediaTypeCount(hFilter, m_PinId, &MediaTypeCount);
if (FAILED(hr) || !MediaTypeCount)
{
{
OutputDebugStringW(L"COutputPin::EnumMediaTypes failed1\n");
return hr;
}
}
// allocate media types
MediaTypes = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE) * MediaTypeCount);
@@ -605,7 +1342,7 @@ COutputPin::EnumMediaTypes(IEnumMediaTypes **ppEnum)
{
// failed
CoTaskMemFree(MediaTypes);
OutputDebugStringW(L"COutputPin::EnumMediaTypes failed2\n");
OutputDebugStringW(L"COutputPin::EnumMediaTypes failed\n");
return hr;
}
}
+30
View File
@@ -19,8 +19,23 @@
#include <stdio.h>
#include <vector>
#include <assert.h>
#include <ksmedia.h>
//#include <debug.h>
interface DECLSPEC_UUID("877E4351-6FEA-11D0-B863-00AA00A216A1") IKsClock;
#undef INTERFACE
#define INTERFACE IKsClock
DECLARE_INTERFACE_(IKsClock, IUnknown)
{
STDMETHOD_(HANDLE, KsGetClockHandle)(
THIS
) PURE;
};
typedef HRESULT (CALLBACK *LPFNCREATEINSTANCE)(IUnknown* pUnkOuter, REFIID riid, LPVOID* ppvObject);
typedef struct {
@@ -139,4 +154,19 @@ CEnumMediaTypes_fnConstructor(
REFIID riid,
LPVOID * ppv);
/* node.cpp */
HRESULT
WINAPI
CKsNode_Constructor(
IUnknown * pUnkOuter,
HANDLE ParentHandle,
ULONG NodeId,
ACCESS_MASK DesiredAccess,
REFIID riid,
LPVOID * ppv);
extern const GUID IID_IKsObject;
extern const GUID IID_IKsPinEx;
extern const GUID IID_IKsAggregateControl;
extern const GUID IID_IKsPinPipe;
extern const GUID IID_IKsPinFactory;
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -92,7 +92,7 @@ KsiCreateObjectType( HANDLE hHandle,
*
*--*/
KSDDKAPI
NTSTATUS
DWORD
NTAPI
KsCreateAllocator(HANDLE ConnectionHandle,
PKSALLOCATOR_FRAMING AllocatorFraming,
@@ -130,7 +130,7 @@ KsCreateAllocator(HANDLE ConnectionHandle,
*
*--*/
KSDDKAPI
NTSTATUS
DWORD
NTAPI
KsCreateClock(HANDLE ConnectionHandle,
PKSCLOCK_CREATE ClockCreate,
@@ -225,7 +225,7 @@ KsCreatePin(HANDLE FilterHandle,
*
*--*/
KSDDKAPI
NTSTATUS
DWORD
NTAPI
KsCreateTopologyNode(HANDLE ParentHandle,
PKSNODE_CREATE NodeCreate,
+2 -2
View File
@@ -1916,9 +1916,9 @@ RegpApplyRestrictions(DWORD dwFlags,
{
DWORD cbExpect = 0;
if ((dwFlags & RRF_RT_DWORD) == RRF_RT_DWORD)
if ((dwFlags & RRF_RT_ANY) == RRF_RT_DWORD)
cbExpect = 4;
else if ((dwFlags & RRF_RT_QWORD) == RRF_RT_QWORD)
else if ((dwFlags & RRF_RT_ANY) == RRF_RT_QWORD)
cbExpect = 8;
if (cbExpect && cbData != cbExpect)
+3
View File
@@ -805,6 +805,9 @@ static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
return FALSE;
}
while (*StringSid == ' ')
StringSid++;
*cBytes = ComputeStringSidSize(StringSid);
if (!pisid) /* Simply compute the size */
{
+25 -37
View File
@@ -42,7 +42,7 @@ EVENTLOG_HANDLE_A_bind(EVENTLOG_HANDLE_A UNCServerName)
status = RpcStringBindingComposeA(NULL,
(UCHAR *)"ncacn_np",
(UCHAR *)UNCServerName,
(UCHAR *)"\\pipe\\ntsvcs",
(UCHAR *)"\\pipe\\EventLog",
NULL,
(UCHAR **)&pszStringBinding);
if (status)
@@ -147,20 +147,17 @@ BOOL WINAPI
BackupEventLogA(IN HANDLE hEventLog,
IN LPCSTR lpBackupFileName)
{
RPC_STRING BackupFileName;
ANSI_STRING BackupFileName;
NTSTATUS Status;
TRACE("%p, %s\n", hEventLog, lpBackupFileName);
BackupFileName.Buffer = (LPSTR)lpBackupFileName;
BackupFileName.Length = BackupFileName.MaximumLength =
lpBackupFileName ? strlen(lpBackupFileName) : 0;
BackupFileName.MaximumLength += sizeof(CHAR);
RtlInitAnsiString(&BackupFileName, lpBackupFileName);
RpcTryExcept
{
Status = ElfrBackupELFA(hEventLog,
&BackupFileName);
(PRPC_STRING)&BackupFileName);
}
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
@@ -188,20 +185,17 @@ BOOL WINAPI
BackupEventLogW(IN HANDLE hEventLog,
IN LPCWSTR lpBackupFileName)
{
RPC_UNICODE_STRING BackupFileName;
UNICODE_STRING BackupFileName;
NTSTATUS Status;
TRACE("%p, %s\n", hEventLog, debugstr_w(lpBackupFileName));
BackupFileName.Buffer = (LPWSTR)lpBackupFileName;
BackupFileName.Length = BackupFileName.MaximumLength =
lpBackupFileName ? wcslen(lpBackupFileName) * sizeof(WCHAR) : 0;
BackupFileName.MaximumLength += sizeof(WCHAR);
RtlInitUnicodeString(&BackupFileName, lpBackupFileName);
RpcTryExcept
{
Status = ElfrBackupELFW(hEventLog,
&BackupFileName);
(PRPC_UNICODE_STRING)&BackupFileName);
}
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
@@ -226,20 +220,17 @@ BOOL WINAPI
ClearEventLogA(IN HANDLE hEventLog,
IN LPCSTR lpBackupFileName)
{
RPC_STRING BackupFileName;
ANSI_STRING BackupFileName;
NTSTATUS Status;
TRACE("%p, %s\n", hEventLog, lpBackupFileName);
BackupFileName.Buffer = (LPSTR)lpBackupFileName;
BackupFileName.Length = BackupFileName.MaximumLength =
lpBackupFileName ? strlen(lpBackupFileName) : 0;
BackupFileName.MaximumLength += sizeof(CHAR);
RtlInitAnsiString(&BackupFileName, lpBackupFileName);
RpcTryExcept
{
Status = ElfrClearELFA(hEventLog,
&BackupFileName);
(PRPC_STRING)&BackupFileName);
}
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
@@ -264,20 +255,17 @@ BOOL WINAPI
ClearEventLogW(IN HANDLE hEventLog,
IN LPCWSTR lpBackupFileName)
{
RPC_UNICODE_STRING BackupFileName;
UNICODE_STRING BackupFileName;
NTSTATUS Status;
TRACE("%p, %s\n", hEventLog, debugstr_w(lpBackupFileName));
BackupFileName.Buffer = (LPWSTR)lpBackupFileName;
BackupFileName.Length = BackupFileName.MaximumLength =
lpBackupFileName ? wcslen(lpBackupFileName) * sizeof(WCHAR) : 0;
BackupFileName.MaximumLength += sizeof(WCHAR);
RtlInitUnicodeString(&BackupFileName,lpBackupFileName);
RpcTryExcept
{
Status = ElfrClearELFW(hEventLog,
&BackupFileName);
(PRPC_UNICODE_STRING)&BackupFileName);
}
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
@@ -380,6 +368,12 @@ GetEventLogInformation(IN HANDLE hEventLog,
{
NTSTATUS Status;
if (dwInfoLevel != EVENTLOG_FULL_INFO)
{
SetLastError(ERROR_INVALID_LEVEL);
return FALSE;
}
RpcTryExcept
{
Status = ElfrGetLogInformation(hEventLog,
@@ -562,21 +556,18 @@ HANDLE WINAPI
OpenBackupEventLogW(IN LPCWSTR lpUNCServerName,
IN LPCWSTR lpFileName)
{
RPC_UNICODE_STRING FileName;
UNICODE_STRING FileName;
IELF_HANDLE LogHandle;
NTSTATUS Status;
TRACE("%s, %s\n", debugstr_w(lpUNCServerName), debugstr_w(lpFileName));
FileName.Buffer = (LPWSTR)lpFileName;
FileName.Length = FileName.MaximumLength =
lpFileName ? wcslen(lpFileName) * sizeof(WCHAR) : 0;
FileName.MaximumLength += sizeof(WCHAR);
RtlInitUnicodeString(&FileName, lpFileName);
RpcTryExcept
{
Status = ElfrOpenBELW((LPWSTR)lpUNCServerName,
&FileName,
(PRPC_UNICODE_STRING)&FileName,
1,
1,
&LogHandle);
@@ -903,21 +894,18 @@ HANDLE WINAPI
RegisterEventSourceW(IN LPCWSTR lpUNCServerName,
IN LPCWSTR lpSourceName)
{
RPC_UNICODE_STRING SourceName;
UNICODE_STRING SourceName;
IELF_HANDLE LogHandle;
NTSTATUS Status;
TRACE("%s, %s\n", debugstr_w(lpUNCServerName), debugstr_w(lpSourceName));
SourceName.Buffer = (LPWSTR)lpSourceName;
SourceName.Length = SourceName.MaximumLength =
lpSourceName ? wcslen(lpSourceName) * sizeof(WCHAR) : 0;
SourceName.MaximumLength += sizeof(WCHAR);
RtlInitUnicodeString(&SourceName, lpSourceName);
RpcTryExcept
{
Status = ElfrRegisterEventSourceW((LPWSTR)lpUNCServerName,
&SourceName,
(PRPC_UNICODE_STRING)&SourceName,
&EmptyStringU,
1,
1,
-55
View File
@@ -131,61 +131,6 @@ SVCCTL_HANDLEW_unbind(SVCCTL_HANDLEW szMachineName,
}
handle_t __RPC_USER
RPC_SERVICE_STATUS_HANDLE_bind(RPC_SERVICE_STATUS_HANDLE hServiceStatus)
{
handle_t hBinding = NULL;
LPWSTR pszStringBinding;
RPC_STATUS status;
TRACE("RPC_SERVICE_STATUS_HANDLE_bind() called\n");
status = RpcStringBindingComposeW(NULL,
L"ncacn_np",
NULL,
L"\\pipe\\ntsvcs",
NULL,
&pszStringBinding);
if (status != RPC_S_OK)
{
ERR("RpcStringBindingCompose returned 0x%x\n", status);
return NULL;
}
/* Set the binding handle that will be used to bind to the server. */
status = RpcBindingFromStringBindingW(pszStringBinding,
&hBinding);
if (status != RPC_S_OK)
{
ERR("RpcBindingFromStringBinding returned 0x%x\n", status);
}
status = RpcStringFreeW(&pszStringBinding);
if (status != RPC_S_OK)
{
ERR("RpcStringFree returned 0x%x\n", status);
}
return hBinding;
}
void __RPC_USER
RPC_SERVICE_STATUS_HANDLE_unbind(RPC_SERVICE_STATUS_HANDLE hServiceStatus,
handle_t hBinding)
{
RPC_STATUS status;
TRACE("RPC_SERVICE_STATUS_HANDLE_unbind() called\n");
status = RpcBindingFree(&hBinding);
if (status != RPC_S_OK)
{
ERR("RpcBindingFree returned 0x%x\n", status);
}
}
DWORD
ScmRpcStatusToWinError(RPC_STATUS Status)
{
+88 -2
View File
@@ -41,10 +41,87 @@ typedef struct _ACTIVE_SERVICE
static DWORD dwActiveServiceCount = 0;
static PACTIVE_SERVICE lpActiveServices = NULL;
static handle_t hStatusBinding = NULL;
/* FUNCTIONS *****************************************************************/
handle_t __RPC_USER
RPC_SERVICE_STATUS_HANDLE_bind(RPC_SERVICE_STATUS_HANDLE hServiceStatus)
{
return hStatusBinding;
}
void __RPC_USER
RPC_SERVICE_STATUS_HANDLE_unbind(RPC_SERVICE_STATUS_HANDLE hServiceStatus,
handle_t hBinding)
{
}
static RPC_STATUS
ScCreateStatusBinding(VOID)
{
LPWSTR pszStringBinding;
RPC_STATUS status;
TRACE("ScCreateStatusBinding() called\n");
status = RpcStringBindingComposeW(NULL,
L"ncacn_np",
NULL,
L"\\pipe\\ntsvcs",
NULL,
&pszStringBinding);
if (status != RPC_S_OK)
{
ERR("RpcStringBindingCompose returned 0x%x\n", status);
return status;
}
/* Set the binding handle that will be used to bind to the server. */
status = RpcBindingFromStringBindingW(pszStringBinding,
&hStatusBinding);
if (status != RPC_S_OK)
{
ERR("RpcBindingFromStringBinding returned 0x%x\n", status);
}
status = RpcStringFreeW(&pszStringBinding);
if (status != RPC_S_OK)
{
ERR("RpcStringFree returned 0x%x\n", status);
}
return status;
}
static RPC_STATUS
ScDestroyStatusBinding(VOID)
{
RPC_STATUS status;
TRACE("ScDestroyStatusBinding() called\n");
if (hStatusBinding == NULL)
return RPC_S_OK;
status = RpcBindingFree(&hStatusBinding);
if (status != RPC_S_OK)
{
ERR("RpcBindingFree returned 0x%x\n", status);
}
else
{
hStatusBinding = NULL;
}
return status;
}
static PACTIVE_SERVICE
ScLookupServiceByServiceName(LPCWSTR lpServiceName)
{
@@ -259,7 +336,6 @@ ScConnectControlPipe(HANDLE *hPipe)
TRACE("Sent Process ID %lu\n", dwProcessId);
return ERROR_SUCCESS;
}
@@ -403,7 +479,7 @@ ScServiceDispatcher(HANDLE hPipe,
}
else
{
dwError = ERROR_NOT_FOUND;
dwError = ERROR_SERVICE_DOES_NOT_EXIST;
}
ReplyPacket.dwError = dwError;
@@ -747,7 +823,12 @@ StartServiceCtrlDispatcherA(const SERVICE_TABLE_ENTRYA * lpServiceStartTable)
return FALSE;
}
ScCreateStatusBinding();
ScServiceDispatcher(hPipe, lpMessageBuffer, 256);
ScDestroyStatusBinding();
CloseHandle(hPipe);
/* Free the message buffer */
@@ -837,7 +918,12 @@ StartServiceCtrlDispatcherW(const SERVICE_TABLE_ENTRYW * lpServiceStartTable)
return FALSE;
}
ScCreateStatusBinding();
ScServiceDispatcher(hPipe, lpMessageBuffer, 256);
ScDestroyStatusBinding();
CloseHandle(hPipe);
/* Free the message buffer */
+16 -9
View File
@@ -108,12 +108,18 @@ static int coff_add_file(struct CoffFileSet* coff_files, struct module* module,
if (coff_files->nfiles + 1 >= coff_files->nfiles_alloc)
{
coff_files->nfiles_alloc += 10;
coff_files->files = (coff_files->files) ?
HeapReAlloc(GetProcessHeap(), 0, coff_files->files,
coff_files->nfiles_alloc * sizeof(struct CoffFile)) :
HeapAlloc(GetProcessHeap(), 0,
coff_files->nfiles_alloc * sizeof(struct CoffFile));
if (coff_files->files)
{
coff_files->nfiles_alloc *= 2;
coff_files->files = HeapReAlloc(GetProcessHeap(), 0, coff_files->files,
coff_files->nfiles_alloc * sizeof(struct CoffFile));
}
else
{
coff_files->nfiles_alloc = 16;
coff_files->files = HeapAlloc(GetProcessHeap(), 0,
coff_files->nfiles_alloc * sizeof(struct CoffFile));
}
}
file = coff_files->files + coff_files->nfiles;
file->startaddr = 0xffffffff;
@@ -132,7 +138,7 @@ static void coff_add_symbol(struct CoffFile* coff_file, struct symt* sym)
{
if (coff_file->neps + 1 >= coff_file->neps_alloc)
{
coff_file->neps_alloc += 10;
coff_file->neps_alloc *= 2;
coff_file->entries = (coff_file->entries) ?
HeapReAlloc(GetProcessHeap(), 0, coff_file->entries,
coff_file->neps_alloc * sizeof(struct symt*)) :
@@ -389,6 +395,7 @@ BOOL coff_process_info(const struct msc_debug_info* msc_dbg)
{
if (coff_files.files[j].entries != NULL)
{
symt_cmp_addr_module = msc_dbg->module;
qsort(coff_files.files[j].entries, coff_files.files[j].neps,
sizeof(struct symt*), symt_cmp_addr);
}
@@ -413,7 +420,7 @@ BOOL coff_process_info(const struct msc_debug_info* msc_dbg)
for (;;)
{
if (l+1 >= coff_files.files[j].neps) break;
symt_get_info(coff_files.files[j].entries[l+1], TI_GET_ADDRESS, &addr);
symt_get_info(msc_dbg->module, coff_files.files[j].entries[l+1], TI_GET_ADDRESS, &addr);
if (((msc_dbg->module->module.BaseOfImage + linepnt->Type.VirtualAddress) < addr))
break;
l++;
@@ -426,7 +433,7 @@ BOOL coff_process_info(const struct msc_debug_info* msc_dbg)
* start of the function, so we need to subtract that offset
* first.
*/
symt_get_info(coff_files.files[j].entries[l+1], TI_GET_ADDRESS, &addr);
symt_get_info(msc_dbg->module, coff_files.files[j].entries[l+1], TI_GET_ADDRESS, &addr);
symt_add_func_line(msc_dbg->module, (struct symt_function*)coff_files.files[j].entries[l+1],
coff_files.files[j].compiland->source, linepnt->Linenumber,
msc_dbg->module->module.BaseOfImage + linepnt->Type.VirtualAddress - addr);
+412
View File
@@ -0,0 +1,412 @@
/*
* File cpu_i386.c
*
* Copyright (C) 2009-2009, Eric Pouech.
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "dbghelp_private.h"
#include "wine/winbase16.h"
#include "winternl.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
#define STEP_FLAG 0x00000100 /* single step flag */
#define V86_FLAG 0x00020000
#define IS_VM86_MODE(ctx) (ctx->EFlags & V86_FLAG)
#ifdef __i386__
static ADDRESS_MODE get_selector_type(HANDLE hThread, const CONTEXT* ctx, WORD sel)
{
LDT_ENTRY le;
if (IS_VM86_MODE(ctx)) return AddrModeReal;
/* null or system selector */
if (!(sel & 4) || ((sel >> 3) < 17)) return AddrModeFlat;
if (hThread && GetThreadSelectorEntry(hThread, sel, &le))
return le.HighWord.Bits.Default_Big ? AddrMode1632 : AddrMode1616;
/* selector doesn't exist */
return -1;
}
static unsigned i386_build_addr(HANDLE hThread, const CONTEXT* ctx, ADDRESS64* addr,
unsigned seg, unsigned long offset)
{
addr->Mode = AddrModeFlat;
addr->Segment = seg;
addr->Offset = offset;
if (seg)
{
switch (addr->Mode = get_selector_type(hThread, ctx, seg))
{
case AddrModeReal:
case AddrMode1616:
addr->Offset &= 0xffff;
break;
case AddrModeFlat:
case AddrMode1632:
break;
default:
return FALSE;
}
}
return TRUE;
}
#endif
static unsigned i386_get_addr(HANDLE hThread, const CONTEXT* ctx,
enum cpu_addr ca, ADDRESS64* addr)
{
#ifdef __i386__
switch (ca)
{
case cpu_addr_pc: return i386_build_addr(hThread, ctx, addr, ctx->SegCs, ctx->Eip);
case cpu_addr_stack: return i386_build_addr(hThread, ctx, addr, ctx->SegSs, ctx->Esp);
case cpu_addr_frame: return i386_build_addr(hThread, ctx, addr, ctx->SegSs, ctx->Ebp);
}
#endif
return FALSE;
}
enum st_mode {stm_start, stm_32bit, stm_16bit, stm_done};
/* indexes in Reserved array */
#define __CurrentMode 0
#define __CurrentSwitch 1
#define __NextSwitch 2
#define curr_mode (frame->Reserved[__CurrentMode])
#define curr_switch (frame->Reserved[__CurrentSwitch])
#define next_switch (frame->Reserved[__NextSwitch])
static BOOL i386_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame)
{
STACK32FRAME frame32;
STACK16FRAME frame16;
char ch;
ADDRESS64 tmp;
DWORD p;
WORD val;
BOOL do_switch;
/* sanity check */
if (curr_mode >= stm_done) return FALSE;
TRACE("Enter: PC=%s Frame=%s Return=%s Stack=%s Mode=%s cSwitch=%p nSwitch=%p\n",
wine_dbgstr_addr(&frame->AddrPC),
wine_dbgstr_addr(&frame->AddrFrame),
wine_dbgstr_addr(&frame->AddrReturn),
wine_dbgstr_addr(&frame->AddrStack),
curr_mode == stm_start ? "start" : (curr_mode == stm_16bit ? "16bit" : "32bit"),
(void*)(DWORD_PTR)curr_switch, (void*)(DWORD_PTR)next_switch);
if (curr_mode == stm_start)
{
THREAD_BASIC_INFORMATION info;
if ((frame->AddrPC.Mode == AddrModeFlat) &&
(frame->AddrFrame.Mode != AddrModeFlat))
{
WARN("Bad AddrPC.Mode / AddrFrame.Mode combination\n");
goto done_err;
}
/* Init done */
curr_mode = (frame->AddrPC.Mode == AddrModeFlat) ? stm_32bit : stm_16bit;
/* cur_switch holds address of WOW32Reserved field in TEB in debuggee
* address space
*/
if (NtQueryInformationThread(csw->hThread, ThreadBasicInformation, &info,
sizeof(info), NULL) == STATUS_SUCCESS)
{
curr_switch = (unsigned long)info.TebBaseAddress + FIELD_OFFSET(TEB, WOW32Reserved);
if (!sw_read_mem(csw, curr_switch, &p, sizeof(p)))
{
WARN("Can't read TEB:WOW32Reserved\n");
goto done_err;
}
next_switch = p;
if (!next_switch) /* no 16-bit stack */
{
curr_switch = 0;
}
else if (curr_mode == stm_16bit)
{
if (!sw_read_mem(csw, next_switch, &frame32, sizeof(frame32)))
{
WARN("Bad stack frame %p\n", (void*)(DWORD_PTR)next_switch);
goto done_err;
}
curr_switch = (DWORD)frame32.frame16;
tmp.Mode = AddrMode1616;
tmp.Segment = SELECTOROF(curr_switch);
tmp.Offset = OFFSETOF(curr_switch);
if (!sw_read_mem(csw, sw_xlat_addr(csw, &tmp), &ch, sizeof(ch)))
curr_switch = 0xFFFFFFFF;
}
else
{
tmp.Mode = AddrMode1616;
tmp.Segment = SELECTOROF(next_switch);
tmp.Offset = OFFSETOF(next_switch);
p = sw_xlat_addr(csw, &tmp);
if (!sw_read_mem(csw, p, &frame16, sizeof(frame16)))
{
WARN("Bad stack frame 0x%08x\n", p);
goto done_err;
}
curr_switch = (DWORD_PTR)frame16.frame32;
if (!sw_read_mem(csw, curr_switch, &ch, sizeof(ch)))
curr_switch = 0xFFFFFFFF;
}
}
else
/* FIXME: this will allow to work when we're not attached to a live target,
* but the 16 <=> 32 switch facility won't be available.
*/
curr_switch = 0;
frame->AddrReturn.Mode = frame->AddrStack.Mode = (curr_mode == stm_16bit) ? AddrMode1616 : AddrModeFlat;
/* don't set up AddrStack on first call. Either the caller has set it up, or
* we will get it in the next frame
*/
memset(&frame->AddrBStore, 0, sizeof(frame->AddrBStore));
}
else
{
if (frame->AddrFrame.Offset == 0) goto done_err;
if (frame->AddrFrame.Mode == AddrModeFlat)
{
assert(curr_mode == stm_32bit);
do_switch = curr_switch && frame->AddrFrame.Offset >= curr_switch;
}
else
{
assert(curr_mode == stm_16bit);
do_switch = curr_switch &&
frame->AddrFrame.Segment == SELECTOROF(curr_switch) &&
frame->AddrFrame.Offset >= OFFSETOF(curr_switch);
}
if (do_switch)
{
if (curr_mode == stm_16bit)
{
if (!sw_read_mem(csw, next_switch, &frame32, sizeof(frame32)))
{
WARN("Bad stack frame %p\n", (void*)(DWORD_PTR)next_switch);
goto done_err;
}
frame->AddrPC.Mode = AddrModeFlat;
frame->AddrPC.Segment = 0;
frame->AddrPC.Offset = frame32.retaddr;
frame->AddrFrame.Mode = AddrModeFlat;
frame->AddrFrame.Segment = 0;
frame->AddrFrame.Offset = frame32.ebp;
frame->AddrStack.Mode = AddrModeFlat;
frame->AddrStack.Segment = 0;
frame->AddrReturn.Mode = AddrModeFlat;
frame->AddrReturn.Segment = 0;
next_switch = curr_switch;
tmp.Mode = AddrMode1616;
tmp.Segment = SELECTOROF(next_switch);
tmp.Offset = OFFSETOF(next_switch);
p = sw_xlat_addr(csw, &tmp);
if (!sw_read_mem(csw, p, &frame16, sizeof(frame16)))
{
WARN("Bad stack frame 0x%08x\n", p);
goto done_err;
}
curr_switch = (DWORD_PTR)frame16.frame32;
curr_mode = stm_32bit;
if (!sw_read_mem(csw, curr_switch, &ch, sizeof(ch)))
curr_switch = 0;
}
else
{
tmp.Mode = AddrMode1616;
tmp.Segment = SELECTOROF(next_switch);
tmp.Offset = OFFSETOF(next_switch);
p = sw_xlat_addr(csw, &tmp);
if (!sw_read_mem(csw, p, &frame16, sizeof(frame16)))
{
WARN("Bad stack frame 0x%08x\n", p);
goto done_err;
}
TRACE("Got a 16 bit stack switch:"
"\n\tframe32: %08lx"
"\n\tedx:%08x ecx:%08x ebp:%08x"
"\n\tds:%04x es:%04x fs:%04x gs:%04x"
"\n\tcall_from_ip:%08x module_cs:%04x relay=%08x"
"\n\tentry_ip:%04x entry_point:%08x"
"\n\tbp:%04x ip:%04x cs:%04x\n",
(unsigned long)frame16.frame32,
frame16.edx, frame16.ecx, frame16.ebp,
frame16.ds, frame16.es, frame16.fs, frame16.gs,
frame16.callfrom_ip, frame16.module_cs, frame16.relay,
frame16.entry_ip, frame16.entry_point,
frame16.bp, frame16.ip, frame16.cs);
frame->AddrPC.Mode = AddrMode1616;
frame->AddrPC.Segment = frame16.cs;
frame->AddrPC.Offset = frame16.ip;
frame->AddrFrame.Mode = AddrMode1616;
frame->AddrFrame.Segment = SELECTOROF(next_switch);
frame->AddrFrame.Offset = frame16.bp;
frame->AddrStack.Mode = AddrMode1616;
frame->AddrStack.Segment = SELECTOROF(next_switch);
frame->AddrReturn.Mode = AddrMode1616;
frame->AddrReturn.Segment = frame16.cs;
next_switch = curr_switch;
if (!sw_read_mem(csw, next_switch, &frame32, sizeof(frame32)))
{
WARN("Bad stack frame %p\n", (void*)(DWORD_PTR)next_switch);
goto done_err;
}
curr_switch = (DWORD)frame32.frame16;
tmp.Mode = AddrMode1616;
tmp.Segment = SELECTOROF(curr_switch);
tmp.Offset = OFFSETOF(curr_switch);
if (!sw_read_mem(csw, sw_xlat_addr(csw, &tmp), &ch, sizeof(ch)))
curr_switch = 0;
curr_mode = stm_16bit;
}
}
else
{
frame->AddrPC = frame->AddrReturn;
if (curr_mode == stm_16bit)
{
frame->AddrStack.Offset = frame->AddrFrame.Offset + 2 * sizeof(WORD);
/* "pop up" previous BP value */
if (!sw_read_mem(csw, sw_xlat_addr(csw, &frame->AddrFrame),
&val, sizeof(WORD)))
goto done_err;
frame->AddrFrame.Offset = val;
}
else
{
frame->AddrStack.Offset = frame->AddrFrame.Offset + 2 * sizeof(DWORD);
/* "pop up" previous EBP value */
if (!sw_read_mem(csw, frame->AddrFrame.Offset,
&frame->AddrFrame.Offset, sizeof(DWORD)))
goto done_err;
}
}
}
if (curr_mode == stm_16bit)
{
unsigned int i;
p = sw_xlat_addr(csw, &frame->AddrFrame);
if (!sw_read_mem(csw, p + sizeof(WORD), &val, sizeof(WORD)))
goto done_err;
frame->AddrReturn.Offset = val;
/* get potential cs if a far call was used */
if (!sw_read_mem(csw, p + 2 * sizeof(WORD), &val, sizeof(WORD)))
goto done_err;
if (frame->AddrFrame.Offset & 1)
frame->AddrReturn.Segment = val; /* far call assumed */
else
{
/* not explicitly marked as far call,
* but check whether it could be anyway
*/
if ((val & 7) == 7 && val != frame->AddrReturn.Segment)
{
LDT_ENTRY le;
if (GetThreadSelectorEntry(csw->hThread, val, &le) &&
(le.HighWord.Bits.Type & 0x08)) /* code segment */
{
/* it is very uncommon to push a code segment cs as
* a parameter, so this should work in most cases
*/
frame->AddrReturn.Segment = val;
}
}
}
frame->AddrFrame.Offset &= ~1;
/* we "pop" parameters as 16 bit entities... of course, this won't
* work if the parameter is in fact bigger than 16bit, but
* there's no way to know that here
*/
for (i = 0; i < sizeof(frame->Params) / sizeof(frame->Params[0]); i++)
{
sw_read_mem(csw, p + (2 + i) * sizeof(WORD), &val, sizeof(val));
frame->Params[i] = val;
}
}
else
{
if (!sw_read_mem(csw, frame->AddrFrame.Offset + sizeof(DWORD),
&frame->AddrReturn.Offset, sizeof(DWORD)))
{
WARN("Cannot read new frame offset %p\n",
(void*)(DWORD_PTR)(frame->AddrFrame.Offset + (int)sizeof(DWORD)));
goto done_err;
}
sw_read_mem(csw, frame->AddrFrame.Offset + 2 * sizeof(DWORD),
frame->Params, sizeof(frame->Params));
}
frame->Far = TRUE;
frame->Virtual = TRUE;
p = sw_xlat_addr(csw, &frame->AddrPC);
if (p && sw_module_base(csw, p))
frame->FuncTableEntry = sw_table_access(csw, p);
else
frame->FuncTableEntry = NULL;
TRACE("Leave: PC=%s Frame=%s Return=%s Stack=%s Mode=%s cSwitch=%p nSwitch=%p FuncTable=%p\n",
wine_dbgstr_addr(&frame->AddrPC),
wine_dbgstr_addr(&frame->AddrFrame),
wine_dbgstr_addr(&frame->AddrReturn),
wine_dbgstr_addr(&frame->AddrStack),
curr_mode == stm_start ? "start" : (curr_mode == stm_16bit ? "16bit" : "32bit"),
(void*)(DWORD_PTR)curr_switch, (void*)(DWORD_PTR)next_switch, frame->FuncTableEntry);
return TRUE;
done_err:
curr_mode = stm_done;
return FALSE;
}
struct cpu cpu_i386 = {
IMAGE_FILE_MACHINE_I386,
4,
i386_get_addr,
i386_stack_walk,
};
+62
View File
@@ -0,0 +1,62 @@
/*
* File cpu_ppc.c
*
* Copyright (C) 2009-2009, Eric Pouech.
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "dbghelp_private.h"
#include "winternl.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
static unsigned ppc_get_addr(HANDLE hThread, const CONTEXT* ctx,
enum cpu_addr ca, ADDRESS64* addr)
{
switch (ca)
{
#if defined(__powerpc__)
case cpu_addr_pc:
addr->Mode = AddrModeFlat;
addr->Segment = 0; /* don't need segment */
addr->Offset = ctx->Iar;
return TRUE;
#endif
default:
case cpu_addr_stack:
case cpu_addr_frame:
FIXME("not done\n");
}
return FALSE;
}
static BOOL ppc_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame)
{
FIXME("not done\n");
return FALSE;
}
struct cpu cpu_ppc = {
IMAGE_FILE_MACHINE_POWERPC,
4,
ppc_get_addr,
ppc_stack_walk,
};
+132
View File
@@ -0,0 +1,132 @@
/*
* File cpu_x86_64.c
*
* Copyright (C) 2009-2009, Eric Pouech.
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <assert.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "dbghelp_private.h"
#include "winternl.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
static unsigned x86_64_get_addr(HANDLE hThread, const CONTEXT* ctx,
enum cpu_addr ca, ADDRESS64* addr)
{
addr->Mode = AddrModeFlat;
switch (ca)
{
#ifdef __x86_64__
case cpu_addr_pc: addr->Segment = ctx->SegCs; addr->Offset = ctx->Rip; return TRUE;
case cpu_addr_stack: addr->Segment = ctx->SegSs; addr->Offset = ctx->Rsp; return TRUE;
case cpu_addr_frame: addr->Segment = ctx->SegSs; addr->Offset = ctx->Rbp; return TRUE;
#endif
default: addr->Mode = -1;
return FALSE;
}
}
enum st_mode {stm_start, stm_64bit, stm_done};
/* indexes in Reserved array */
#define __CurrentMode 0
#define __CurrentSwitch 1
#define __NextSwitch 2
#define curr_mode (frame->Reserved[__CurrentMode])
#define curr_switch (frame->Reserved[__CurrentSwitch])
#define next_switch (frame->Reserved[__NextSwitch])
static BOOL x86_64_stack_walk(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame)
{
/* sanity check */
if (curr_mode >= stm_done) return FALSE;
assert(!csw->is32);
TRACE("Enter: PC=%s Frame=%s Return=%s Stack=%s Mode=%s\n",
wine_dbgstr_addr(&frame->AddrPC),
wine_dbgstr_addr(&frame->AddrFrame),
wine_dbgstr_addr(&frame->AddrReturn),
wine_dbgstr_addr(&frame->AddrStack),
curr_mode == stm_start ? "start" : "64bit");
if (curr_mode == stm_start)
{
if ((frame->AddrPC.Mode == AddrModeFlat) &&
(frame->AddrFrame.Mode != AddrModeFlat))
{
WARN("Bad AddrPC.Mode / AddrFrame.Mode combination\n");
goto done_err;
}
/* Init done */
curr_mode = stm_64bit;
curr_switch = 0;
frame->AddrReturn.Mode = frame->AddrStack.Mode = AddrModeFlat;
/* don't set up AddrStack on first call. Either the caller has set it up, or
* we will get it in the next frame
*/
memset(&frame->AddrBStore, 0, sizeof(frame->AddrBStore));
}
else
{
if (frame->AddrReturn.Offset == 0) goto done_err;
frame->AddrPC = frame->AddrReturn;
}
if (!sw_read_mem(csw, frame->AddrStack.Offset,
&frame->AddrReturn.Offset, sizeof(DWORD64)))
{
WARN("Cannot read new frame offset %s\n",
wine_dbgstr_longlong(frame->AddrFrame.Offset + sizeof(DWORD64)));
goto done_err;
}
/* FIXME: simplistic stuff... need to handle both dwarf & PE stack information */
frame->AddrStack.Offset += sizeof(DWORD64);
memset(&frame->Params, 0, sizeof(frame->Params));
frame->Far = TRUE;
frame->Virtual = TRUE;
if (frame->AddrPC.Offset && sw_module_base(csw, frame->AddrPC.Offset))
frame->FuncTableEntry = sw_table_access(csw, frame->AddrPC.Offset);
else
frame->FuncTableEntry = NULL;
TRACE("Leave: PC=%s Frame=%s Return=%s Stack=%s Mode=%s FuncTable=%p\n",
wine_dbgstr_addr(&frame->AddrPC),
wine_dbgstr_addr(&frame->AddrFrame),
wine_dbgstr_addr(&frame->AddrReturn),
wine_dbgstr_addr(&frame->AddrStack),
curr_mode == stm_start ? "start" : "64bit",
frame->FuncTableEntry);
return TRUE;
done_err:
curr_mode = stm_done;
return FALSE;
}
struct cpu cpu_x86_64 = {
IMAGE_FILE_MACHINE_AMD64,
8,
x86_64_get_addr,
x86_64_stack_walk,
};
+149
View File
@@ -0,0 +1,149 @@
/*
* File crc32.c - calculate CRC32 checksum of a file
*
* Copyright (C) 1996, Eric Youngdale.
* 1999-2007 Eric Pouech
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include "wine/port.h"
#include <stdio.h>
#include "dbghelp_private.h"
/* Copyright (C) 1986 Gary S. Brown. Modified by Robert Shearman. You may use
the following calc_crc32 code or tables extracted from it, as desired without
restriction. */
/**********************************************************************\
|* Demonstration program to compute the 32-bit CRC used as the frame *|
|* check sequence in ADCCP (ANSI X3.66, also known as FIPS PUB 71 *|
|* and FED-STD-1003, the U.S. versions of CCITT's X.25 link-level *|
|* protocol). The 32-bit FCS was added via the Federal Register, *|
|* 1 June 1982, p.23798. I presume but don't know for certain that *|
|* this polynomial is or will be included in CCITT V.41, which *|
|* defines the 16-bit CRC (often called CRC-CCITT) polynomial. FIPS *|
|* PUB 78 says that the 32-bit FCS reduces otherwise undetected *|
|* errors by a factor of 10^-5 over 16-bit FCS. *|
\**********************************************************************/
/* First, the polynomial itself and its table of feedback terms. The */
/* polynomial is */
/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
/* Note that we take it "backwards" and put the highest-order term in */
/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */
/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */
/* the MSB being 1. */
/* Note that the usual hardware shift register implementation, which */
/* is what we're using (we're merely optimizing it by doing eight-bit */
/* chunks at a time) shifts bits into the lowest-order term. In our */
/* implementation, that means shifting towards the right. Why do we */
/* do it this way? Because the calculated CRC must be transmitted in */
/* order from highest-order term to lowest-order term. UARTs transmit */
/* characters in order from LSB to MSB. By storing the CRC this way, */
/* we hand it to the UART in the order low-byte to high-byte; the UART */
/* sends each low-bit to hight-bit; and the result is transmission bit */
/* by bit from highest- to lowest-order term without requiring any bit */
/* shuffling on our part. Reception works similarly. */
/* The feedback terms table consists of 256, 32-bit entries. Notes: */
/* */
/* 1. The table can be generated at runtime if desired; code to do so */
/* is shown later. It might not be obvious, but the feedback */
/* terms simply represent the results of eight shift/xor opera- */
/* tions for all combinations of data and CRC register values. */
/* */
/* 2. The CRC accumulation logic is the same for all CRC polynomials, */
/* be they sixteen or thirty-two bits wide. You simply choose the */
/* appropriate table. Alternatively, because the table can be */
/* generated at runtime, you can start by generating the table for */
/* the polynomial in question and use exactly the same "updcrc", */
/* if your application needn't simultaneously handle two CRC */
/* polynomials. (Note, however, that XMODEM is strange.) */
/* */
/* 3. For 16-bit CRCs, the table entries need be only 16 bits wide; */
/* of course, 32-bit entries work OK if the high 16 bits are zero. */
/* */
/* 4. The values must be right-shifted by eight bits by the "updcrc" */
/* logic; the shift must be unsigned (bring in zeroes). On some */
/* hardware you could probably optimize the shift in assembler by */
/* using byte-swap instructions. */
DWORD calc_crc32(int fd)
{
#define UPDC32(octet,crc) (crc_32_tab[((crc) ^ (octet)) & 0xff] ^ ((crc) >> 8))
static const DWORD crc_32_tab[] =
{ /* CRC polynomial 0xedb88320 */
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
int i, r;
unsigned char buffer[8192];
DWORD crc = ~0;
_lseek(fd, 0, SEEK_SET);
while ((r = _read(fd, buffer, sizeof(buffer))) > 0)
{
for (i = 0; i < r; i++) crc = UPDC32(buffer[i], crc);
}
return ~crc;
#undef UPDC32
}
+65 -20
View File
@@ -106,7 +106,7 @@ struct process* process_find_by_handle(HANDLE hProcess)
*/
BOOL validate_addr64(DWORD64 addr)
{
if (addr >> 32)
if (sizeof(void*) == sizeof(int) && (addr >> 32))
{
FIXME("Unsupported address %s\n", wine_dbgstr_longlong(addr));
SetLastError(ERROR_INVALID_PARAMETER);
@@ -133,6 +133,48 @@ void* fetch_buffer(struct process* pcs, unsigned size)
return pcs->buffer;
}
const char* wine_dbgstr_addr(const ADDRESS64* addr)
{
if (!addr) return "(null)";
switch (addr->Mode)
{
case AddrModeFlat:
return wine_dbg_sprintf("flat<%s>", wine_dbgstr_longlong(addr->Offset));
case AddrMode1616:
return wine_dbg_sprintf("1616<%04x:%04x>", addr->Segment, (DWORD)addr->Offset);
case AddrMode1632:
return wine_dbg_sprintf("1632<%04x:%08x>", addr->Segment, (DWORD)addr->Offset);
case AddrModeReal:
return wine_dbg_sprintf("real<%04x:%04x>", addr->Segment, (DWORD)addr->Offset);
default:
return "unknown";
}
}
extern struct cpu cpu_i386, cpu_x86_64;
static struct cpu* dbghelp_cpus[] = {&cpu_i386, &cpu_x86_64, NULL};
struct cpu* dbghelp_current_cpu =
#if defined(__i386__)
&cpu_i386
#elif defined(__x86_64__)
&cpu_x86_64
#else
#error define support for your CPU
#endif
;
struct cpu* cpu_find(DWORD machine)
{
struct cpu** cpu;
for (cpu = dbghelp_cpus ; *cpu; cpu++)
{
if (cpu[0]->machine == machine) return cpu[0];
}
return NULL;
}
/******************************************************************
* SymSetSearchPathW (DBGHELP.@)
*
@@ -211,16 +253,16 @@ BOOL WINAPI SymGetSearchPath(HANDLE hProcess, PSTR szSearchPath,
* SymInitialize helper: loads in dbghelp all known (and loaded modules)
* this assumes that hProcess is a handle on a valid process
*/
static BOOL WINAPI process_invade_cb(PCSTR name, ULONG base, ULONG size, PVOID user)
static BOOL WINAPI process_invade_cb(PCWSTR name, ULONG64 base, ULONG size, PVOID user)
{
char tmp[MAX_PATH];
WCHAR tmp[MAX_PATH];
HANDLE hProcess = user;
if (!GetModuleFileNameExA(hProcess, (HMODULE)base,
tmp, sizeof(tmp)))
lstrcpynA(tmp, name, sizeof(tmp));
if (!GetModuleFileNameExW(hProcess, (HMODULE)(DWORD_PTR)base,
tmp, sizeof(tmp) / sizeof(WCHAR)))
lstrcpynW(tmp, name, sizeof(tmp) / sizeof(WCHAR));
SymLoadModule(hProcess, 0, tmp, name, base, size);
SymLoadModuleExW(hProcess, 0, tmp, name, base, size, NULL, 0);
return TRUE;
}
@@ -232,7 +274,8 @@ static BOOL check_live_target(struct process* pcs)
{
if (!GetProcessId(pcs->handle)) return FALSE;
if (GetEnvironmentVariableA("DBGHELP_NOLIVE", NULL, 0)) return FALSE;
elf_read_wine_loader_dbg_info(pcs);
if (!elf_read_wine_loader_dbg_info(pcs))
macho_read_wine_loader_dbg_info(pcs);
return TRUE;
}
@@ -325,8 +368,9 @@ BOOL WINAPI SymInitializeW(HANDLE hProcess, PCWSTR UserSearchPath, BOOL fInvadeP
if (check_live_target(pcs))
{
if (fInvadeProcess)
EnumerateLoadedModules(hProcess, process_invade_cb, hProcess);
EnumerateLoadedModulesW64(hProcess, process_invade_cb, hProcess);
elf_synchronize_module_list(pcs);
macho_synchronize_module_list(pcs);
}
else if (fInvadeProcess)
{
@@ -459,25 +503,25 @@ BOOL WINAPI SymSetContext(HANDLE hProcess, PIMAGEHLP_STACK_FRAME StackFrame,
*/
static BOOL CALLBACK reg_cb64to32(HANDLE hProcess, ULONG action, ULONG64 data, ULONG64 user)
{
PSYMBOL_REGISTERED_CALLBACK cb32 = (PSYMBOL_REGISTERED_CALLBACK)(DWORD)(user >> 32);
DWORD user32 = (DWORD)user;
struct process* pcs = process_find_by_handle(hProcess);
void* data32;
IMAGEHLP_DEFERRED_SYMBOL_LOAD64* idsl64;
IMAGEHLP_DEFERRED_SYMBOL_LOAD idsl;
if (!pcs) return FALSE;
switch (action)
{
case CBA_DEBUG_INFO:
case CBA_DEFERRED_SYMBOL_LOAD_CANCEL:
case CBA_SET_OPTIONS:
case CBA_SYMBOLS_UNLOADED:
data32 = (void*)(DWORD)data;
data32 = (void*)(DWORD_PTR)data;
break;
case CBA_DEFERRED_SYMBOL_LOAD_COMPLETE:
case CBA_DEFERRED_SYMBOL_LOAD_FAILURE:
case CBA_DEFERRED_SYMBOL_LOAD_PARTIAL:
case CBA_DEFERRED_SYMBOL_LOAD_START:
idsl64 = (IMAGEHLP_DEFERRED_SYMBOL_LOAD64*)(DWORD)data;
idsl64 = (IMAGEHLP_DEFERRED_SYMBOL_LOAD64*)(DWORD_PTR)data;
if (!validate_addr64(idsl64->BaseOfImage))
return FALSE;
idsl.SizeOfStruct = sizeof(idsl);
@@ -495,7 +539,7 @@ static BOOL CALLBACK reg_cb64to32(HANDLE hProcess, ULONG action, ULONG64 data, U
FIXME("No mapping for action %u\n", action);
return FALSE;
}
return cb32(hProcess, action, data32, (PVOID)user32);
return pcs->reg_cb32(hProcess, action, data32, (PVOID)(DWORD_PTR)user);
}
/******************************************************************
@@ -522,7 +566,7 @@ BOOL pcs_callback(const struct process* pcs, ULONG action, void* data)
case CBA_DEFERRED_SYMBOL_LOAD_FAILURE:
case CBA_DEFERRED_SYMBOL_LOAD_PARTIAL:
case CBA_DEFERRED_SYMBOL_LOAD_START:
idslW = (IMAGEHLP_DEFERRED_SYMBOL_LOADW64*)(DWORD)data;
idslW = data;
idsl.SizeOfStruct = sizeof(idsl);
idsl.BaseOfImage = idslW->BaseOfImage;
idsl.CheckSum = idslW->CheckSum;
@@ -548,14 +592,16 @@ BOOL pcs_callback(const struct process* pcs, ULONG action, void* data)
*
* Helper for registering a callback.
*/
static BOOL sym_register_cb(HANDLE hProcess,
static BOOL sym_register_cb(HANDLE hProcess,
PSYMBOL_REGISTERED_CALLBACK64 cb,
PSYMBOL_REGISTERED_CALLBACK cb32,
DWORD64 user, BOOL unicode)
{
struct process* pcs = process_find_by_handle(hProcess);
if (!pcs) return FALSE;
pcs->reg_cb = cb;
pcs->reg_cb32 = cb32;
pcs->reg_is_unicode = unicode;
pcs->reg_user = user;
@@ -569,10 +615,9 @@ BOOL WINAPI SymRegisterCallback(HANDLE hProcess,
PSYMBOL_REGISTERED_CALLBACK CallbackFunction,
PVOID UserContext)
{
DWORD64 tmp = ((ULONGLONG)(DWORD)CallbackFunction << 32) | (DWORD)UserContext;
TRACE("(%p, %p, %p)\n",
hProcess, CallbackFunction, UserContext);
return sym_register_cb(hProcess, reg_cb64to32, tmp, FALSE);
return sym_register_cb(hProcess, reg_cb64to32, CallbackFunction, (DWORD_PTR)UserContext, FALSE);
}
/***********************************************************************
@@ -584,7 +629,7 @@ BOOL WINAPI SymRegisterCallback64(HANDLE hProcess,
{
TRACE("(%p, %p, %s)\n",
hProcess, CallbackFunction, wine_dbgstr_longlong(UserContext));
return sym_register_cb(hProcess, CallbackFunction, UserContext, FALSE);
return sym_register_cb(hProcess, CallbackFunction, NULL, UserContext, FALSE);
}
/***********************************************************************
@@ -596,7 +641,7 @@ BOOL WINAPI SymRegisterCallbackW64(HANDLE hProcess,
{
TRACE("(%p, %p, %s)\n",
hProcess, CallbackFunction, wine_dbgstr_longlong(UserContext));
return sym_register_cb(hProcess, CallbackFunction, UserContext, TRUE);
return sym_register_cb(hProcess, CallbackFunction, NULL, UserContext, TRUE);
}
/* This is imagehlp version not dbghelp !! */
+6
View File
@@ -9,10 +9,15 @@
<define name="_WINE" />
<define name="HAVE_REGEX_H" />
<file>coff.c</file>
<file>cpu_i386.c</file>
<file>cpu_ppc.c</file>
<file>cpu_x86_64.c</file>
<file>crc32.c</file>
<file>dbghelp.c</file>
<file>dwarf.c</file>
<file>elf_module.c</file>
<file>image.c</file>
<file>macho_module.c</file>
<file>memory.c</file>
<file>minidump.c</file>
<file>module.c</file>
@@ -27,6 +32,7 @@
<file>storage.c</file>
<file>symbol.c</file>
<file>type.c</file>
<file>version.rc</file>
<library>wine</library>
<library>psapi</library>
<library>version</library>
+101 -34
View File
@@ -29,6 +29,7 @@
#include "objbase.h"
#include "oaidl.h"
#include "winnls.h"
#include "wine/list.h"
#include "wine/unicode.h"
#include "cvconst.h"
@@ -37,13 +38,14 @@
struct pool /* poor's man */
{
struct pool_arena* first;
unsigned arena_size;
struct list arena_list;
struct list arena_full;
size_t arena_size;
};
void pool_init(struct pool* a, unsigned arena_size);
void pool_init(struct pool* a, size_t arena_size);
void pool_destroy(struct pool* a);
void* pool_alloc(struct pool* a, unsigned len);
void* pool_alloc(struct pool* a, size_t len);
char* pool_strdup(struct pool* a, const char* str);
struct vector
@@ -96,7 +98,6 @@ void hash_table_init(struct pool* pool, struct hash_table* ht,
unsigned num_buckets);
void hash_table_destroy(struct hash_table* ht);
void hash_table_add(struct hash_table* ht, struct hash_table_elt* elt);
unsigned hash_table_hash(const char* name, unsigned num_buckets);
struct hash_table_iter
{
@@ -116,7 +117,7 @@ void* hash_table_iter_up(struct hash_table_iter* hti);
extern unsigned dbghelp_options;
/* some more Wine extensions */
#define SYMOPT_WINE_WITH_ELF_MODULES 0x40000000
#define SYMOPT_WINE_WITH_NATIVE_MODULES 0x40000000
enum location_kind {loc_error, /* reg is the error code */
loc_absolute, /* offset is the location */
@@ -226,8 +227,6 @@ struct symt_public
struct symt* container; /* compiland */
unsigned long address;
unsigned long size;
unsigned in_code : 1,
is_function : 1;
};
struct symt_thunk
@@ -245,7 +244,7 @@ struct symt_array
{
struct symt symt;
int start;
int end;
int end; /* end index if > 0, or -array_len (in bytes) if < 0 */
struct symt* base_type;
struct symt* index_type;
};
@@ -308,6 +307,7 @@ enum module_type
DMT_UNKNOWN, /* for lookup, not actually used for a module */
DMT_ELF, /* a real ELF shared module */
DMT_PE, /* a native or builtin PE module */
DMT_MACHO, /* a real Mach-O shared module */
DMT_PDB, /* .PDB file */
DMT_DBG, /* .DBG file */
};
@@ -327,12 +327,17 @@ struct module
struct elf_module_info* elf_info;
struct dwarf2_module_info_s*dwarf2_info;
struct macho_module_info* macho_info;
/* memory allocation pool */
struct pool pool;
/* symbols & symbol tables */
struct vector vsymt;
int sortlist_valid;
unsigned num_sorttab; /* number of symbols with addresses */
unsigned num_symbols;
unsigned sorttab_size;
struct symt_ht** addr_sorttab;
struct hash_table ht_symbols;
void (*loc_compute)(struct process* pcs,
@@ -355,8 +360,9 @@ struct process
struct process* next;
HANDLE handle;
WCHAR* search_path;
PSYMBOL_REGISTERED_CALLBACK64 reg_cb;
PSYMBOL_REGISTERED_CALLBACK reg_cb32;
BOOL reg_is_unicode;
DWORD64 reg_user;
@@ -411,17 +417,62 @@ struct pdb_lookup
} u;
};
struct cpu_stack_walk
{
HANDLE hProcess;
HANDLE hThread;
BOOL is32;
union
{
struct
{
PREAD_PROCESS_MEMORY_ROUTINE f_read_mem;
PTRANSLATE_ADDRESS_ROUTINE f_xlat_adr;
PFUNCTION_TABLE_ACCESS_ROUTINE f_tabl_acs;
PGET_MODULE_BASE_ROUTINE f_modl_bas;
} s32;
struct
{
PREAD_PROCESS_MEMORY_ROUTINE64 f_read_mem;
PTRANSLATE_ADDRESS_ROUTINE64 f_xlat_adr;
PFUNCTION_TABLE_ACCESS_ROUTINE64 f_tabl_acs;
PGET_MODULE_BASE_ROUTINE64 f_modl_bas;
} s64;
} u;
};
enum cpu_addr {cpu_addr_pc, cpu_addr_stack, cpu_addr_frame};
struct cpu
{
DWORD machine;
DWORD word_size;
/* address manipulation */
unsigned (*get_addr)(HANDLE hThread, const CONTEXT* ctx,
enum cpu_addr, ADDRESS64* addr);
/* stack manipulation */
BOOL (*stack_walk)(struct cpu_stack_walk* csw, LPSTACKFRAME64 frame);
};
extern struct cpu* dbghelp_current_cpu;
/* dbghelp.c */
extern struct process* process_find_by_handle(HANDLE hProcess);
extern HANDLE hMsvcrt;
extern BOOL validate_addr64(DWORD64 addr);
extern BOOL pcs_callback(const struct process* pcs, ULONG action, void* data);
extern void* fetch_buffer(struct process* pcs, unsigned size);
extern const char* wine_dbgstr_addr(const ADDRESS64* addr);
extern struct cpu* cpu_find(DWORD);
/* crc32.c */
extern DWORD calc_crc32(int fd);
typedef BOOL (*enum_modules_cb)(const WCHAR*, unsigned long addr, void* user);
/* elf_module.c */
#define ELF_NO_MAP ((const void*)0xffffffff)
typedef BOOL (*elf_enum_modules_cb)(const WCHAR*, unsigned long addr, void* user);
extern BOOL elf_enum_modules(HANDLE hProc, elf_enum_modules_cb, void*);
#define ELF_NO_MAP ((const void*)-1)
extern BOOL elf_enum_modules(HANDLE hProc, enum_modules_cb, void*);
extern BOOL elf_fetch_file_info(const WCHAR* name, DWORD* base, DWORD* size, DWORD* checksum);
struct elf_file_map;
extern BOOL elf_load_debug_info(struct module* module, struct elf_file_map* fmap);
@@ -431,21 +482,27 @@ extern BOOL elf_read_wine_loader_dbg_info(struct process* pcs);
extern BOOL elf_synchronize_module_list(struct process* pcs);
struct elf_thunk_area;
extern int elf_is_in_thunk_area(unsigned long addr, const struct elf_thunk_area* thunks);
extern DWORD WINAPI addr_to_linear(HANDLE hProcess, HANDLE hThread, ADDRESS* addr);
/* macho_module.c */
#define MACHO_NO_MAP ((const void*)-1)
extern BOOL macho_enum_modules(HANDLE hProc, enum_modules_cb, void*);
extern BOOL macho_fetch_file_info(const WCHAR* name, DWORD* base, DWORD* size, DWORD* checksum);
struct macho_file_map;
extern BOOL macho_load_debug_info(struct module* module, struct macho_file_map* fmap);
extern struct module*
macho_load_module(struct process* pcs, const WCHAR* name, unsigned long);
extern BOOL macho_read_wine_loader_dbg_info(struct process* pcs);
extern BOOL macho_synchronize_module_list(struct process* pcs);
/* module.c */
extern const WCHAR S_ElfW[];
extern const WCHAR S_WineLoaderW[];
extern const WCHAR S_WinePThreadW[];
extern const WCHAR S_WineKThreadW[];
extern const WCHAR S_WineW[];
extern const WCHAR S_SlashW[];
extern struct module*
module_find_by_addr(const struct process* pcs, unsigned long addr,
enum module_type type);
extern struct module*
module_find_by_name(const struct process* pcs,
const WCHAR* name);
extern struct module*
module_find_by_nameA(const struct process* pcs,
const char* name);
@@ -456,11 +513,8 @@ extern BOOL module_get_debug(struct module_pair*);
extern struct module*
module_new(struct process* pcs, const WCHAR* name,
enum module_type type, BOOL virtual,
unsigned long addr, unsigned long size,
DWORD64 addr, DWORD64 size,
unsigned long stamp, unsigned long checksum);
extern struct module*
module_get_container(const struct process* pcs,
const struct module* inner);
extern struct module*
module_get_containee(const struct process* pcs,
const struct module* inner);
@@ -485,13 +539,13 @@ extern BOOL path_find_symbol_file(const struct process* pcs, PCSTR full_
BOOL* is_unmatched);
/* pe_module.c */
extern BOOL pe_load_nt_header(HANDLE hProc, DWORD base, IMAGE_NT_HEADERS* nth);
extern BOOL pe_load_nt_header(HANDLE hProc, DWORD64 base, IMAGE_NT_HEADERS* nth);
extern struct module*
pe_load_native_module(struct process* pcs, const WCHAR* name,
HANDLE hFile, DWORD base, DWORD size);
extern struct module*
pe_load_builtin_module(struct process* pcs, const WCHAR* name,
DWORD base, DWORD size);
DWORD64 base, DWORD64 size);
extern BOOL pe_load_debug_info(const struct process* pcs,
struct module* module);
/* source.c */
@@ -499,9 +553,14 @@ extern unsigned source_new(struct module* module, const char* basedir, const
extern const char* source_get(const struct module* module, unsigned idx);
/* stabs.c */
typedef void (*stabs_def_cb)(struct module* module, unsigned long load_offset,
const char* name, unsigned long offset,
BOOL is_public, BOOL is_global, unsigned char other,
struct symt_compiland* compiland, void* user);
extern BOOL stabs_parse(struct module* module, unsigned long load_offset,
const void* stabs, int stablen,
const char* strs, int strtablen);
const char* strs, int strtablen,
stabs_def_cb callback, void* user);
/* dwarf.c */
extern BOOL dwarf2_parse(struct module* module, unsigned long load_offset,
@@ -512,12 +571,19 @@ extern BOOL dwarf2_parse(struct module* module, unsigned long load_offse
const unsigned char* line, unsigned int line_size,
const unsigned char* loclist, unsigned int loclist_size);
/* stack.c */
extern BOOL sw_read_mem(struct cpu_stack_walk* csw, DWORD64 addr, void* ptr, DWORD sz);
extern DWORD64 sw_xlat_addr(struct cpu_stack_walk* csw, ADDRESS64* addr);
extern void* sw_table_access(struct cpu_stack_walk* csw, DWORD64 addr);
extern DWORD64 sw_module_base(struct cpu_stack_walk* csw, DWORD64 addr);
/* symbol.c */
extern const char* symt_get_name(const struct symt* sym);
extern struct module* symt_cmp_addr_module;
extern int symt_cmp_addr(const void* p1, const void* p2);
extern void copy_symbolW(SYMBOL_INFOW* siw, const SYMBOL_INFO* si);
extern struct symt_ht*
symt_find_nearest(struct module* module, DWORD addr);
symt_find_nearest(struct module* module, DWORD_PTR addr);
extern struct symt_compiland*
symt_new_compiland(struct module* module, unsigned long address,
unsigned src_idx);
@@ -525,8 +591,7 @@ extern struct symt_public*
symt_new_public(struct module* module,
struct symt_compiland* parent,
const char* typename,
unsigned long address, unsigned size,
BOOL in_code, BOOL is_func);
unsigned long address, unsigned size);
extern struct symt_data*
symt_new_global_variable(struct module* module,
struct symt_compiland* parent,
@@ -540,7 +605,7 @@ extern struct symt_function*
unsigned long addr, unsigned long size,
struct symt* type);
extern BOOL symt_normalize_function(struct module* module,
struct symt_function* func);
const struct symt_function* func);
extern void symt_add_func_line(struct module* module,
struct symt_function* func,
unsigned source_idx, int line_num,
@@ -558,7 +623,7 @@ extern struct symt_block*
unsigned pc, unsigned len);
extern struct symt_block*
symt_close_func_block(struct module* module,
struct symt_function* func,
const struct symt_function* func,
struct symt_block* block, unsigned pc);
extern struct symt_hierarchy_point*
symt_add_function_point(struct module* module,
@@ -568,8 +633,8 @@ extern struct symt_hierarchy_point*
const char* name);
extern BOOL symt_fill_func_line_info(const struct module* module,
const struct symt_function* func,
DWORD addr, IMAGEHLP_LINE* line);
extern BOOL symt_get_func_line_next(const struct module* module, PIMAGEHLP_LINE line);
DWORD64 addr, IMAGEHLP_LINE64* line);
extern BOOL symt_get_func_line_next(const struct module* module, PIMAGEHLP_LINE64 line);
extern struct symt_thunk*
symt_new_thunk(struct module* module,
struct symt_compiland* parent,
@@ -584,10 +649,12 @@ extern struct symt_hierarchy_point*
symt_new_label(struct module* module,
struct symt_compiland* compiland,
const char* name, unsigned long address);
extern struct symt* symt_index2ptr(struct module* module, DWORD id);
extern DWORD symt_ptr2index(struct module* module, const struct symt* sym);
/* type.c */
extern void symt_init_basic(struct module* module);
extern BOOL symt_get_info(const struct symt* type,
extern BOOL symt_get_info(struct module* module, const struct symt* type,
IMAGEHLP_SYMBOL_TYPE_INFO req, void* pInfo);
extern struct symt_basic*
symt_new_basic(struct module* module, enum BasicType,
+169 -42
View File
@@ -72,7 +72,7 @@ static void dump(const void* ptr, unsigned len)
int i, j;
BYTE msg[128];
static const char hexof[] = "0123456789abcdef";
const BYTE* x = (const BYTE*)ptr;
const BYTE* x = ptr;
for (i = 0; i < len; i += 16)
{
@@ -217,7 +217,7 @@ static unsigned char dwarf2_parse_byte(dwarf2_traverse_context_t* ctx)
static unsigned short dwarf2_get_u2(const unsigned char* ptr)
{
return *(const unsigned short*)ptr;
return *(const UINT16*)ptr;
}
static unsigned short dwarf2_parse_u2(dwarf2_traverse_context_t* ctx)
@@ -229,7 +229,7 @@ static unsigned short dwarf2_parse_u2(dwarf2_traverse_context_t* ctx)
static unsigned long dwarf2_get_u4(const unsigned char* ptr)
{
return *(const unsigned long*)ptr;
return *(const UINT32*)ptr;
}
static unsigned long dwarf2_parse_u4(dwarf2_traverse_context_t* ctx)
@@ -239,6 +239,18 @@ static unsigned long dwarf2_parse_u4(dwarf2_traverse_context_t* ctx)
return uvalue;
}
static DWORD64 dwarf2_get_u8(const unsigned char* ptr)
{
return *(const UINT64*)ptr;
}
static DWORD64 dwarf2_parse_u8(dwarf2_traverse_context_t* ctx)
{
DWORD64 uvalue = dwarf2_get_u8(ctx->data);
ctx->data += 8;
return uvalue;
}
static unsigned long dwarf2_get_leb128_as_unsigned(const unsigned char* ptr, const unsigned char** end)
{
unsigned long ret = 0;
@@ -309,6 +321,13 @@ static unsigned dwarf2_leb128_length(const dwarf2_traverse_context_t* ctx)
return ret + 1;
}
/******************************************************************
* dwarf2_get_addr
*
* Returns an address.
* We assume that in all cases word size from Dwarf matches the size of
* addresses in platform where the exec is compiled.
*/
static unsigned long dwarf2_get_addr(const unsigned char* ptr, unsigned word_size)
{
unsigned long ret;
@@ -318,6 +337,9 @@ static unsigned long dwarf2_get_addr(const unsigned char* ptr, unsigned word_siz
case 4:
ret = dwarf2_get_u4(ptr);
break;
case 8:
ret = dwarf2_get_u8(ptr);
break;
default:
FIXME("Unsupported Word Size %u\n", word_size);
ret = 0;
@@ -490,7 +512,9 @@ static void dwarf2_fill_attr(const dwarf2_parse_context_t* ctx,
break;
case DW_FORM_data8:
FIXME("Unhandled 64bits support\n");
attr->u.block.size = 8;
attr->u.block.ptr = data;
data += 8;
break;
case DW_FORM_ref1:
@@ -652,7 +676,7 @@ static enum location_error
compute_location(dwarf2_traverse_context_t* ctx, struct location* loc,
HANDLE hproc, const struct location* frame)
{
unsigned long stack[64];
DWORD_PTR tmp, stack[64];
unsigned stk;
unsigned char op;
BOOL piece_found = FALSE;
@@ -665,27 +689,11 @@ compute_location(dwarf2_traverse_context_t* ctx, struct location* loc,
while (ctx->data < ctx->end_data)
{
op = dwarf2_parse_byte(ctx);
switch (op)
if (op >= DW_OP_lit0 && op <= DW_OP_lit31)
stack[++stk] = op - DW_OP_lit0;
else if (op >= DW_OP_reg0 && op <= DW_OP_reg31)
{
case DW_OP_addr: stack[++stk] = dwarf2_parse_addr(ctx); break;
case DW_OP_const1u: stack[++stk] = dwarf2_parse_byte(ctx); break;
case DW_OP_const1s: stack[++stk] = (long)(signed char)dwarf2_parse_byte(ctx); break;
case DW_OP_const2u: stack[++stk] = dwarf2_parse_u2(ctx); break;
case DW_OP_const2s: stack[++stk] = (long)(short)dwarf2_parse_u2(ctx); break;
case DW_OP_const4u: stack[++stk] = dwarf2_parse_u4(ctx); break;
case DW_OP_const4s: stack[++stk] = dwarf2_parse_u4(ctx); break;
case DW_OP_constu: stack[++stk] = dwarf2_leb128_as_unsigned(ctx); break;
case DW_OP_consts: stack[++stk] = dwarf2_leb128_as_signed(ctx); break;
case DW_OP_plus_uconst:
stack[stk] += dwarf2_leb128_as_unsigned(ctx); break;
case DW_OP_reg0: case DW_OP_reg1: case DW_OP_reg2: case DW_OP_reg3:
case DW_OP_reg4: case DW_OP_reg5: case DW_OP_reg6: case DW_OP_reg7:
case DW_OP_reg8: case DW_OP_reg9: case DW_OP_reg10: case DW_OP_reg11:
case DW_OP_reg12: case DW_OP_reg13: case DW_OP_reg14: case DW_OP_reg15:
case DW_OP_reg16: case DW_OP_reg17: case DW_OP_reg18: case DW_OP_reg19:
case DW_OP_reg20: case DW_OP_reg21: case DW_OP_reg22: case DW_OP_reg23:
case DW_OP_reg24: case DW_OP_reg25: case DW_OP_reg26: case DW_OP_reg27:
case DW_OP_reg28: case DW_OP_reg29: case DW_OP_reg30: case DW_OP_reg31:
/* dbghelp APIs don't know how to cope with this anyway
* (for example 'long long' stored in two registers)
* FIXME: We should tell winedbg how to deal with it (sigh)
@@ -698,15 +706,9 @@ compute_location(dwarf2_traverse_context_t* ctx, struct location* loc,
loc->reg = dwarf2_map_register(op - DW_OP_reg0);
}
loc->kind = loc_register;
break;
case DW_OP_breg0: case DW_OP_breg1: case DW_OP_breg2: case DW_OP_breg3:
case DW_OP_breg4: case DW_OP_breg5: case DW_OP_breg6: case DW_OP_breg7:
case DW_OP_breg8: case DW_OP_breg9: case DW_OP_breg10: case DW_OP_breg11:
case DW_OP_breg12: case DW_OP_breg13: case DW_OP_breg14: case DW_OP_breg15:
case DW_OP_breg16: case DW_OP_breg17: case DW_OP_breg18: case DW_OP_breg19:
case DW_OP_breg20: case DW_OP_breg21: case DW_OP_breg22: case DW_OP_breg23:
case DW_OP_breg24: case DW_OP_breg25: case DW_OP_breg26: case DW_OP_breg27:
case DW_OP_breg28: case DW_OP_breg29: case DW_OP_breg30: case DW_OP_breg31:
}
else if (op >= DW_OP_breg0 && op <= DW_OP_breg31)
{
/* dbghelp APIs don't know how to cope with this anyway
* (for example 'long long' stored in two registers)
* FIXME: We should tell winedbg how to deal with it (sigh)
@@ -714,13 +716,71 @@ compute_location(dwarf2_traverse_context_t* ctx, struct location* loc,
if (!piece_found)
{
if (loc->reg != Wine_DW_no_register)
FIXME("Only supporting one reg (%d -> %d)\n",
FIXME("Only supporting one breg (%d -> %d)\n",
loc->reg, dwarf2_map_register(op - DW_OP_breg0));
loc->reg = dwarf2_map_register(op - DW_OP_breg0);
}
stack[++stk] = dwarf2_leb128_as_signed(ctx);
loc->kind = loc_regrel;
break;
}
else switch (op)
{
case DW_OP_nop: break;
case DW_OP_addr: stack[++stk] = dwarf2_parse_addr(ctx); break;
case DW_OP_const1u: stack[++stk] = dwarf2_parse_byte(ctx); break;
case DW_OP_const1s: stack[++stk] = dwarf2_parse_byte(ctx); break;
case DW_OP_const2u: stack[++stk] = dwarf2_parse_u2(ctx); break;
case DW_OP_const2s: stack[++stk] = dwarf2_parse_u2(ctx); break;
case DW_OP_const4u: stack[++stk] = dwarf2_parse_u4(ctx); break;
case DW_OP_const4s: stack[++stk] = dwarf2_parse_u4(ctx); break;
case DW_OP_const8u: stack[++stk] = dwarf2_parse_u8(ctx); break;
case DW_OP_const8s: stack[++stk] = dwarf2_parse_u8(ctx); break;
case DW_OP_constu: stack[++stk] = dwarf2_leb128_as_unsigned(ctx); break;
case DW_OP_consts: stack[++stk] = dwarf2_leb128_as_signed(ctx); break;
case DW_OP_dup: stack[stk + 1] = stack[stk]; stk++; break;
case DW_OP_drop: stk--; break;
case DW_OP_over: stack[stk + 1] = stack[stk - 1]; stk++; break;
case DW_OP_pick: stack[stk + 1] = stack[stk - dwarf2_parse_byte(ctx)]; stk++; break;
case DW_OP_swap: tmp = stack[stk]; stack[stk] = stack[stk-1]; stack[stk-1] = tmp; break;
case DW_OP_rot: tmp = stack[stk]; stack[stk] = stack[stk-1]; stack[stk-1] = stack[stk-2]; stack[stk-2] = tmp; break;
case DW_OP_abs: stack[stk] = labs(stack[stk]); break;
case DW_OP_neg: stack[stk] = -stack[stk]; break;
case DW_OP_not: stack[stk] = ~stack[stk]; break;
case DW_OP_and: stack[stk-1] &= stack[stk]; stk--; break;
case DW_OP_or: stack[stk-1] |= stack[stk]; stk--; break;
case DW_OP_minus: stack[stk-1] -= stack[stk]; stk--; break;
case DW_OP_mul: stack[stk-1] *= stack[stk]; stk--; break;
case DW_OP_plus: stack[stk-1] += stack[stk]; stk--; break;
case DW_OP_xor: stack[stk-1] ^= stack[stk]; stk--; break;
case DW_OP_shl: stack[stk-1] <<= stack[stk]; stk--; break;
case DW_OP_shr: stack[stk-1] >>= stack[stk]; stk--; break;
case DW_OP_plus_uconst: stack[stk] += dwarf2_leb128_as_unsigned(ctx); break;
case DW_OP_shra: stack[stk-1] = stack[stk-1] / (1 << stack[stk]); stk--; break;
case DW_OP_div: stack[stk-1] = stack[stk-1] / stack[stk]; stk--; break;
case DW_OP_mod: stack[stk-1] = stack[stk-1] % stack[stk]; stk--; break;
case DW_OP_ge: stack[stk-1] = (stack[stk-1] >= stack[stk]); stk--; break;
case DW_OP_gt: stack[stk-1] = (stack[stk-1] > stack[stk]); stk--; break;
case DW_OP_le: stack[stk-1] = (stack[stk-1] <= stack[stk]); stk--; break;
case DW_OP_lt: stack[stk-1] = (stack[stk-1] < stack[stk]); stk--; break;
case DW_OP_eq: stack[stk-1] = (stack[stk-1] == stack[stk]); stk--; break;
case DW_OP_ne: stack[stk-1] = (stack[stk-1] != stack[stk]); stk--; break;
case DW_OP_skip: tmp = dwarf2_parse_u2(ctx); ctx->data += tmp; break;
case DW_OP_bra: tmp = dwarf2_parse_u2(ctx); if (!stack[stk--]) ctx->data += tmp; break;
case DW_OP_regx:
if (loc->reg != Wine_DW_no_register)
FIXME("Only supporting one regx\n");
loc->reg = dwarf2_map_register(dwarf2_leb128_as_unsigned(ctx));
loc->kind = loc_register;
break;
case DW_OP_bregx:
tmp = dwarf2_leb128_as_unsigned(ctx);
ctx->data++;
if (loc->reg != Wine_DW_no_register)
FIXME("Only supporting one regx\n");
loc->reg = dwarf2_map_register(tmp) + dwarf2_leb128_as_signed(ctx);
loc->kind = loc_register;
break;
case DW_OP_fbreg:
if (loc->reg != Wine_DW_no_register)
FIXME("Only supporting one reg (%d -> -2)\n", loc->reg);
@@ -765,12 +825,12 @@ compute_location(dwarf2_traverse_context_t* ctx, struct location* loc,
}
if (hproc)
{
DWORD addr = stack[stk--];
DWORD deref;
DWORD_PTR addr = stack[stk--];
DWORD_PTR deref;
if (!ReadProcessMemory(hproc, (void*)addr, &deref, sizeof(deref), NULL))
{
WARN("Couldn't read memory at %x\n", addr);
WARN("Couldn't read memory at %lx\n", addr);
return loc_err_cant_read;
}
stack[++stk] = deref;
@@ -780,8 +840,46 @@ compute_location(dwarf2_traverse_context_t* ctx, struct location* loc,
loc->kind = loc_dwarf2_block;
}
break;
case DW_OP_deref_size:
if (!stk)
{
FIXME("Unexpected empty stack\n");
return loc_err_internal;
}
if (loc->reg != Wine_DW_no_register)
{
WARN("Too complex expression for deref\n");
return loc_err_too_complex;
}
if (hproc)
{
DWORD_PTR addr = stack[stk--];
BYTE derefsize = dwarf2_parse_byte(ctx);
DWORD64 deref;
if (!ReadProcessMemory(hproc, (void*)addr, &deref, derefsize, NULL))
{
WARN("Couldn't read memory at %lx\n", addr);
return loc_err_cant_read;
}
switch (derefsize)
{
case 1: stack[++stk] = *(unsigned char*)&deref; break;
case 2: stack[++stk] = *(unsigned short*)&deref; break;
case 4: stack[++stk] = *(DWORD*)&deref; break;
case 8: if (ctx->word_size >= derefsize) stack[++stk] = deref; break;
}
}
else
{
loc->kind = loc_dwarf2_block;
}
break;
default:
FIXME("Unhandled attr op: %x\n", op);
if (op < DW_OP_lo_user) /* as DW_OP_hi_user is 0xFF, we don't need to test against it */
FIXME("Unhandled attr op: %x\n", op);
/* FIXME else unhandled extension */
return loc_err_internal;
}
}
@@ -1163,7 +1261,8 @@ static void dwarf2_parse_udt_member(dwarf2_parse_context_t* ctx,
if (!dwarf2_find_attribute(ctx, di, DW_AT_byte_size, &nbytes))
{
DWORD64 size;
nbytes.u.uvalue = symt_get_info(elt_type, TI_GET_LENGTH, &size) ? (unsigned long)size : 0;
nbytes.u.uvalue = symt_get_info(ctx->module, elt_type, TI_GET_LENGTH, &size) ?
(unsigned long)size : 0;
}
bit_offset.u.uvalue = nbytes.u.uvalue * 8 - bit_offset.u.uvalue - bit_size.u.uvalue;
}
@@ -1214,6 +1313,10 @@ static struct symt* dwarf2_parse_udt_type(dwarf2_parse_context_t* ctx,
case DW_TAG_union_type:
case DW_TAG_typedef:
/* FIXME: we need to handle nested udt definitions */
case DW_TAG_inheritance:
case DW_TAG_subprogram:
case DW_TAG_variable:
/* FIXME: some C++ related stuff */
break;
default:
FIXME("Unhandled Tag type 0x%lx at %s, for %s\n",
@@ -1334,6 +1437,8 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm,
switch (loc.kind)
{
case loc_error:
break;
case loc_absolute:
/* it's a global variable */
/* FIXME: we don't handle its scope yet */
@@ -1389,11 +1494,28 @@ static void dwarf2_parse_variable(dwarf2_subprogram_t* subpgm,
v.n1.n2.n3.byref = pool_strdup(&subpgm->ctx->module->pool, value.u.string);
break;
case DW_FORM_data8:
case DW_FORM_block:
case DW_FORM_block1:
case DW_FORM_block2:
case DW_FORM_block4:
v.n1.n2.vt = VT_I4;
switch (value.u.block.size)
{
case 1: v.n1.n2.n3.lVal = *(BYTE*)value.u.block.ptr; break;
case 2: v.n1.n2.n3.lVal = *(USHORT*)value.u.block.ptr; break;
case 4: v.n1.n2.n3.lVal = *(DWORD*)value.u.block.ptr; break;
default:
v.n1.n2.vt = VT_I1 | VT_BYREF;
v.n1.n2.n3.byref = pool_alloc(&subpgm->ctx->module->pool, value.u.block.size);
memcpy(v.n1.n2.n3.byref, value.u.block.ptr, value.u.block.size);
}
break;
case DW_FORM_data8:
v.n1.n2.vt = VT_I1 | VT_BYREF;
v.n1.n2.n3.byref = pool_alloc(&subpgm->ctx->module->pool, value.u.block.size);
memcpy(v.n1.n2.n3.byref, value.u.block.ptr, value.u.block.size);
break;
default:
FIXME("Unsupported form for const value %s (%lx)\n",
@@ -1786,6 +1908,11 @@ static void dwarf2_load_one_entry(dwarf2_parse_context_t* ctx,
dwarf2_parse_variable(&subpgm, NULL, di);
}
break;
/* silence a couple of C++ defines */
case DW_TAG_namespace:
case DW_TAG_imported_module:
case DW_TAG_imported_declaration:
break;
default:
FIXME("Unhandled Tag type 0x%lx at %s, for %lu\n",
di->abbrev->tag, dwarf2_debug_ctx(ctx), di->abbrev->entry_code);
@@ -2010,7 +2137,7 @@ static BOOL dwarf2_parse_compilation_unit(const dwarf2_section_t* sections,
cu_ctx.word_size = dwarf2_parse_byte(&cu_ctx);
TRACE("Compilation Unit Header found at 0x%x:\n",
comp_unit_start - sections[section_debug].address);
(int)(comp_unit_start - sections[section_debug].address));
TRACE("- length: %lu\n", cu_length);
TRACE("- version: %u\n", cu_version);
TRACE("- abbrev_offset: %lu\n", cu_abbrev_offset);
+12
View File
@@ -376,6 +376,18 @@ typedef enum dwarf_operation_e
DW_OP_call2 = 0x98,
DW_OP_call4 = 0x99,
DW_OP_call_ref = 0x9a,
DW_OP_form_tls_address = 0x9b,
DW_OP_call_frame_cfa = 0x9c,
DW_OP_bit_piece = 0x9d,
/* Implementation defined extensions */
DW_OP_lo_user = 0xe0,
DW_OP_hi_user = 0xff,
/* GNU extensions */
DW_OP_GNU_push_tls_address = 0xe0,
DW_OP_GNU_uninit = 0xf0,
DW_OP_GNU_encoded_addr = 0xf1,
} dwarf_operation_t;
enum dwarf_calling_convention
+59 -165
View File
@@ -77,7 +77,7 @@
struct elf_module_info
{
unsigned long elf_addr;
DWORD_PTR elf_addr;
unsigned short elf_mark : 1,
elf_loader : 1;
};
@@ -93,22 +93,36 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
struct elf_info
{
unsigned flags; /* IN one (or several) of the ELF_INFO constants */
unsigned long dbg_hdr_addr; /* OUT address of debug header (if ELF_INFO_DEBUG_HEADER is set) */
DWORD_PTR dbg_hdr_addr; /* OUT address of debug header (if ELF_INFO_DEBUG_HEADER is set) */
struct module* module; /* OUT loaded module (if ELF_INFO_MODULE is set) */
const WCHAR* module_name; /* OUT found module name (if ELF_INFO_NAME is set) */
};
#ifdef _WIN64
#define Elf_Ehdr Elf64_Ehdr
#define Elf_Shdr Elf64_Shdr
#define Elf_Phdr Elf64_Phdr
#define Elf_Dyn Elf64_Dyn
#define Elf_Sym Elf64_Sym
#else
#define Elf_Ehdr Elf32_Ehdr
#define Elf_Shdr Elf32_Shdr
#define Elf_Phdr Elf32_Phdr
#define Elf_Dyn Elf32_Dyn
#define Elf_Sym Elf32_Sym
#endif
/* structure holding information while handling an ELF image
* allows one by one section mapping for memory savings
*/
struct elf_file_map
{
Elf32_Ehdr elfhdr;
Elf_Ehdr elfhdr;
size_t elf_size;
size_t elf_start;
struct
{
Elf32_Shdr shdr;
Elf_Shdr shdr;
const char* mapped;
}* sect;
int fd;
@@ -125,7 +139,7 @@ struct elf_section_map
struct symtab_elt
{
struct hash_table_elt ht_elt;
const Elf32_Sym* symp;
const Elf_Sym* symp;
struct symt_compiland* compiland;
unsigned used;
};
@@ -237,7 +251,7 @@ static void elf_end_find(struct elf_file_map* fmap)
*
* Get the size of an ELF section
*/
static inline unsigned elf_get_map_size(struct elf_section_map* esm)
static inline unsigned elf_get_map_size(const struct elf_section_map* esm)
{
if (esm->sidx < 0 || esm->sidx >= esm->fmap->elfhdr.e_shnum)
return 0;
@@ -254,7 +268,7 @@ static BOOL elf_map_file(const WCHAR* filenameW, struct elf_file_map* fmap)
static const BYTE elf_signature[4] = { ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3 };
struct stat statbuf;
int i;
Elf32_Phdr phdr;
Elf_Phdr phdr;
unsigned tmp, page_mask = getpagesize() - 1;
char* filename;
unsigned len;
@@ -279,7 +293,12 @@ static BOOL elf_map_file(const WCHAR* filenameW, struct elf_file_map* fmap)
/* and check for an ELF header */
if (memcmp(fmap->elfhdr.e_ident,
elf_signature, sizeof(elf_signature))) goto done;
/* and check 32 vs 64 size according to current machine */
#ifdef _WIN64
if (fmap->elfhdr.e_ident[EI_CLASS] != ELFCLASS64) goto done;
#else
if (fmap->elfhdr.e_ident[EI_CLASS] != ELFCLASS32) goto done;
#endif
fmap->sect = HeapAlloc(GetProcessHeap(), 0,
fmap->elfhdr.e_shnum * sizeof(fmap->sect[0]));
if (!fmap->sect) goto done;
@@ -350,7 +369,7 @@ int elf_is_in_thunk_area(unsigned long addr,
{
unsigned i;
for (i = 0; thunks[i].symname; i++)
if (thunks) for (i = 0; thunks[i].symname; i++)
{
if (addr >= thunks[i].rva_start && addr < thunks[i].rva_end)
return i;
@@ -372,13 +391,13 @@ static void elf_hash_symtab(struct module* module, struct pool* pool,
const char* symname;
struct symt_compiland* compiland = NULL;
const char* ptr;
const Elf32_Sym* symp;
const Elf_Sym* symp;
struct symtab_elt* ste;
struct elf_section_map esm, esm_str;
if (!elf_find_section(fmap, ".symtab", SHT_SYMTAB, &esm) &&
!elf_find_section(fmap, ".dynsym", SHT_DYNSYM, &esm)) return;
if ((symp = (const Elf32_Sym*)elf_map_section(&esm)) == ELF_NO_MAP) return;
if ((symp = (const Elf_Sym*)elf_map_section(&esm)) == ELF_NO_MAP) return;
esm_str.fmap = fmap;
esm_str.sidx = fmap->sect[esm.sidx].shdr.sh_link;
if ((strp = elf_map_section(&esm_str)) == ELF_NO_MAP) return;
@@ -471,9 +490,9 @@ static void elf_hash_symtab(struct module* module, struct pool* pool,
*
* lookup a symbol by name in our internal hash table for the symtab
*/
static const Elf32_Sym* elf_lookup_symtab(const struct module* module,
static const Elf_Sym* elf_lookup_symtab(const struct module* module,
const struct hash_table* ht_symtab,
const char* name, struct symt* compiland)
const char* name, const struct symt* compiland)
{
struct symtab_elt* weak_result = NULL; /* without compiland name */
struct symtab_elt* result = NULL;
@@ -490,7 +509,7 @@ static const Elf32_Sym* elf_lookup_symtab(const struct module* module,
if (compiland)
{
compiland_name = source_get(module,
((struct symt_compiland*)compiland)->source);
((const struct symt_compiland*)compiland)->source);
compiland_basename = strrchr(compiland_name, '/');
if (!compiland_basename++) compiland_basename = compiland_name;
}
@@ -542,12 +561,12 @@ static const Elf32_Sym* elf_lookup_symtab(const struct module* module,
* - get any relevant information (address & size) from the bits we got from the
* stabs debugging information
*/
static void elf_finish_stabs_info(struct module* module, struct hash_table* symtab)
static void elf_finish_stabs_info(struct module* module, const struct hash_table* symtab)
{
struct hash_table_iter hti;
void* ptr;
struct symt_ht* sym;
const Elf32_Sym* symp;
const Elf_Sym* symp;
hash_table_iter_init(&module->ht_symbols, &hti, NULL);
while ((ptr = hash_table_iter_up(&hti)))
@@ -623,13 +642,13 @@ static void elf_finish_stabs_info(struct module* module, struct hash_table* symt
*
* creating the thunk objects for a wine native DLL
*/
static int elf_new_wine_thunks(struct module* module, struct hash_table* ht_symtab,
static int elf_new_wine_thunks(struct module* module, const struct hash_table* ht_symtab,
const struct elf_thunk_area* thunks)
{
int j;
struct hash_table_iter hti;
struct symtab_elt* ste;
DWORD addr;
DWORD_PTR addr;
struct symt_ht* symt;
hash_table_iter_init(ht_symtab, &hti, NULL);
@@ -650,8 +669,8 @@ static int elf_new_wine_thunks(struct module* module, struct hash_table* ht_symt
ULONG64 ref_addr;
symt = symt_find_nearest(module, addr);
if (symt)
symt_get_info(&symt->symt, TI_GET_ADDRESS, &ref_addr);
if (symt && !symt_get_info(module, &symt->symt, TI_GET_ADDRESS, &ref_addr))
ref_addr = addr;
if (!symt || addr != ref_addr)
{
/* creating public symbols for all the ELF symbols which haven't been
@@ -687,9 +706,9 @@ static int elf_new_wine_thunks(struct module* module, struct hash_table* ht_symt
ULONG64 xaddr = 0, xsize = 0;
DWORD kind = -1;
symt_get_info(&symt->symt, TI_GET_ADDRESS, &xaddr);
symt_get_info(&symt->symt, TI_GET_LENGTH, &xsize);
symt_get_info(&symt->symt, TI_GET_DATAKIND, &kind);
symt_get_info(module, &symt->symt, TI_GET_ADDRESS, &xaddr);
symt_get_info(module, &symt->symt, TI_GET_LENGTH, &xsize);
symt_get_info(module, &symt->symt, TI_GET_DATAKIND, &kind);
/* If none of symbols has a correct size, we consider they are both markers
* Hence, we can silence this warning
@@ -698,7 +717,7 @@ static int elf_new_wine_thunks(struct module* module, struct hash_table* ht_symt
*/
if ((xsize || ste->symp->st_size) &&
(kind == (ELF32_ST_BIND(ste->symp->st_info) == STB_LOCAL) ? DataIsFileStatic : DataIsGlobal))
FIXME("Duplicate in %s: %s<%08x-%08x> %s<%s-%s>\n",
FIXME("Duplicate in %s: %s<%08lx-%08x> %s<%s-%s>\n",
debugstr_w(module->module.ModuleName),
ste->ht_elt.name, addr, (unsigned int)ste->symp->st_size,
symt->hash_elt.name,
@@ -716,7 +735,7 @@ static int elf_new_wine_thunks(struct module* module, struct hash_table* ht_symt
*
* Creates a set of public symbols from an ELF symtab
*/
static int elf_new_public_symbols(struct module* module, struct hash_table* symtab)
static int elf_new_public_symbols(struct module* module, const struct hash_table* symtab)
{
struct hash_table_iter hti;
struct symtab_elt* ste;
@@ -730,142 +749,19 @@ static int elf_new_public_symbols(struct module* module, struct hash_table* symt
{
symt_new_public(module, ste->compiland, ste->ht_elt.name,
module->elf_info->elf_addr + ste->symp->st_value,
ste->symp->st_size, TRUE /* FIXME */,
ELF32_ST_TYPE(ste->symp->st_info) == STT_FUNC);
ste->symp->st_size);
}
return TRUE;
}
/* Copyright (C) 1986 Gary S. Brown. Modified by Robert Shearman. You may use
the following calc_crc32 code or tables extracted from it, as desired without
restriction. */
/**********************************************************************\
|* Demonstration program to compute the 32-bit CRC used as the frame *|
|* check sequence in ADCCP (ANSI X3.66, also known as FIPS PUB 71 *|
|* and FED-STD-1003, the U.S. versions of CCITT's X.25 link-level *|
|* protocol). The 32-bit FCS was added via the Federal Register, *|
|* 1 June 1982, p.23798. I presume but don't know for certain that *|
|* this polynomial is or will be included in CCITT V.41, which *|
|* defines the 16-bit CRC (often called CRC-CCITT) polynomial. FIPS *|
|* PUB 78 says that the 32-bit FCS reduces otherwise undetected *|
|* errors by a factor of 10^-5 over 16-bit FCS. *|
\**********************************************************************/
/* First, the polynomial itself and its table of feedback terms. The */
/* polynomial is */
/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
/* Note that we take it "backwards" and put the highest-order term in */
/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */
/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */
/* the MSB being 1. */
/* Note that the usual hardware shift register implementation, which */
/* is what we're using (we're merely optimizing it by doing eight-bit */
/* chunks at a time) shifts bits into the lowest-order term. In our */
/* implementation, that means shifting towards the right. Why do we */
/* do it this way? Because the calculated CRC must be transmitted in */
/* order from highest-order term to lowest-order term. UARTs transmit */
/* characters in order from LSB to MSB. By storing the CRC this way, */
/* we hand it to the UART in the order low-byte to high-byte; the UART */
/* sends each low-bit to hight-bit; and the result is transmission bit */
/* by bit from highest- to lowest-order term without requiring any bit */
/* shuffling on our part. Reception works similarly. */
/* The feedback terms table consists of 256, 32-bit entries. Notes: */
/* */
/* 1. The table can be generated at runtime if desired; code to do so */
/* is shown later. It might not be obvious, but the feedback */
/* terms simply represent the results of eight shift/xor opera- */
/* tions for all combinations of data and CRC register values. */
/* */
/* 2. The CRC accumulation logic is the same for all CRC polynomials, */
/* be they sixteen or thirty-two bits wide. You simply choose the */
/* appropriate table. Alternatively, because the table can be */
/* generated at runtime, you can start by generating the table for */
/* the polynomial in question and use exactly the same "updcrc", */
/* if your application needn't simultaneously handle two CRC */
/* polynomials. (Note, however, that XMODEM is strange.) */
/* */
/* 3. For 16-bit CRCs, the table entries need be only 16 bits wide; */
/* of course, 32-bit entries work OK if the high 16 bits are zero. */
/* */
/* 4. The values must be right-shifted by eight bits by the "updcrc" */
/* logic; the shift must be unsigned (bring in zeroes). On some */
/* hardware you could probably optimize the shift in assembler by */
/* using byte-swap instructions. */
static DWORD calc_crc32(struct elf_file_map* fmap)
{
#define UPDC32(octet,crc) (crc_32_tab[((crc) ^ (octet)) & 0xff] ^ ((crc) >> 8))
static const DWORD crc_32_tab[] =
{ /* CRC polynomial 0xedb88320 */
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
int i, r;
unsigned char buffer[256];
DWORD crc = ~0;
lseek(fmap->fd, 0, SEEK_SET);
while ((r = read(fmap->fd, buffer, sizeof(buffer))) > 0)
{
for (i = 0; i < r; i++) crc = UPDC32(buffer[i], crc);
}
return ~crc;
#undef UPDC32
}
static BOOL elf_check_debug_link(const WCHAR* file, struct elf_file_map* fmap, DWORD crc)
{
BOOL ret;
if (!elf_map_file(file, fmap)) return FALSE;
if (!(ret = crc == calc_crc32(fmap)))
if (!(ret = crc == calc_crc32(fmap->fd)))
{
WARN("Bad CRC for file %s (got %08x while expecting %08x)\n",
debugstr_w(file), calc_crc32(fmap), crc);
debugstr_w(file), calc_crc32(fmap->fd), crc);
elf_unmap_file(fmap);
}
return ret;
@@ -952,7 +848,7 @@ found:
* Parses a .gnu_debuglink section and loads the debug info from
* the external file specified there.
*/
static BOOL elf_debuglink_parse(struct elf_file_map* fmap, struct module* module,
static BOOL elf_debuglink_parse(struct elf_file_map* fmap, const struct module* module,
const BYTE* debuglink)
{
/* The content of a debug link section is:
@@ -1039,7 +935,8 @@ static BOOL elf_load_debug_info_from_map(struct module* module,
/* OK, now just parse all of the stabs. */
lret = stabs_parse(module, module->elf_info->elf_addr,
stab, elf_get_map_size(&stab_sect),
stabstr, elf_get_map_size(&stabstr_sect));
stabstr, elf_get_map_size(&stabstr_sect),
NULL, NULL);
if (lret)
/* and fill in the missing information for stabs */
elf_finish_stabs_info(module, ht_symtab);
@@ -1160,7 +1057,7 @@ BOOL elf_fetch_file_info(const WCHAR* name, DWORD* base,
if (!elf_map_file(name, &fmap)) return FALSE;
if (base) *base = fmap.elf_start;
*size = fmap.elf_size;
*checksum = calc_crc32(&fmap);
*checksum = calc_crc32(fmap.fd);
elf_unmap_file(&fmap);
return TRUE;
}
@@ -1184,7 +1081,7 @@ static BOOL elf_load_file(struct process* pcs, const WCHAR* filename,
TRACE("Processing elf file '%s' at %08lx\n", debugstr_w(filename), load_offset);
if (!elf_map_file(filename, &fmap)) goto leave;
if (!elf_map_file(filename, &fmap)) return ret;
/* Next, we need to find a few of the internal ELF headers within
* this thing. We need the main executable header, and the section
@@ -1206,7 +1103,7 @@ static BOOL elf_load_file(struct process* pcs, const WCHAR* filename,
if (elf_find_section(&fmap, ".dynamic", SHT_DYNAMIC, &esm))
{
Elf32_Dyn dyn;
Elf_Dyn dyn;
char* ptr = (char*)fmap.sect[esm.sidx].shdr.sh_addr;
unsigned long len;
@@ -1234,7 +1131,7 @@ static BOOL elf_load_file(struct process* pcs, const WCHAR* filename,
if (!elf_module_info) goto leave;
elf_info->module = module_new(pcs, filename, DMT_ELF, FALSE,
(load_offset) ? load_offset : fmap.elf_start,
fmap.elf_size, 0, calc_crc32(&fmap));
fmap.elf_size, 0, calc_crc32(fmap.fd));
if (!elf_info->module)
{
HeapFree(GetProcessHeap(), 0, elf_module_info);
@@ -1389,7 +1286,7 @@ static BOOL elf_search_and_load_file(struct process* pcs, const WCHAR* filename,
*/
static BOOL elf_enum_modules_internal(const struct process* pcs,
const WCHAR* main_name,
elf_enum_modules_cb cb, void* user)
enum_modules_cb cb, void* user)
{
struct r_debug dbg_hdr;
void* lm_addr;
@@ -1492,9 +1389,7 @@ static BOOL elf_search_loader(struct process* pcs, struct elf_info* elf_info)
const char* ptr;
/* All binaries are loaded with WINELOADER (if run from tree) or by the
* main executable (either wine-kthread or wine-pthread)
* FIXME: the heuristic used to know whether we need to load wine-pthread
* or wine-kthread is not 100% safe
* main executable
*/
if ((ptr = getenv("WINELOADER")))
{
@@ -1504,8 +1399,7 @@ static BOOL elf_search_loader(struct process* pcs, struct elf_info* elf_info)
}
else
{
ret = elf_search_and_load_file(pcs, S_WineKThreadW, 0, elf_info) ||
elf_search_and_load_file(pcs, S_WinePThreadW, 0, elf_info);
ret = elf_search_and_load_file(pcs, S_WineW, 0, elf_info);
}
return ret;
}
@@ -1533,7 +1427,7 @@ BOOL elf_read_wine_loader_dbg_info(struct process* pcs)
* This function doesn't require that someone has called SymInitialize
* on this very process.
*/
BOOL elf_enum_modules(HANDLE hProc, elf_enum_modules_cb cb, void* user)
BOOL elf_enum_modules(HANDLE hProc, enum_modules_cb cb, void* user)
{
struct process pcs;
struct elf_info elf_info;
@@ -1638,7 +1532,7 @@ BOOL elf_read_wine_loader_dbg_info(struct process* pcs)
return FALSE;
}
BOOL elf_enum_modules(HANDLE hProc, elf_enum_modules_cb cb, void* user)
BOOL elf_enum_modules(HANDLE hProc, enum_modules_cb cb, void* user)
{
return FALSE;
}
File diff suppressed because it is too large Load Diff
+100 -92
View File
@@ -34,7 +34,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
struct dump_memory
{
ULONG base;
ULONG64 base;
ULONG size;
ULONG rva;
};
@@ -42,7 +42,7 @@ struct dump_memory
struct dump_module
{
unsigned is_elf;
ULONG base;
ULONG64 base;
ULONG size;
DWORD timestamp;
DWORD checksum;
@@ -59,6 +59,7 @@ struct dump_context
/* module information */
struct dump_module* modules;
unsigned num_modules;
unsigned alloc_modules;
/* exception information */
/* output information */
MINIDUMP_TYPE type;
@@ -66,6 +67,7 @@ struct dump_context
RVA rva;
struct dump_memory* mem;
unsigned num_mem;
unsigned alloc_mem;
/* callback information */
MINIDUMP_CALLBACK_INFORMATION* cb;
};
@@ -98,10 +100,9 @@ static BOOL fetch_processes_info(struct dump_context* dc)
dc->spi = dc->pcs_buffer;
for (;;)
{
if (dc->spi->dwProcessID == dc->pid) return TRUE;
if (!dc->spi->dwOffset) break;
dc->spi = (SYSTEM_PROCESS_INFORMATION*)
((char*)dc->spi + dc->spi->dwOffset);
if (HandleToUlong(dc->spi->UniqueProcessId) == dc->pid) return TRUE;
if (!dc->spi->NextEntryOffset) break;
dc->spi = (SYSTEM_PROCESS_INFORMATION*)((char*)dc->spi + dc->spi->NextEntryOffset);
}
}
HeapFree(GetProcessHeap(), 0, dc->pcs_buffer);
@@ -114,58 +115,25 @@ static void fetch_thread_stack(struct dump_context* dc, const void* teb_addr,
const CONTEXT* ctx, MINIDUMP_MEMORY_DESCRIPTOR* mmd)
{
NT_TIB tib;
ADDRESS64 addr;
if (ReadProcessMemory(dc->hProcess, teb_addr, &tib, sizeof(tib), NULL))
if (ReadProcessMemory(dc->hProcess, teb_addr, &tib, sizeof(tib), NULL) &&
dbghelp_current_cpu &&
dbghelp_current_cpu->get_addr(NULL /* FIXME */, ctx, cpu_addr_stack, &addr) && addr.Mode == AddrModeFlat)
{
#ifdef __i386__
/* limiting the stack dumping to the size actually used */
if (ctx->Esp){
/* make sure ESP is within the established range of the stack. It could have
if (addr.Offset)
{
addr.Offset -= dbghelp_current_cpu->word_size;
/* make sure stack pointer is within the established range of the stack. It could have
been clobbered by whatever caused the original exception. */
if (ctx->Esp - 4 < (ULONG_PTR)tib.StackLimit || ctx->Esp - 4 > (ULONG_PTR)tib.StackBase)
if (addr.Offset < (ULONG_PTR)tib.StackLimit || addr.Offset > (ULONG_PTR)tib.StackBase)
mmd->StartOfMemoryRange = (ULONG_PTR)tib.StackLimit;
else
mmd->StartOfMemoryRange = (ctx->Esp - 4);
mmd->StartOfMemoryRange = addr.Offset;
}
else
mmd->StartOfMemoryRange = (ULONG_PTR)tib.StackLimit;
#elif defined(__powerpc__)
if (ctx->Iar){
/* make sure IAR is within the established range of the stack. It could have
been clobbered by whatever caused the original exception. */
if (ctx->Iar - 4 < (ULONG_PTR)tib.StackLimit || ctx->Iar - 4 > (ULONG_PTR)tib.StackBase)
mmd->StartOfMemoryRange = (ULONG_PTR)tib.StackLimit;
else
mmd->StartOfMemoryRange = (ctx->Iar - 4);
}
else
mmd->StartOfMemoryRange = (ULONG_PTR)tib.StackLimit;
#elif defined(__x86_64__)
if (ctx->Rsp){
/* make sure RSP is within the established range of the stack. It could have
been clobbered by whatever caused the original exception. */
if (ctx->Rsp - 8 < (ULONG_PTR)tib.StackLimit || ctx->Rsp - 8 > (ULONG_PTR)tib.StackBase)
mmd->StartOfMemoryRange = (ULONG_PTR)tib.StackLimit;
else
mmd->StartOfMemoryRange = (ctx->Rsp - 8);
}
else
mmd->StartOfMemoryRange = (ULONG_PTR)tib.StackLimit;
#else
#error unsupported CPU
#endif
mmd->Memory.DataSize = (ULONG_PTR)tib.StackBase - mmd->StartOfMemoryRange;
}
}
@@ -179,13 +147,13 @@ static BOOL fetch_thread_info(struct dump_context* dc, int thd_idx,
const MINIDUMP_EXCEPTION_INFORMATION* except,
MINIDUMP_THREAD* mdThd, CONTEXT* ctx)
{
DWORD tid = dc->spi->ti[thd_idx].dwThreadID;
DWORD tid = HandleToUlong(dc->spi->ti[thd_idx].ClientId.UniqueThread);
HANDLE hThread;
THREAD_BASIC_INFORMATION tbi;
memset(ctx, 0, sizeof(*ctx));
mdThd->ThreadId = dc->spi->ti[thd_idx].dwThreadID;
mdThd->ThreadId = tid;
mdThd->SuspendCount = 0;
mdThd->Teb = 0;
mdThd->Stack.StartOfMemoryRange = 0;
@@ -198,8 +166,7 @@ static BOOL fetch_thread_info(struct dump_context* dc, int thd_idx,
if ((hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, tid)) == NULL)
{
FIXME("Couldn't open thread %u (%u)\n",
dc->spi->ti[thd_idx].dwThreadID, GetLastError());
FIXME("Couldn't open thread %u (%u)\n", tid, GetLastError());
return FALSE;
}
@@ -230,7 +197,7 @@ static BOOL fetch_thread_info(struct dump_context* dc, int thd_idx,
ReadProcessMemory(dc->hProcess, except->ExceptionPointers,
&ep, sizeof(ep), NULL);
ReadProcessMemory(dc->hProcess, ep.ContextRecord,
&ctx, sizeof(ctx), NULL);
&lctx, sizeof(lctx), NULL);
pctx = &lctx;
}
else pctx = except->ExceptionPointers->ContextRecord;
@@ -251,27 +218,38 @@ static BOOL fetch_thread_info(struct dump_context* dc, int thd_idx,
* Add a module to a dump context
*/
static BOOL add_module(struct dump_context* dc, const WCHAR* name,
DWORD base, DWORD size, DWORD timestamp, DWORD checksum,
DWORD64 base, DWORD size, DWORD timestamp, DWORD checksum,
BOOL is_elf)
{
if (!dc->modules)
{
dc->alloc_modules = 32;
dc->modules = HeapAlloc(GetProcessHeap(), 0,
++dc->num_modules * sizeof(*dc->modules));
else
dc->alloc_modules * sizeof(*dc->modules));
}
else if(dc->num_modules >= dc->alloc_modules)
{
dc->alloc_modules *= 2;
dc->modules = HeapReAlloc(GetProcessHeap(), 0, dc->modules,
++dc->num_modules * sizeof(*dc->modules));
if (!dc->modules) return FALSE;
dc->alloc_modules * sizeof(*dc->modules));
}
if (!dc->modules)
{
dc->alloc_modules = dc->num_modules = 0;
return FALSE;
}
if (is_elf ||
!GetModuleFileNameExW(dc->hProcess, (HMODULE)base,
dc->modules[dc->num_modules - 1].name,
sizeof(dc->modules[dc->num_modules - 1].name) / sizeof(WCHAR)))
lstrcpynW(dc->modules[dc->num_modules - 1].name, name,
sizeof(dc->modules[dc->num_modules - 1].name) / sizeof(WCHAR));
dc->modules[dc->num_modules - 1].base = base;
dc->modules[dc->num_modules - 1].size = size;
dc->modules[dc->num_modules - 1].timestamp = timestamp;
dc->modules[dc->num_modules - 1].checksum = checksum;
dc->modules[dc->num_modules - 1].is_elf = is_elf;
!GetModuleFileNameExW(dc->hProcess, (HMODULE)(DWORD_PTR)base,
dc->modules[dc->num_modules].name,
sizeof(dc->modules[dc->num_modules].name) / sizeof(WCHAR)))
lstrcpynW(dc->modules[dc->num_modules].name, name,
sizeof(dc->modules[dc->num_modules].name) / sizeof(WCHAR));
dc->modules[dc->num_modules].base = base;
dc->modules[dc->num_modules].size = size;
dc->modules[dc->num_modules].timestamp = timestamp;
dc->modules[dc->num_modules].checksum = checksum;
dc->modules[dc->num_modules].is_elf = is_elf;
dc->num_modules++;
return TRUE;
}
@@ -284,13 +262,13 @@ static BOOL add_module(struct dump_context* dc, const WCHAR* name,
static BOOL WINAPI fetch_pe_module_info_cb(PCWSTR name, DWORD64 base, ULONG size,
PVOID user)
{
struct dump_context* dc = (struct dump_context*)user;
struct dump_context* dc = user;
IMAGE_NT_HEADERS nth;
if (!validate_addr64(base)) return FALSE;
if (pe_load_nt_header(dc->hProcess, base, &nth))
add_module((struct dump_context*)user, name, base, size,
add_module(user, name, base, size,
nth.FileHeader.TimeDateStamp, nth.OptionalHeader.CheckSum,
FALSE);
return TRUE;
@@ -304,7 +282,7 @@ static BOOL WINAPI fetch_pe_module_info_cb(PCWSTR name, DWORD64 base, ULONG size
static BOOL fetch_elf_module_info_cb(const WCHAR* name, unsigned long base,
void* user)
{
struct dump_context* dc = (struct dump_context*)user;
struct dump_context* dc = user;
DWORD rbase, size, checksum;
/* FIXME: there's no relevant timestamp on ELF modules */
@@ -318,6 +296,27 @@ static BOOL fetch_elf_module_info_cb(const WCHAR* name, unsigned long base,
return TRUE;
}
/******************************************************************
* fetch_macho_module_info_cb
*
* Callback for accumulating in dump_context a Mach-O modules set
*/
static BOOL fetch_macho_module_info_cb(const WCHAR* name, unsigned long base,
void* user)
{
struct dump_context* dc = (struct dump_context*)user;
DWORD rbase, size, checksum;
/* FIXME: there's no relevant timestamp on Mach-O modules */
/* NB: if we have a non-null base from the live-target use it. If we have
* a null base, then grab its base address from Mach-O file.
*/
if (!macho_fetch_file_info(name, &rbase, &size, &checksum))
size = checksum = 0;
add_module(dc, name, base ? base : rbase, size, 0 /* FIXME */, checksum, TRUE);
return TRUE;
}
static void fetch_modules_info(struct dump_context* dc)
{
EnumerateLoadedModulesW64(dc->hProcess, fetch_pe_module_info_cb, dc);
@@ -327,6 +326,7 @@ static void fetch_modules_info(struct dump_context* dc)
* a given application in a post mortem debugging condition.
*/
elf_enum_modules(dc->hProcess, fetch_elf_module_info_cb, dc);
macho_enum_modules(dc->hProcess, fetch_macho_module_info_cb, dc);
}
static void fetch_module_versioninfo(LPCWSTR filename, VS_FIXEDFILEINFO* ffi)
@@ -361,18 +361,25 @@ static void fetch_module_versioninfo(LPCWSTR filename, VS_FIXEDFILEINFO* ffi)
*/
static void add_memory_block(struct dump_context* dc, ULONG64 base, ULONG size, ULONG rva)
{
if (dc->mem)
dc->mem = HeapReAlloc(GetProcessHeap(), 0, dc->mem,
++dc->num_mem * sizeof(*dc->mem));
else
dc->mem = HeapAlloc(GetProcessHeap(), 0, ++dc->num_mem * sizeof(*dc->mem));
if (!dc->mem)
{
dc->alloc_mem = 32;
dc->mem = HeapAlloc(GetProcessHeap(), 0, dc->alloc_mem * sizeof(*dc->mem));
}
else if (dc->num_mem >= dc->alloc_mem)
{
dc->alloc_mem *= 2;
dc->mem = HeapReAlloc(GetProcessHeap(), 0, dc->mem,
dc->alloc_mem * sizeof(*dc->mem));
}
if (dc->mem)
{
dc->mem[dc->num_mem - 1].base = base;
dc->mem[dc->num_mem - 1].size = size;
dc->mem[dc->num_mem - 1].rva = rva;
dc->mem[dc->num_mem].base = base;
dc->mem[dc->num_mem].size = size;
dc->mem[dc->num_mem].rva = rva;
dc->num_mem++;
}
else dc->num_mem = 0;
else dc->num_mem = dc->alloc_mem = 0;
}
/******************************************************************
@@ -394,7 +401,7 @@ static void writeat(struct dump_context* dc, RVA rva, const void* data, unsigned
* writes a new chunk of data to the minidump, increasing the current
* rva in dc
*/
static void append(struct dump_context* dc, void* data, unsigned size)
static void append(struct dump_context* dc, const void* data, unsigned size)
{
writeat(dc, dc->rva, data, size);
dc->rva += size;
@@ -683,7 +690,7 @@ static unsigned dump_threads(struct dump_context* dc,
{
MINIDUMP_THREAD mdThd;
MINIDUMP_THREAD_LIST mdThdList;
unsigned i;
unsigned i, sz;
RVA rva_base;
DWORD flags_out;
CONTEXT ctx;
@@ -691,8 +698,7 @@ static unsigned dump_threads(struct dump_context* dc,
mdThdList.NumberOfThreads = 0;
rva_base = dc->rva;
dc->rva += sizeof(mdThdList.NumberOfThreads) +
dc->spi->dwThreadCount * sizeof(mdThd);
dc->rva += sz = sizeof(mdThdList.NumberOfThreads) + dc->spi->dwThreadCount * sizeof(mdThd);
for (i = 0; i < dc->spi->dwThreadCount; i++)
{
@@ -713,7 +719,7 @@ static unsigned dump_threads(struct dump_context* dc,
cbin.ProcessId = dc->pid;
cbin.ProcessHandle = dc->hProcess;
cbin.CallbackType = ThreadCallback;
cbin.u.Thread.ThreadId = dc->spi->ti[i].dwThreadID;
cbin.u.Thread.ThreadId = HandleToUlong(dc->spi->ti[i].ClientId.UniqueThread);
cbin.u.Thread.ThreadHandle = 0; /* FIXME */
cbin.u.Thread.Context = ctx;
cbin.u.Thread.SizeOfContext = sizeof(CONTEXT);
@@ -760,7 +766,7 @@ static unsigned dump_threads(struct dump_context* dc,
writeat(dc, rva_base,
&mdThdList.NumberOfThreads, sizeof(mdThdList.NumberOfThreads));
return dc->rva - rva_base;
return sz;
}
/******************************************************************
@@ -795,7 +801,7 @@ static unsigned dump_memory_info(struct dump_context* dc)
{
len = min(dc->mem[i].size - pos, sizeof(tmp));
if (ReadProcessMemory(dc->hProcess,
(void*)(dc->mem[i].base + pos),
(void*)(DWORD_PTR)(dc->mem[i].base + pos),
tmp, len, NULL))
WriteFile(dc->hFile, tmp, len, &written, NULL);
}
@@ -847,10 +853,12 @@ BOOL WINAPI MiniDumpWriteDump(HANDLE hProcess, DWORD pid, HANDLE hFile,
dc.pid = pid;
dc.modules = NULL;
dc.num_modules = 0;
dc.alloc_modules = 0;
dc.cb = CallbackParam;
dc.type = DumpType;
dc.mem = NULL;
dc.num_mem = 0;
dc.alloc_mem = 0;
dc.rva = 0;
if (!fetch_processes_info(&dc)) return FALSE;
@@ -973,7 +981,7 @@ BOOL WINAPI MiniDumpReadDumpStream(PVOID base, ULONG str_idx,
PMINIDUMP_DIRECTORY* pdir,
PVOID* stream, ULONG* size)
{
MINIDUMP_HEADER* mdHead = (MINIDUMP_HEADER*)base;
MINIDUMP_HEADER* mdHead = base;
if (mdHead->Signature == MINIDUMP_SIGNATURE)
{
@@ -985,9 +993,9 @@ BOOL WINAPI MiniDumpReadDumpStream(PVOID base, ULONG str_idx,
{
if (dir->StreamType == str_idx)
{
*pdir = dir;
*stream = (char*)base + dir->Location.Rva;
*size = dir->Location.DataSize;
if (pdir) *pdir = dir;
if (stream) *stream = (char*)base + dir->Location.Rva;
if (size) *size = dir->Location.DataSize;
return TRUE;
}
}
+89 -31
View File
@@ -35,10 +35,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
const WCHAR S_ElfW[] = {'<','e','l','f','>','\0'};
const WCHAR S_WineLoaderW[] = {'<','w','i','n','e','-','l','o','a','d','e','r','>','\0'};
static const WCHAR S_DotSoW[] = {'.','s','o','\0'};
static const WCHAR S_DotDylibW[] = {'.','d','y','l','i','b','\0'};
static const WCHAR S_DotPdbW[] = {'.','p','d','b','\0'};
static const WCHAR S_DotDbgW[] = {'.','d','b','g','\0'};
const WCHAR S_WinePThreadW[] = {'w','i','n','e','-','p','t','h','r','e','a','d','\0'};
const WCHAR S_WineKThreadW[] = {'w','i','n','e','-','k','t','h','r','e','a','d','\0'};
const WCHAR S_WineW[] = {'w','i','n','e',0};
const WCHAR S_SlashW[] = {'/','\0'};
static const WCHAR S_AcmW[] = {'.','a','c','m','\0'};
@@ -87,9 +87,7 @@ static void module_fill_module(const WCHAR* in, WCHAR* out, size_t size)
out[len] = '\0';
if (len > 4 && (l = match_ext(out, len)))
out[len - l] = '\0';
else if (len > 12 &&
(!strcmpiW(out + len - 12, S_WinePThreadW) ||
!strcmpiW(out + len - 12, S_WineKThreadW)))
else if (len > 4 && !strcmpiW(out + len - 4, S_WineW))
lstrcpynW(out, S_WineLoaderW, size);
else
{
@@ -114,6 +112,7 @@ static const char* get_module_type(enum module_type type, BOOL virtual)
{
case DMT_ELF: return virtual ? "Virtual ELF" : "ELF";
case DMT_PE: return virtual ? "Virtual PE" : "PE";
case DMT_MACHO: return virtual ? "Virtual Mach-O" : "Mach-O";
default: return "---";
}
}
@@ -123,20 +122,21 @@ static const char* get_module_type(enum module_type type, BOOL virtual)
*/
struct module* module_new(struct process* pcs, const WCHAR* name,
enum module_type type, BOOL virtual,
unsigned long mod_addr, unsigned long size,
DWORD64 mod_addr, DWORD64 size,
unsigned long stamp, unsigned long checksum)
{
struct module* module;
assert(type == DMT_ELF || type == DMT_PE);
assert(type == DMT_ELF || type == DMT_PE || type == DMT_MACHO);
if (!(module = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*module))))
return NULL;
module->next = pcs->lmodules;
pcs->lmodules = module;
TRACE("=> %s %08lx-%08lx %s\n",
get_module_type(type, virtual), mod_addr, mod_addr + size,
TRACE("=> %s %s-%s %s\n",
get_module_type(type, virtual),
wine_dbgstr_longlong(mod_addr), wine_dbgstr_longlong(mod_addr + size),
debugstr_w(name));
pool_init(&module->pool, 65536);
@@ -169,7 +169,12 @@ struct module* module_new(struct process* pcs, const WCHAR* name,
module->type = type;
module->is_virtual = virtual ? TRUE : FALSE;
module->sortlist_valid = FALSE;
module->sorttab_size = 0;
module->addr_sorttab = NULL;
module->num_sorttab = 0;
module->num_symbols = 0;
vector_init(&module->vsymt, sizeof(struct symt*), 128);
/* FIXME: this seems a bit too high (on a per module basis)
* need some statistics about this
*/
@@ -188,7 +193,7 @@ struct module* module_new(struct process* pcs, const WCHAR* name,
* module_find_by_name
*
*/
struct module* module_find_by_name(const struct process* pcs, const WCHAR* name)
static struct module* module_find_by_name(const struct process* pcs, const WCHAR* name)
{
struct module* module;
@@ -238,7 +243,7 @@ struct module* module_is_already_loaded(const struct process* pcs, const WCHAR*
* module_get_container
*
*/
struct module* module_get_container(const struct process* pcs,
static struct module* module_get_container(const struct process* pcs,
const struct module* inner)
{
struct module* module;
@@ -319,6 +324,9 @@ BOOL module_get_debug(struct module_pair* pair)
ret ? CBA_DEFERRED_SYMBOL_LOAD_COMPLETE : CBA_DEFERRED_SYMBOL_LOAD_FAILURE,
&idslW64);
break;
case DMT_MACHO:
ret = macho_load_debug_info(pair->effective, NULL);
break;
default:
ret = FALSE;
break;
@@ -344,7 +352,8 @@ struct module* module_find_by_addr(const struct process* pcs, unsigned long addr
if (type == DMT_UNKNOWN)
{
if ((module = module_find_by_addr(pcs, addr, DMT_PE)) ||
(module = module_find_by_addr(pcs, addr, DMT_ELF)))
(module = module_find_by_addr(pcs, addr, DMT_ELF)) ||
(module = module_find_by_addr(pcs, addr, DMT_MACHO)))
return module;
}
else
@@ -361,13 +370,13 @@ struct module* module_find_by_addr(const struct process* pcs, unsigned long addr
}
/******************************************************************
* module_is_elf_container_loaded
* module_is_container_loaded
*
* checks whether the ELF container, for a (supposed) PE builtin is
* checks whether the native container, for a (supposed) PE builtin is
* already loaded
*/
static BOOL module_is_elf_container_loaded(const struct process* pcs,
const WCHAR* ImageName, DWORD base)
static BOOL module_is_container_loaded(const struct process* pcs,
const WCHAR* ImageName, DWORD64 base)
{
size_t len;
struct module* module;
@@ -379,7 +388,7 @@ static BOOL module_is_elf_container_loaded(const struct process* pcs,
for (module = pcs->lmodules; module; module = module->next)
{
if (module->type == DMT_ELF &&
if ((module->type == DMT_ELF || module->type == DMT_MACHO) &&
base >= module->module.BaseOfImage &&
base < module->module.BaseOfImage + module->module.ImageSize)
{
@@ -419,8 +428,17 @@ enum module_type module_get_type_by_name(const WCHAR* name)
} while (len);
/* check for terminating .so or .so.[digit] */
/* FIXME: Can't rely solely on extension; have to check magic or
* stop using .so on Mac OS X. For now, base on platform. */
if (len > 3 && !memcmp(name + len - 3, S_DotSoW, 3))
#ifdef __APPLE__
return DMT_MACHO;
#else
return DMT_ELF;
#endif
if (len > 6 && !strncmpiW(name + len - 6, S_DotDylibW, 6))
return DMT_MACHO;
if (len > 4 && !strncmpiW(name + len - 4, S_DotPdbW, 4))
return DMT_PDB;
@@ -428,16 +446,27 @@ enum module_type module_get_type_by_name(const WCHAR* name)
if (len > 4 && !strncmpiW(name + len - 4, S_DotDbgW, 4))
return DMT_DBG;
/* wine-[kp]thread is also an ELF module */
if (((len > 12 && name[len - 13] == '/') || len == 12) &&
(!strncmpiW(name + len - 12, S_WinePThreadW, 12) ||
!strncmpiW(name + len - 12, S_WineKThreadW, 12)))
/* wine is also a native module (Mach-O on Mac OS X, ELF elsewhere) */
if (((len > 4 && name[len - 5] == '/') || len == 4) && !strcmpiW(name + len - 4, S_WineW))
{
#ifdef __APPLE__
return DMT_MACHO;
#else
return DMT_ELF;
#endif
}
return DMT_PE;
}
/******************************************************************
* refresh_module_list
*/
static BOOL refresh_module_list(struct process* pcs)
{
/* force transparent ELF and Mach-O loading / unloading */
return elf_synchronize_module_list(pcs) || macho_synchronize_module_list(pcs);
}
/***********************************************************************
* SymLoadModule (DBGHELP.@)
*/
@@ -508,8 +537,9 @@ DWORD64 WINAPI SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageNam
if (Flags & SLMFLAG_VIRTUAL)
{
if (!wImageName) return FALSE;
module = module_new(pcs, wImageName, module_get_type_by_name(wImageName),
TRUE, (DWORD)BaseOfDll, SizeOfDll, 0, 0);
TRUE, BaseOfDll, SizeOfDll, 0, 0);
if (!module) return FALSE;
if (wModuleName) module_set_module(module, wModuleName);
module->module.SymType = SymVirtual;
@@ -519,8 +549,7 @@ DWORD64 WINAPI SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageNam
if (Flags & ~(SLMFLAG_VIRTUAL))
FIXME("Unsupported Flags %08x for %s\n", Flags, debugstr_w(wImageName));
/* force transparent ELF loading / unloading */
elf_synchronize_module_list(pcs);
refresh_module_list(pcs);
/* this is a Wine extension to the API just to redo the synchronisation */
if (!wImageName && !hFile) return 0;
@@ -531,7 +560,7 @@ DWORD64 WINAPI SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageNam
if (wImageName)
{
module = module_is_already_loaded(pcs, wImageName);
if (!module && module_is_elf_container_loaded(pcs, wImageName, BaseOfDll))
if (!module && module_is_container_loaded(pcs, wImageName, BaseOfDll))
{
/* force the loading of DLL as builtin */
module = pe_load_builtin_module(pcs, wImageName, BaseOfDll, SizeOfDll);
@@ -540,11 +569,22 @@ DWORD64 WINAPI SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageNam
if (!module)
{
/* otherwise, try a regular PE module */
if (!(module = pe_load_native_module(pcs, wImageName, hFile, BaseOfDll, SizeOfDll)))
if (!(module = pe_load_native_module(pcs, wImageName, hFile, BaseOfDll, SizeOfDll)) &&
wImageName)
{
/* and finally and ELF module */
if (module_get_type_by_name(wImageName) == DMT_ELF)
module = elf_load_module(pcs, wImageName, BaseOfDll);
/* and finally an ELF or Mach-O module */
switch (module_get_type_by_name(wImageName))
{
case DMT_ELF:
module = elf_load_module(pcs, wImageName, BaseOfDll);
break;
case DMT_MACHO:
module = macho_load_module(pcs, wImageName, BaseOfDll);
break;
default:
/* Ignored */
break;
}
}
}
if (!module)
@@ -558,7 +598,8 @@ DWORD64 WINAPI SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageNam
*/
if (wModuleName)
module_set_module(module, wModuleName);
lstrcpynW(module->module.ImageName, wImageName,
if (wImageName)
lstrcpynW(module->module.ImageName, wImageName,
sizeof(module->module.ImageName) / sizeof(WCHAR));
return module->module.BaseOfImage;
@@ -715,7 +756,8 @@ BOOL WINAPI SymEnumerateModulesW64(HANDLE hProcess,
for (module = pcs->lmodules; module; module = module->next)
{
if (!(dbghelp_options & SYMOPT_WINE_WITH_ELF_MODULES) && module->type == DMT_ELF)
if (!(dbghelp_options & SYMOPT_WINE_WITH_NATIVE_MODULES) &&
(module->type == DMT_ELF || module->type == DMT_MACHO))
continue;
if (!EnumModulesCallback(module->module.ModuleName,
module->module.BaseOfImage, UserContext))
@@ -1008,7 +1050,9 @@ DWORD64 WINAPI SymGetModuleBase64(HANDLE hProcess, DWORD64 dwAddr)
void module_reset_debug_info(struct module* module)
{
module->sortlist_valid = TRUE;
module->sorttab_size = 0;
module->addr_sorttab = NULL;
module->num_sorttab = module->num_symbols = 0;
hash_table_destroy(&module->ht_symbols);
module->ht_symbols.num_buckets = 0;
module->ht_symbols.buckets = NULL;
@@ -1020,3 +1064,17 @@ void module_reset_debug_info(struct module* module)
module->sources_used = module->sources_alloc = 0;
module->sources = NULL;
}
/******************************************************************
* SymRefreshModuleList (DBGHELP.@)
*/
BOOL WINAPI SymRefreshModuleList(HANDLE hProcess)
{
struct process* pcs;
TRACE("(%p)\n", hProcess);
if (!(pcs = process_find_by_handle(hProcess))) return FALSE;
return refresh_module_list(pcs);
}
+81 -55
View File
@@ -71,7 +71,7 @@ static void dump(const void* ptr, unsigned len)
unsigned int i, j;
char msg[128];
const char* hexof = "0123456789abcdef";
const BYTE* x = (const BYTE*)ptr;
const BYTE* x = ptr;
for (i = 0; i < len; i += 16)
{
@@ -95,7 +95,7 @@ static void dump(const void* ptr, unsigned len)
* Process CodeView type information.
*/
#define MAX_BUILTIN_TYPES 0x0480
#define MAX_BUILTIN_TYPES 0x0604
#define FIRST_DEFINABLE_TYPE 0x1000
static struct symt* cv_basic_types[MAX_BUILTIN_TYPES];
@@ -113,6 +113,7 @@ static struct cv_defined_module*cv_current_module;
static void codeview_init_basic_types(struct module* module)
{
struct symt_udt* udt;
/*
* These are the common builtin types that are used by VC++.
*/
@@ -169,6 +170,12 @@ static void codeview_init_basic_types(struct module* module)
cv_basic_types[T_32PINT8] = &symt_new_pointer(module, cv_basic_types[T_INT8])->symt;
cv_basic_types[T_32PUINT8] = &symt_new_pointer(module, cv_basic_types[T_UINT8])->symt;
cv_basic_types[T_32PHRESULT]= &symt_new_pointer(module, cv_basic_types[T_HRESULT])->symt;
/* The .pdb file can refer to 64 bit pointers values even on 32 bits applications. */
udt = symt_new_udt(module, "PVOID64", 8, UdtStruct);
symt_add_udt_element(module, udt, "ptr64_low", cv_basic_types[T_LONG], 0, 32);
symt_add_udt_element(module, udt, "ptr64_high", cv_basic_types[T_LONG], 32, 32);
cv_basic_types[0x603]= &udt->symt;
}
static int leaf_as_variant(VARIANT* v, const unsigned short int* leaf)
@@ -486,18 +493,23 @@ static int codeview_add_type(unsigned int typeno, struct symt* dt)
if ((typeno >> 24) != 0)
FIXME("No module index while inserting type-id assumption is wrong %x\n",
typeno);
while (typeno - FIRST_DEFINABLE_TYPE >= cv_current_module->num_defined_types)
if (typeno - FIRST_DEFINABLE_TYPE >= cv_current_module->num_defined_types)
{
cv_current_module->num_defined_types += 0x100;
if (cv_current_module->defined_types)
{
cv_current_module->num_defined_types = max( cv_current_module->num_defined_types * 2,
typeno - FIRST_DEFINABLE_TYPE + 1 );
cv_current_module->defined_types = HeapReAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, cv_current_module->defined_types,
cv_current_module->num_defined_types * sizeof(struct symt*));
}
else
{
cv_current_module->num_defined_types = max( 256, typeno - FIRST_DEFINABLE_TYPE + 1 );
cv_current_module->defined_types = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
cv_current_module->num_defined_types * sizeof(struct symt*));
}
if (cv_current_module->defined_types == NULL) return FALSE;
}
if (cv_current_module->defined_types[typeno - FIRST_DEFINABLE_TYPE])
@@ -581,15 +593,8 @@ static struct symt* codeview_add_type_array(struct codeview_type_parse* ctp,
{
struct symt* elem = codeview_fetch_type(ctp, elemtype, FALSE);
struct symt* index = codeview_fetch_type(ctp, indextype, FALSE);
DWORD arr_max = 0;
if (elem)
{
DWORD64 elem_size;
symt_get_info(elem, TI_GET_LENGTH, &elem_size);
if (elem_size) arr_max = arr_len / (DWORD)elem_size;
}
return &symt_new_array(ctp->module, 0, arr_max, elem, index)->symt;
return &symt_new_array(ctp->module, 0, -arr_len, elem, index)->symt;
}
static int codeview_add_type_enum_field_list(struct module* module,
@@ -669,7 +674,7 @@ static void codeview_add_udt_element(struct codeview_type_parse* ctp,
if (subtype)
{
DWORD64 elem_size = 0;
symt_get_info(subtype, TI_GET_LENGTH, &elem_size);
symt_get_info(ctp->module, subtype, TI_GET_LENGTH, &elem_size);
symt_add_udt_element(ctp->module, symt, name, subtype,
value << 3, (DWORD)elem_size << 3);
}
@@ -1357,48 +1362,72 @@ static void codeview_snarf_linetab(const struct msc_debug_info* msc_dbg, const B
}
static void codeview_snarf_linetab2(const struct msc_debug_info* msc_dbg, const BYTE* linetab, DWORD size,
const char* strimage, DWORD strsize)
const char* strimage, DWORD strsize)
{
DWORD offset;
unsigned i;
DWORD addr;
const struct codeview_linetab2_block* lbh;
const struct codeview_linetab2_file* fd;
const struct codeview_linetab2* lt2;
const struct codeview_linetab2* lt2_files = NULL;
const struct codeview_lt2blk_lines* lines_blk;
const struct codeview_linetab2_file*fd;
unsigned source;
struct symt_function* func;
if (*(const DWORD*)linetab != 0x000000f4) return;
offset = *((const DWORD*)linetab + 1);
for (lbh = (const struct codeview_linetab2_block*)(linetab + 8 + offset);
(const BYTE*)lbh < linetab + size;
lbh = (const struct codeview_linetab2_block*)((const char*)lbh + 8 + lbh->size_of_block))
/* locate LT2_FILES_BLOCK (if any) */
lt2 = (const struct codeview_linetab2*)linetab;
while ((const BYTE*)(lt2 + 1) < linetab + size)
{
if (lbh->header != 0x000000f2)
/* FIXME: should also check that whole lbh fits in linetab + size */
if (lt2->header == LT2_FILES_BLOCK)
{
TRACE("block end %x\n", lbh->header);
lt2_files = lt2;
break;
}
addr = codeview_get_address(msc_dbg, lbh->seg, lbh->start);
TRACE("block from %04x:%08x #%x (%x lines)\n",
lbh->seg, lbh->start, lbh->size, lbh->nlines);
fd = (const struct codeview_linetab2_file*)(linetab + 8 + lbh->file_offset);
/* FIXME: should check that string is within strimage + strsize */
source = source_new(msc_dbg->module, NULL, strimage + fd->offset);
func = (struct symt_function*)symt_find_nearest(msc_dbg->module, addr);
/* FIXME: at least labels support line numbers */
if (!func || func->symt.tag != SymTagFunction)
lt2 = codeview_linetab2_next_block(lt2);
}
if (!lt2_files)
{
TRACE("No LT2_FILES_BLOCK found\n");
return;
}
lt2 = (const struct codeview_linetab2*)linetab;
while ((const BYTE*)(lt2 + 1) < linetab + size)
{
/* FIXME: should also check that whole lines_blk fits in linetab + size */
switch (lt2->header)
{
WARN("--not a func at %04x:%08x %x tag=%d\n",
lbh->seg, lbh->start, addr, func ? func->symt.tag : -1);
case LT2_LINES_BLOCK:
lines_blk = (const struct codeview_lt2blk_lines*)lt2;
/* FIXME: should check that file_offset is within the LT2_FILES_BLOCK we've seen */
addr = codeview_get_address(msc_dbg, lines_blk->seg, lines_blk->start);
TRACE("block from %04x:%08x #%x (%x lines)\n",
lines_blk->seg, lines_blk->start, lines_blk->size, lines_blk->nlines);
fd = (const struct codeview_linetab2_file*)((const char*)lt2_files + 8 + lines_blk->file_offset);
/* FIXME: should check that string is within strimage + strsize */
source = source_new(msc_dbg->module, NULL, strimage + fd->offset);
func = (struct symt_function*)symt_find_nearest(msc_dbg->module, addr);
/* FIXME: at least labels support line numbers */
if (!func || func->symt.tag != SymTagFunction)
{
WARN("--not a func at %04x:%08x %x tag=%d\n",
lines_blk->seg, lines_blk->start, addr, func ? func->symt.tag : -1);
break;
}
for (i = 0; i < lines_blk->nlines; i++)
{
symt_add_func_line(msc_dbg->module, func, source,
lines_blk->l[i].lineno ^ 0x80000000,
lines_blk->l[i].offset);
}
break;
case LT2_FILES_BLOCK: /* skip */
break;
default:
TRACE("Block end %x\n", lt2->header);
lt2 = (const struct codeview_linetab2*)((const char*)linetab + size);
continue;
}
for (i = 0; i < lbh->nlines; i++)
{
symt_add_func_line(msc_dbg->module, func, source,
lbh->l[i].lineno ^ 0x80000000, lbh->l[i].offset - lbh->start);
}
lt2 = codeview_linetab2_next_block(lt2);
}
}
@@ -1897,8 +1926,7 @@ static int codeview_snarf_public(const struct msc_debug_info* msc_dbg, const BYT
{
symt_new_public(msc_dbg->module, compiland,
terminate_string(&sym->data_v1.p_name),
codeview_get_address(msc_dbg, sym->data_v1.segment, sym->data_v1.offset),
1, TRUE /* FIXME */, TRUE /* FIXME */);
codeview_get_address(msc_dbg, sym->data_v1.segment, sym->data_v1.offset), 1);
}
break;
case S_PUB_V2: /* FIXME is this really a 'data_v2' structure ?? */
@@ -1906,8 +1934,7 @@ static int codeview_snarf_public(const struct msc_debug_info* msc_dbg, const BYT
{
symt_new_public(msc_dbg->module, compiland,
terminate_string(&sym->data_v2.p_name),
codeview_get_address(msc_dbg, sym->data_v2.segment, sym->data_v2.offset),
1, TRUE /* FIXME */, TRUE /* FIXME */);
codeview_get_address(msc_dbg, sym->data_v2.segment, sym->data_v2.offset), 1);
}
break;
@@ -1916,8 +1943,7 @@ static int codeview_snarf_public(const struct msc_debug_info* msc_dbg, const BYT
{
symt_new_public(msc_dbg->module, compiland,
sym->data_v3.name,
codeview_get_address(msc_dbg, sym->data_v3.segment, sym->data_v3.offset),
1, FALSE /* FIXME */, FALSE);
codeview_get_address(msc_dbg, sym->data_v3.segment, sym->data_v3.offset), 1);
}
break;
case S_PUB_FUNC1_V3:
@@ -1928,8 +1954,7 @@ static int codeview_snarf_public(const struct msc_debug_info* msc_dbg, const BYT
{
symt_new_public(msc_dbg->module, compiland,
sym->data_v3.name,
codeview_get_address(msc_dbg, sym->data_v3.segment, sym->data_v3.offset),
1, TRUE /* FIXME */, TRUE);
codeview_get_address(msc_dbg, sym->data_v3.segment, sym->data_v3.offset), 1);
}
#endif
break;
@@ -2150,7 +2175,7 @@ static void pdb_convert_symbol_file(const PDB_SYMBOLS* symbols,
{
if (symbols->version < 19970000)
{
const PDB_SYMBOL_FILE *sym_file = (const PDB_SYMBOL_FILE*)image;
const PDB_SYMBOL_FILE *sym_file = image;
memset(sfile, 0, sizeof(*sfile));
sfile->file = sym_file->file;
sfile->range.index = sym_file->range.index;
@@ -2217,7 +2242,8 @@ static void pdb_process_types(const struct msc_debug_info* msc_dbg,
case 19950410: /* VC 4.0 */
case 19951122:
case 19961031: /* VC 5.0 / 6.0 */
case 19990903:
case 19990903: /* VC 7.0 */
case 20040203: /* VC 8.0 */
break;
default:
ERR("-Unknown type info version %d\n", types.version);
@@ -2385,7 +2411,7 @@ static void pdb_process_symbol_imports(const struct process* pcs,
imp = (const PDB_SYMBOL_IMPORT*)((const char*)symbols_image + sizeof(PDB_SYMBOLS) +
symbols->module_size + symbols->offset_size +
symbols->hash_size + symbols->srcmodule_size);
first = (const char*)imp;
first = imp;
last = (const char*)imp + symbols->pdbimport_size;
while (imp < (const PDB_SYMBOL_IMPORT*)last)
{
@@ -2524,7 +2550,7 @@ static BOOL pdb_process_internal(const struct process* pcs,
}
file_name = (const char*)file + size;
file_name += strlen(file_name) + 1;
file = (BYTE*)((DWORD)(file_name + strlen(file_name) + 1 + 3) & ~3);
file = (BYTE*)((DWORD_PTR)(file_name + strlen(file_name) + 1 + 3) & ~3);
}
/* finish the remaining public and global information */
if (globalimage)
+20 -5
View File
@@ -234,7 +234,7 @@ static BOOL do_searchW(PCWSTR file, PWSTR buffer, BOOL recurse,
strcpyW(buffer + pos, fd.cFileName);
if (recurse && (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
found = do_searchW(file, buffer, TRUE, cb, user);
else if (SymMatchFileNameW(buffer, (WCHAR*)file, NULL, NULL))
else if (SymMatchFileNameW(buffer, file, NULL, NULL))
{
if (!cb || cb(buffer, user)) found = TRUE;
}
@@ -340,13 +340,13 @@ struct sffip
*/
static BOOL CALLBACK sffip_cb(PCWSTR buffer, PVOID user)
{
struct sffip* s = (struct sffip*)user;
struct sffip* s = user;
if (!s->cb) return TRUE;
/* yes, EnumDirTree/do_search and SymFindFileInPath callbacks use the opposite
* convention to stop/continue enumeration. sigh.
*/
return !(s->cb)((WCHAR*)buffer, s->user);
return !(s->cb)(buffer, s->user);
}
/******************************************************************
@@ -461,7 +461,7 @@ struct module_find
*/
static BOOL CALLBACK module_find_cb(PCWSTR buffer, PVOID user)
{
struct module_find* mf = (struct module_find*)user;
struct module_find* mf = user;
DWORD size, checksum, timestamp;
unsigned matched = 0;
@@ -522,6 +522,21 @@ static BOOL CALLBACK module_find_cb(PCWSTR buffer, PVOID user)
return FALSE;
}
break;
case DMT_MACHO:
if (macho_fetch_file_info(buffer, 0, &size, &checksum))
{
matched++;
if (checksum == mf->dw1) matched++;
else
WARN("Found %s, but wrong checksums: %08x %08x\n",
debugstr_w(buffer), checksum, mf->dw1);
}
else
{
WARN("Couldn't read %s\n", debugstr_w(buffer));
return FALSE;
}
break;
case DMT_PDB:
{
struct pdb_lookup pdb_lookup;
@@ -580,7 +595,7 @@ static BOOL CALLBACK module_find_cb(PCWSTR buffer, PVOID user)
if ((mapping = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL)
{
const IMAGE_SEPARATE_DEBUG_HEADER* hdr;
hdr = (const IMAGE_SEPARATE_DEBUG_HEADER*)mapping;
hdr = mapping;
if (hdr->Signature == IMAGE_SEPARATE_DEBUG_SIGNATURE)
{
+219 -39
View File
@@ -35,6 +35,141 @@
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
/******************************************************************
* pe_locate_with_coff_symbol_table
*
* Use the COFF symbol table (if any) from the IMAGE_FILE_HEADER to set the absolute address
* of global symbols.
* Mingw32 requires this for stabs debug information as address for global variables isn't filled in
* (this is similar to what is done in elf_module.c when using the .symtab ELF section)
*/
static BOOL pe_locate_with_coff_symbol_table(struct module* module, IMAGE_NT_HEADERS* nth, void* mapping)
{
const IMAGE_SYMBOL* isym;
int i, numsym, naux;
const char* strtable;
char tmp[9];
const char* name;
struct hash_table_iter hti;
void* ptr;
struct symt_data* sym;
const IMAGE_SECTION_HEADER* sect;
numsym = nth->FileHeader.NumberOfSymbols;
if (!nth->FileHeader.PointerToSymbolTable || !numsym)
return TRUE;
isym = (const IMAGE_SYMBOL*)((char*)mapping + nth->FileHeader.PointerToSymbolTable);
/* FIXME: no way to get strtable size */
strtable = (const char*)&isym[numsym];
sect = IMAGE_FIRST_SECTION(nth);
for (i = 0; i < numsym; i+= naux, isym += naux)
{
if (isym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL &&
isym->SectionNumber > 0 && isym->SectionNumber <= nth->FileHeader.NumberOfSections)
{
if (isym->N.Name.Short)
{
name = memcpy(tmp, isym->N.ShortName, 8);
tmp[8] = '\0';
}
else name = strtable + isym->N.Name.Long;
if (name[0] == '_') name++;
hash_table_iter_init(&module->ht_symbols, &hti, name);
while ((ptr = hash_table_iter_up(&hti)))
{
sym = GET_ENTRY(ptr, struct symt_data, hash_elt);
if (sym->symt.tag == SymTagData &&
(sym->kind == DataIsGlobal || sym->kind == DataIsFileStatic) &&
!strcmp(sym->hash_elt.name, name))
{
TRACE("Changing absolute address for %d.%s: %lx -> %s\n",
isym->SectionNumber, name, sym->u.var.offset,
wine_dbgstr_longlong(module->module.BaseOfImage +
sect[isym->SectionNumber - 1].VirtualAddress + isym->Value));
sym->u.var.offset = module->module.BaseOfImage +
sect[isym->SectionNumber - 1].VirtualAddress + isym->Value;
break;
}
}
}
naux = isym->NumberOfAuxSymbols + 1;
}
return TRUE;
}
/******************************************************************
* pe_load_coff_symbol_table
*
* Load public symbols out of the COFF symbol table (if any).
*/
static BOOL pe_load_coff_symbol_table(struct module* module, IMAGE_NT_HEADERS* nth, void* mapping)
{
const IMAGE_SYMBOL* isym;
int i, numsym, naux;
const char* strtable;
char tmp[9];
const char* name;
const char* lastfilename = NULL;
struct symt_compiland* compiland = NULL;
const IMAGE_SECTION_HEADER* sect;
numsym = nth->FileHeader.NumberOfSymbols;
if (!nth->FileHeader.PointerToSymbolTable || !numsym)
return TRUE;
isym = (const IMAGE_SYMBOL*)((char*)mapping + nth->FileHeader.PointerToSymbolTable);
/* FIXME: no way to get strtable size */
strtable = (const char*)&isym[numsym];
sect = IMAGE_FIRST_SECTION(nth);
for (i = 0; i < numsym; i+= naux, isym += naux)
{
if (isym->StorageClass == IMAGE_SYM_CLASS_FILE)
{
lastfilename = (const char*)(isym + 1);
compiland = NULL;
}
if (isym->StorageClass == IMAGE_SYM_CLASS_EXTERNAL &&
isym->SectionNumber > 0 && isym->SectionNumber <= nth->FileHeader.NumberOfSections)
{
if (isym->N.Name.Short)
{
name = memcpy(tmp, isym->N.ShortName, 8);
tmp[8] = '\0';
}
else name = strtable + isym->N.Name.Long;
if (name[0] == '_') name++;
if (!compiland && lastfilename)
compiland = symt_new_compiland(module, 0,
source_new(module, NULL, lastfilename));
symt_new_public(module, compiland, name,
module->module.BaseOfImage + sect[isym->SectionNumber - 1].VirtualAddress + isym->Value,
1);
}
naux = isym->NumberOfAuxSymbols + 1;
}
module->module.SymType = SymCoff;
module->module.LineNumbers = FALSE;
module->module.GlobalSymbols = FALSE;
module->module.TypeInfo = FALSE;
module->module.SourceIndexed = FALSE;
module->module.Publics = TRUE;
return TRUE;
}
static inline void* pe_get_sect(IMAGE_NT_HEADERS* nth, void* mapping,
IMAGE_SECTION_HEADER* sect)
{
return (sect) ? RtlImageRvaToVa(nth, mapping, sect->VirtualAddress, NULL) : NULL;
}
static inline DWORD pe_get_sect_size(IMAGE_SECTION_HEADER* sect)
{
return (sect) ? sect->SizeOfRawData : 0;
}
/******************************************************************
* pe_load_stabs
*
@@ -45,37 +180,85 @@ static BOOL pe_load_stabs(const struct process* pcs, struct module* module,
void* mapping, IMAGE_NT_HEADERS* nth)
{
IMAGE_SECTION_HEADER* section;
int i, stabsize = 0, stabstrsize = 0;
unsigned int stabs = 0, stabstr = 0;
IMAGE_SECTION_HEADER* sect_stabs = NULL;
IMAGE_SECTION_HEADER* sect_stabstr = NULL;
int i;
BOOL ret = FALSE;
section = (IMAGE_SECTION_HEADER*)
((char*)&nth->OptionalHeader + nth->FileHeader.SizeOfOptionalHeader);
for (i = 0; i < nth->FileHeader.NumberOfSections; i++, section++)
{
if (!strcasecmp((const char*)section->Name, ".stab"))
{
stabs = section->VirtualAddress;
stabsize = section->SizeOfRawData;
}
else if (!strncasecmp((const char*)section->Name, ".stabstr", 8))
{
stabstr = section->VirtualAddress;
stabstrsize = section->SizeOfRawData;
}
if (!strcasecmp((const char*)section->Name, ".stab")) sect_stabs = section;
else if (!strncasecmp((const char*)section->Name, ".stabstr", 8)) sect_stabstr = section;
}
if (stabstrsize && stabsize)
if (sect_stabs && sect_stabstr)
{
ret = stabs_parse(module,
module->module.BaseOfImage - nth->OptionalHeader.ImageBase,
RtlImageRvaToVa(nth, mapping, stabs, NULL),
stabsize,
RtlImageRvaToVa(nth, mapping, stabstr, NULL),
stabstrsize);
ret = stabs_parse(module,
module->module.BaseOfImage - nth->OptionalHeader.ImageBase,
pe_get_sect(nth, mapping, sect_stabs), pe_get_sect_size(sect_stabs),
pe_get_sect(nth, mapping, sect_stabstr), pe_get_sect_size(sect_stabstr),
NULL, NULL);
if (ret) pe_locate_with_coff_symbol_table(module, nth, mapping);
}
TRACE("%s the STABS debug info\n", ret ? "successfully loaded" : "failed to load");
return ret;
}
/******************************************************************
* pe_load_dwarf
*
* look for dwarf information in PE header (it's also a way for the mingw compiler
* to provide its debugging information)
*/
static BOOL pe_load_dwarf(const struct process* pcs, struct module* module,
void* mapping, IMAGE_NT_HEADERS* nth)
{
IMAGE_SECTION_HEADER* section;
IMAGE_SECTION_HEADER* sect_debuginfo = NULL;
IMAGE_SECTION_HEADER* sect_debugstr = NULL;
IMAGE_SECTION_HEADER* sect_debugabbrev = NULL;
IMAGE_SECTION_HEADER* sect_debugline = NULL;
IMAGE_SECTION_HEADER* sect_debugloc = NULL;
int i;
const char* strtable;
const char* sectname;
BOOL ret = FALSE;
if (nth->FileHeader.PointerToSymbolTable && nth->FileHeader.NumberOfSymbols)
/* FIXME: no way to get strtable size */
strtable = (const char*)mapping + nth->FileHeader.PointerToSymbolTable +
nth->FileHeader.NumberOfSymbols * sizeof(IMAGE_SYMBOL);
else strtable = NULL;
section = (IMAGE_SECTION_HEADER*)
((char*)&nth->OptionalHeader + nth->FileHeader.SizeOfOptionalHeader);
for (i = 0; i < nth->FileHeader.NumberOfSections; i++, section++)
{
sectname = (const char*)section->Name;
/* long section names start with a '/' (at least on MinGW32) */
if (*sectname == '/' && strtable)
sectname = strtable + atoi(sectname + 1);
if (!strcasecmp(sectname, ".debug_info")) sect_debuginfo = section;
else if (!strcasecmp(sectname, ".debug_str")) sect_debugstr = section;
else if (!strcasecmp(sectname, ".debug_abbrev")) sect_debugabbrev = section;
else if (!strcasecmp(sectname, ".debug_line")) sect_debugline = section;
else if (!strcasecmp(sectname, ".debug_loc")) sect_debugloc = section;
}
if (sect_debuginfo)
{
ret = dwarf2_parse(module,
module->module.BaseOfImage - nth->OptionalHeader.ImageBase,
NULL, /* FIXME: some thunks to deal with ? */
pe_get_sect(nth, mapping, sect_debuginfo), pe_get_sect_size(sect_debuginfo),
pe_get_sect(nth, mapping, sect_debugabbrev), pe_get_sect_size(sect_debugabbrev),
pe_get_sect(nth, mapping, sect_debugstr), pe_get_sect_size(sect_debugstr),
pe_get_sect(nth, mapping, sect_debugline), pe_get_sect_size(sect_debugline),
pe_get_sect(nth, mapping, sect_debugloc), pe_get_sect_size(sect_debugloc));
}
TRACE("%s the DWARF debug info\n", ret ? "successfully loaded" : "failed to load");
return ret;
}
@@ -133,7 +316,7 @@ static BOOL pe_load_dbg_file(const struct process* pcs, struct module* module,
*/
static BOOL pe_load_msc_debug_info(const struct process* pcs,
struct module* module,
void* mapping, IMAGE_NT_HEADERS* nth)
void* mapping, const IMAGE_NT_HEADERS* nth)
{
BOOL ret = FALSE;
const IMAGE_DATA_DIRECTORY* dir;
@@ -181,7 +364,7 @@ static BOOL pe_load_msc_debug_info(const struct process* pcs,
*/
static BOOL pe_load_export_debug_info(const struct process* pcs,
struct module* module,
void* mapping, IMAGE_NT_HEADERS* nth)
void* mapping, const IMAGE_NT_HEADERS* nth)
{
unsigned int i;
const IMAGE_EXPORT_DIRECTORY* exports;
@@ -193,14 +376,12 @@ static BOOL pe_load_export_debug_info(const struct process* pcs,
#if 0
/* Add start of DLL (better use the (yet unimplemented) Exe SymTag for this) */
/* FIXME: module.ModuleName isn't correctly set yet if it's passed in SymLoadModule */
symt_new_public(module, NULL, module->module.ModuleName, base, 1,
TRUE /* FIXME */, TRUE /* FIXME */);
symt_new_public(module, NULL, module->module.ModuleName, base, 1);
#endif
/* Add entry point */
symt_new_public(module, NULL, "EntryPoint",
base + nth->OptionalHeader.AddressOfEntryPoint, 1,
TRUE, TRUE);
base + nth->OptionalHeader.AddressOfEntryPoint, 1);
#if 0
/* FIXME: we'd better store addresses linked to sections rather than
absolute values */
@@ -211,8 +392,7 @@ static BOOL pe_load_export_debug_info(const struct process* pcs,
for (i = 0; i < nth->FileHeader.NumberOfSections; i++, section++)
{
symt_new_public(module, NULL, section->Name,
RtlImageRvaToVa(nth, mapping, section->VirtualAddress, NULL),
1, TRUE /* FIXME */, TRUE /* FIXME */);
RtlImageRvaToVa(nth, mapping, section->VirtualAddress, NULL), 1);
}
#endif
@@ -237,8 +417,7 @@ static BOOL pe_load_export_debug_info(const struct process* pcs,
if (!names[i]) continue;
symt_new_public(module, NULL,
RtlImageRvaToVa(nth, mapping, names[i], NULL),
base + functions[ordinals[i]],
1, TRUE /* FIXME */, TRUE /* FIXME */);
base + functions[ordinals[i]], 1);
}
for (i = 0; i < exports->NumberOfFunctions; i++)
@@ -249,8 +428,7 @@ static BOOL pe_load_export_debug_info(const struct process* pcs,
if ((ordinals[j] == i) && names[j]) break;
if (j < exports->NumberOfNames) continue;
snprintf(buffer, sizeof(buffer), "%d", i + exports->Base);
symt_new_public(module, NULL, buffer, base + (DWORD)functions[i], 1,
TRUE /* FIXME */, TRUE /* FIXME */);
symt_new_public(module, NULL, buffer, base + (DWORD)functions[i], 1);
}
}
}
@@ -284,7 +462,9 @@ BOOL pe_load_debug_info(const struct process* pcs, struct module* module)
if (!(dbghelp_options & SYMOPT_PUBLICS_ONLY))
{
ret = pe_load_stabs(pcs, module, mapping, nth) ||
pe_load_msc_debug_info(pcs, module, mapping, nth);
pe_load_dwarf(pcs, module, mapping, nth) ||
pe_load_msc_debug_info(pcs, module, mapping, nth) ||
pe_load_coff_symbol_table(module, nth, mapping);
/* if we still have no debug info (we could only get SymExport at this
* point), then do the SymExport except if we have an ELF container,
* in which case we'll rely on the export's on the ELF side
@@ -367,13 +547,13 @@ struct module* pe_load_native_module(struct process* pcs, const WCHAR* name,
* pe_load_nt_header
*
*/
BOOL pe_load_nt_header(HANDLE hProc, DWORD base, IMAGE_NT_HEADERS* nth)
BOOL pe_load_nt_header(HANDLE hProc, DWORD64 base, IMAGE_NT_HEADERS* nth)
{
IMAGE_DOS_HEADER dos;
return ReadProcessMemory(hProc, (char*)base, &dos, sizeof(dos), NULL) &&
return ReadProcessMemory(hProc, (char*)(DWORD_PTR)base, &dos, sizeof(dos), NULL) &&
dos.e_magic == IMAGE_DOS_SIGNATURE &&
ReadProcessMemory(hProc, (char*)(base + dos.e_lfanew),
ReadProcessMemory(hProc, (char*)(DWORD_PTR)(base + dos.e_lfanew),
nth, sizeof(*nth), NULL) &&
nth->Signature == IMAGE_NT_SIGNATURE;
}
@@ -383,7 +563,7 @@ BOOL pe_load_nt_header(HANDLE hProc, DWORD base, IMAGE_NT_HEADERS* nth)
*
*/
struct module* pe_load_builtin_module(struct process* pcs, const WCHAR* name,
DWORD base, DWORD size)
DWORD64 base, DWORD64 size)
{
struct module* module = NULL;
@@ -435,7 +615,7 @@ PVOID WINAPI ImageDirectoryEntryToDataEx( PVOID base, BOOLEAN image, USHORT dir,
*size = nt->OptionalHeader.DataDirectory[dir].Size;
if (image || addr < nt->OptionalHeader.SizeOfHeaders) return (char *)base + addr;
return RtlImageRvaToVa( nt, (HMODULE)base, addr, section );
return RtlImageRvaToVa( nt, base, addr, section );
}
/***********************************************************************
-80
View File
@@ -309,42 +309,6 @@ SymGetHomeDirectoryW(DWORD dwType,
return NULL;
}
BOOL WINAPI
SymGetLineFromName64(HANDLE hProcess,
PCSTR pszModuleName,
PCSTR pszFileName,
DWORD dwLineNumber,
PLONG plDisplacement,
PIMAGEHLP_LINE64 Line)
{
UNIMPLEMENTED;
return FALSE;
}
BOOL WINAPI
SymGetLineFromName(HANDLE hProcess,
PCSTR pszModuleName,
PCSTR pszFileName,
DWORD dwLineNumber,
PLONG plDisplacement,
PIMAGEHLP_LINE Line)
{
UNIMPLEMENTED;
return FALSE;
}
BOOL WINAPI
SymGetLineFromNameW64(HANDLE hProcess,
PCWSTR pszModuleName,
PCWSTR pszFileName,
DWORD dwLineNumber,
PLONG lpDisplacement,
PIMAGEHLP_LINEW64 Line)
{
UNIMPLEMENTED;
return FALSE;
}
BOOL WINAPI
SymGetLineNextW64(HANDLE hProcess,
PIMAGEHLP_LINEW64 Line)
@@ -459,31 +423,6 @@ SymGetSourceVarFromTokenW(
return FALSE;
}
BOOL WINAPI
SymGetSymFromName64(HANDLE hProcess,
PCSTR pszName,
PIMAGEHLP_SYMBOL64 Symbol)
{
UNIMPLEMENTED;
return FALSE;
}
BOOL WINAPI
SymGetSymNext64(HANDLE hProcess,
PIMAGEHLP_SYMBOL64 Symbol)
{
UNIMPLEMENTED;
return FALSE;
}
BOOL WINAPI
SymGetSymPrev64(HANDLE hProcess,
PIMAGEHLP_SYMBOL64 Symbol)
{
UNIMPLEMENTED;
return FALSE;
}
BOOL WINAPI
SymGetSymbolFile(HANDLE hProcess,
PCSTR pszSymPath,
@@ -581,16 +520,6 @@ SymPrevW(HANDLE hProcess,
return FALSE;
}
BOOL
WINAPI
SymRefreshModuleList(
HANDLE hProcess)
{
UNIMPLEMENTED;
return FALSE;
}
PCHAR WINAPI
SymSetHomeDirectory(HANDLE hProcess,
PCSTR pszDir)
@@ -766,15 +695,6 @@ SymSrvStoreSupplementW(HANDLE hProcess,
return NULL;
}
BOOL WINAPI
SymUnDName64(PIMAGEHLP_SYMBOL64 Symbol,
PSTR pszUndecoratedName,
DWORD dwUndecoratedNameLength)
{
UNIMPLEMENTED;
return FALSE;
}
DWORD WINAPI
UnDecorateSymbolNameW(PCWSTR DecoratedName,
PWSTR pszUnDecoratedName,
+7 -115
View File
@@ -26,9 +26,6 @@
#include "dbghelp_private.h"
#include "wine/debug.h"
#ifdef HAVE_REGEX_H
# include <regex.h>
#endif
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
@@ -79,13 +76,18 @@ unsigned source_new(struct module* module, const char* base, const char* name)
int len = strlen(full) + 1;
if (module->sources_used + len + 1 > module->sources_alloc)
{
/* Alloc by block of 256 bytes */
module->sources_alloc = (module->sources_used + len + 1 + 255) & ~255;
if (!module->sources)
{
module->sources_alloc = (module->sources_used + len + 1 + 255) & ~255;
module->sources = HeapAlloc(GetProcessHeap(), 0, module->sources_alloc);
}
else
{
module->sources_alloc = max( module->sources_alloc * 2,
(module->sources_used + len + 1 + 255) & ~255 );
module->sources = HeapReAlloc(GetProcessHeap(), 0, module->sources,
module->sources_alloc);
}
}
ret = module->sources_used;
memcpy(module->sources + module->sources_used, full, len);
@@ -154,116 +156,6 @@ BOOL WINAPI SymEnumSourceFiles(HANDLE hProcess, ULONG64 ModBase, PCSTR Mask,
return TRUE;
}
static inline void re_append(char** mask, unsigned* len, char ch)
{
*mask = HeapReAlloc(GetProcessHeap(), 0, *mask, ++(*len));
(*mask)[*len - 2] = ch;
}
static BOOL compile_regex(regex_t* re, const char* srcfile)
{
char* mask;
unsigned len = 1;
mask = HeapAlloc(GetProcessHeap(), 0, 1);
re_append(&mask, &len, '^');
if (!srcfile || !*srcfile) re_append(&mask, &len, '*');
else while (*srcfile)
{
switch (*srcfile)
{
case '\\':
case '/':
re_append(&mask, &len, '[');
re_append(&mask, &len, '\\');
re_append(&mask, &len, '\\');
re_append(&mask, &len, '/');
re_append(&mask, &len, ']');
break;
case '.':
re_append(&mask, &len, '\\');
re_append(&mask, &len, '.');
break;
default:
re_append(&mask, &len, *srcfile);
break;
}
srcfile++;
}
re_append(&mask, &len, '$');
mask[len - 1] = '\0';
len = regcomp(re, mask, REG_NOSUB);
HeapFree(GetProcessHeap(), 0, mask);
if (len)
{
FIXME("Couldn't compile %s\n", mask);
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
return TRUE;
}
/******************************************************************
* SymEnumLines (DBGHELP.@)
*
*/
BOOL WINAPI SymEnumLines(HANDLE hProcess, ULONG64 base, PCSTR compiland,
PCSTR srcfile, PSYM_ENUMLINES_CALLBACK cb, PVOID user)
{
struct module_pair pair;
struct hash_table_iter hti;
struct symt_ht* sym;
regex_t re;
struct line_info* dli;
void* ptr;
SRCCODEINFO sci;
const char* file;
if (!cb) return FALSE;
if (!(dbghelp_options & SYMOPT_LOAD_LINES)) return TRUE;
pair.pcs = process_find_by_handle(hProcess);
if (!pair.pcs) return FALSE;
if (compiland) FIXME("Unsupported yet (filtering on compiland %s)\n", compiland);
pair.requested = module_find_by_addr(pair.pcs, base, DMT_UNKNOWN);
if (!module_get_debug(&pair)) return FALSE;
if (!compile_regex(&re, srcfile)) return FALSE;
sci.SizeOfStruct = sizeof(sci);
sci.ModBase = base;
hash_table_iter_init(&pair.effective->ht_symbols, &hti, NULL);
while ((ptr = hash_table_iter_up(&hti)))
{
unsigned int i;
sym = GET_ENTRY(ptr, struct symt_ht, hash_elt);
if (sym->symt.tag != SymTagFunction) continue;
sci.FileName[0] = '\0';
for (i=0; i<vector_length(&((struct symt_function*)sym)->vlines); i++)
{
dli = vector_at(&((struct symt_function*)sym)->vlines, i);
if (dli->is_source_file)
{
file = source_get(pair.effective, dli->u.source_file);
if (regexec(&re, file, 0, NULL, 0) != 0) file = "";
strcpy(sci.FileName, file);
}
else if (sci.FileName[0])
{
sci.Key = dli;
sci.Obj[0] = '\0'; /* FIXME */
sci.LineNumber = dli->line_number;
sci.Address = dli->u.pc_offset;
if (!cb(&sci, user)) break;
}
}
}
regfree(&re);
return TRUE;
}
/******************************************************************
* SymGetSourceFileToken (DBGHELP.@)
*
+216 -65
View File
@@ -26,7 +26,7 @@
* The "stabs" debug format
* by Julia Menapace, Jim Kingdon, David Mackenzie
* of Cygnus Support
* available (hopefully) from http:\\sources.redhat.com\gdb\onlinedocs
* available (hopefully) from http://sources.redhat.com/gdb/onlinedocs
*/
#include "config.h"
@@ -53,6 +53,10 @@
#include <assert.h>
#include <stdarg.h>
#ifdef HAVE_MACH_O_NLIST_H
# include <mach-o/nlist.h>
#endif
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
@@ -65,9 +69,24 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_stabs);
#define strtoull _strtoui64
/* Masks for n_type field */
#ifndef N_STAB
#define N_STAB 0xe0
#endif
#ifndef N_TYPE
#define N_TYPE 0x1e
#endif
#ifndef N_EXT
#define N_EXT 0x01
#endif
/* Values for (n_type & N_TYPE) */
#ifndef N_UNDF
#define N_UNDF 0x00
#endif
#ifndef N_ABS
#define N_ABS 0x02
#endif
#define N_GSYM 0x20
#define N_FUN 0x24
@@ -81,6 +100,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp_stabs);
#define N_SLINE 0x44
#define N_ENSYM 0x4e
#define N_SO 0x64
#define N_OSO 0x66
#define N_LSYM 0x80
#define N_BINCL 0x82
#define N_SOL 0x84
@@ -162,14 +182,18 @@ static int stabs_new_include(const char* file, unsigned long val)
{
if (num_include_def == num_alloc_include_def)
{
num_alloc_include_def += 256;
if (!include_defs)
include_defs = HeapAlloc(GetProcessHeap(), 0,
{
num_alloc_include_def = 256;
include_defs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(include_defs[0]) * num_alloc_include_def);
}
else
include_defs = HeapReAlloc(GetProcessHeap(), 0, include_defs,
{
num_alloc_include_def *= 2;
include_defs = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, include_defs,
sizeof(include_defs[0]) * num_alloc_include_def);
memset(include_defs + num_include_def, 0, sizeof(include_defs[0]) * 256);
}
}
include_defs[num_include_def].name = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(file) + 1), file);
include_defs[num_include_def].value = val;
@@ -244,13 +268,13 @@ static struct symt** stabs_find_ref(long filenr, long subnr)
{
if (cu_nrofentries <= subnr)
{
cu_nrofentries = max( cu_nrofentries * 2, subnr + 1 );
if (!cu_vector)
cu_vector = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(cu_vector[0]) * (subnr+1));
cu_vector = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(cu_vector[0]) * cu_nrofentries);
else
cu_vector = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
cu_vector, sizeof(cu_vector[0]) * (subnr+1));
cu_nrofentries = subnr + 1;
cu_vector = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
cu_vector, sizeof(cu_vector[0]) * cu_nrofentries);
}
ret = &cu_vector[subnr];
}
@@ -263,13 +287,13 @@ static struct symt** stabs_find_ref(long filenr, long subnr)
if (idef->nrofentries <= subnr)
{
idef->nrofentries = max( idef->nrofentries * 2, subnr + 1 );
if (!idef->vector)
idef->vector = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(idef->vector[0]) * (subnr+1));
idef->vector = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(idef->vector[0]) * idef->nrofentries);
else
idef->vector = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
idef->vector, sizeof(idef->vector[0]) * (subnr+1));
idef->nrofentries = subnr + 1;
idef->vector = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
idef->vector, sizeof(idef->vector[0]) * idef->nrofentries);
}
ret = &idef->vector[subnr];
}
@@ -630,25 +654,21 @@ static inline int stabs_pts_read_aggregate(struct ParseTypedefData* ptd,
PTS_ABORTIF(ptd, stabs_pts_read_type_def(ptd, NULL, &adt) == -1);
if (doadd)
if (doadd && adt)
{
char tmp[256];
WCHAR* name;
DWORD64 size;
symt_get_info(adt, TI_GET_SYMNAME, &name);
strcpy(tmp, "__inherited_class_");
WideCharToMultiByte(CP_ACP, 0, name, -1,
tmp + strlen(tmp), sizeof(tmp) - strlen(tmp),
NULL, NULL);
HeapFree(GetProcessHeap(), 0, name);
strcat(tmp, symt_get_name(adt));
/* FIXME: TI_GET_LENGTH will not always work, especially when adt
* has just been seen as a forward definition and not the real stuff
* yet.
* As we don't use much the size of members in structs, this may not
* be much of a problem
*/
symt_get_info(adt, TI_GET_LENGTH, &size);
symt_get_info(ptd->module, adt, TI_GET_LENGTH, &size);
symt_add_udt_element(ptd->module, sdt, tmp, adt, ofs, (DWORD)size * 8);
}
PTS_ABORTIF(ptd, *ptd->ptr++ != ';');
@@ -1094,6 +1114,12 @@ static struct symt* stabs_parse_type(const char* stab)
return *stabs_read_type_enum(&c);
}
enum pending_obj_kind
{
PENDING_VAR,
PENDING_LINE,
};
struct pending_loc_var
{
char name[256];
@@ -1102,44 +1128,99 @@ struct pending_loc_var
struct location loc;
};
struct pending_block
struct pending_line
{
struct pending_loc_var* vars;
int source_idx;
int line_num;
unsigned long offset;
unsigned long load_offset;
};
struct pending_object
{
enum pending_obj_kind tag;
union {
struct pending_loc_var var;
struct pending_line line;
} u;
};
struct pending_list
{
struct pending_object* objs;
unsigned num;
unsigned allocated;
};
static inline void pending_add(struct pending_block* pending, const char* name,
enum DataKind dt, const struct location* loc)
static inline void pending_make_room(struct pending_list* pending)
{
if (pending->num == pending->allocated)
{
pending->allocated += 8;
if (!pending->vars)
pending->vars = HeapAlloc(GetProcessHeap(), 0,
pending->allocated * sizeof(pending->vars[0]));
else
pending->vars = HeapReAlloc(GetProcessHeap(), 0, pending->vars,
pending->allocated * sizeof(pending->vars[0]));
if (!pending->objs)
{
pending->allocated = 8;
pending->objs = HeapAlloc(GetProcessHeap(), 0,
pending->allocated * sizeof(pending->objs[0]));
}
else
{
pending->allocated *= 2;
pending->objs = HeapReAlloc(GetProcessHeap(), 0, pending->objs,
pending->allocated * sizeof(pending->objs[0]));
}
}
stab_strcpy(pending->vars[pending->num].name,
sizeof(pending->vars[pending->num].name), name);
pending->vars[pending->num].type = stabs_parse_type(name);
pending->vars[pending->num].kind = dt;
pending->vars[pending->num].loc = *loc;
}
static inline void pending_add_var(struct pending_list* pending, const char* name,
enum DataKind dt, const struct location* loc)
{
pending_make_room(pending);
pending->objs[pending->num].tag = PENDING_VAR;
stab_strcpy(pending->objs[pending->num].u.var.name,
sizeof(pending->objs[pending->num].u.var.name), name);
pending->objs[pending->num].u.var.type = stabs_parse_type(name);
pending->objs[pending->num].u.var.kind = dt;
pending->objs[pending->num].u.var.loc = *loc;
pending->num++;
}
static void pending_flush(struct pending_block* pending, struct module* module,
static inline void pending_add_line(struct pending_list* pending, int source_idx,
int line_num, unsigned long offset,
unsigned long load_offset)
{
pending_make_room(pending);
pending->objs[pending->num].tag = PENDING_LINE;
pending->objs[pending->num].u.line.source_idx = source_idx;
pending->objs[pending->num].u.line.line_num = line_num;
pending->objs[pending->num].u.line.offset = offset;
pending->objs[pending->num].u.line.load_offset = load_offset;
pending->num++;
}
static void pending_flush(struct pending_list* pending, struct module* module,
struct symt_function* func, struct symt_block* block)
{
unsigned int i;
for (i = 0; i < pending->num; i++)
{
symt_add_func_local(module, func,
pending->vars[i].kind, &pending->vars[i].loc,
block, pending->vars[i].type, pending->vars[i].name);
switch (pending->objs[i].tag)
{
case PENDING_VAR:
symt_add_func_local(module, func,
pending->objs[i].u.var.kind, &pending->objs[i].u.var.loc,
block, pending->objs[i].u.var.type, pending->objs[i].u.var.name);
break;
case PENDING_LINE:
if (module->type == DMT_MACHO)
pending->objs[i].u.line.offset -= func->address - pending->objs[i].u.line.load_offset;
symt_add_func_line(module, func, pending->objs[i].u.line.source_idx,
pending->objs[i].u.line.line_num, pending->objs[i].u.line.offset);
break;
default:
ERR("Unknown pending object tag %u\n", (unsigned)pending->objs[i].tag);
break;
}
}
pending->num = 0;
}
@@ -1156,7 +1237,7 @@ static void pending_flush(struct pending_block* pending, struct module* module,
static void stabs_finalize_function(struct module* module, struct symt_function* func,
unsigned long size)
{
IMAGEHLP_LINE il;
IMAGEHLP_LINE64 il;
struct location loc;
if (!func) return;
@@ -1175,9 +1256,25 @@ static void stabs_finalize_function(struct module* module, struct symt_function*
if (size) func->size = size;
}
static inline void stabbuf_append(char **buf, unsigned *buf_size, const char *str)
{
unsigned str_len, buf_len;
str_len = strlen(str);
buf_len = strlen(*buf);
if(str_len+buf_len >= *buf_size) {
*buf_size += buf_len + str_len;
*buf = HeapReAlloc(GetProcessHeap(), 0, *buf, *buf_size);
}
strcpy(*buf+buf_len, str);
}
BOOL stabs_parse(struct module* module, unsigned long load_offset,
const void* pv_stab_ptr, int stablen,
const char* strs, int strtablen)
const char* strs, int strtablen,
stabs_def_cb callback, void* user)
{
struct symt_function* curr_func = NULL;
struct symt_block* block = NULL;
@@ -1195,16 +1292,19 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
unsigned incl[32];
int incl_stk = -1;
int source_idx = -1;
struct pending_block pending;
struct pending_list pending_block;
struct pending_list pending_func;
BOOL ret = TRUE;
struct location loc;
unsigned char type;
nstab = stablen / sizeof(struct stab_nlist);
strs_end = strs + strtablen;
memset(srcpath, 0, sizeof(srcpath));
memset(stabs_basic, 0, sizeof(stabs_basic));
memset(&pending, 0, sizeof(pending));
memset(&pending_block, 0, sizeof(pending_block));
memset(&pending_func, 0, sizeof(pending_func));
/*
* Allocate a buffer into which we can build stab strings for cases
@@ -1230,23 +1330,22 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
* next record. Repeat the process until we find a stab without the
* '/' character, as this indicates we have the whole thing.
*/
unsigned len = strlen(ptr);
if (strlen(stabbuff) + len > stabbufflen)
{
stabbufflen += 65536;
stabbuff = HeapReAlloc(GetProcessHeap(), 0, stabbuff, stabbufflen);
}
strncat(stabbuff, ptr, len - 1);
stabbuf_append(&stabbuff, &stabbufflen, ptr);
continue;
}
else if (stabbuff[0] != '\0')
{
strcat(stabbuff, ptr);
stabbuf_append(&stabbuff, &stabbufflen, ptr);
ptr = stabbuff;
}
if (stab_ptr->n_type & N_STAB)
type = stab_ptr->n_type;
else
type = (stab_ptr->n_type & N_TYPE);
/* only symbol entries contain a typedef */
switch (stab_ptr->n_type)
switch (type)
{
case N_GSYM:
case N_LCSYM:
@@ -1263,7 +1362,8 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
*/
if (ptr != stabbuff)
{
strcpy(stabbuff, ptr);
stabbuff[0] = 0;
stabbuf_append(&stabbuff, &stabbufflen, ptr);
ptr = stabbuff;
}
stab_strcpy(symname, sizeof(symname), ptr);
@@ -1276,7 +1376,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
}
}
switch (stab_ptr->n_type)
switch (type)
{
case N_GSYM:
/*
@@ -1305,7 +1405,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
{
block = symt_open_func_block(module, curr_func, block,
stab_ptr->n_value, 0);
pending_flush(&pending, module, curr_func, block);
pending_flush(&pending_block, module, curr_func, block);
}
break;
case N_RBRAC:
@@ -1356,6 +1456,22 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
case 17:
case 18:
case 19: loc.reg = CV_REG_ST0 + stab_ptr->n_value - 12; break;
case 21:
case 22:
case 23:
case 24:
case 25:
case 26:
case 27:
case 28: loc.reg = CV_REG_XMM0 + stab_ptr->n_value - 21; break;
case 29:
case 30:
case 31:
case 32:
case 33:
case 34:
case 35:
case 36: loc.reg = CV_REG_MM0 + stab_ptr->n_value - 29; break;
default:
FIXME("Unknown register value (%lu)\n", stab_ptr->n_value);
loc.reg = CV_REG_NONE;
@@ -1373,7 +1489,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
param_type);
}
else
pending_add(&pending, ptr, DataIsLocal, &loc);
pending_add_var(&pending_block, ptr, DataIsLocal, &loc);
}
break;
case N_LSYM:
@@ -1381,19 +1497,24 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
loc.kind = loc_regrel;
loc.reg = 0; /* FIXME */
loc.offset = stab_ptr->n_value;
if (curr_func != NULL) pending_add(&pending, ptr, DataIsLocal, &loc);
if (curr_func != NULL) pending_add_var(&pending_block, ptr, DataIsLocal, &loc);
break;
case N_SLINE:
/*
* This is a line number. These are always relative to the start
* of the function (N_FUN), and this makes the lookup easier.
*/
assert(source_idx >= 0);
if (curr_func != NULL)
{
assert(source_idx >= 0);
unsigned long offset = stab_ptr->n_value;
if (module->type == DMT_MACHO)
offset -= curr_func->address - load_offset;
symt_add_func_line(module, curr_func, source_idx,
stab_ptr->n_desc, stab_ptr->n_value);
stab_ptr->n_desc, offset);
}
else pending_add_line(&pending_func, source_idx, stab_ptr->n_desc,
stab_ptr->n_value, load_offset);
break;
case N_FUN:
/*
@@ -1428,6 +1549,7 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
curr_func = symt_new_function(module, compiland, symname,
load_offset + stab_ptr->n_value, 0,
&func_type->symt);
pending_flush(&pending_func, module, curr_func, NULL);
}
else
{
@@ -1508,10 +1630,38 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
break;
case N_BNSYM:
case N_ENSYM:
case N_OSO:
/* Always ignore these, they seem to be used only on Darwin. */
break;
case N_ABS:
#ifdef N_SECT
case N_SECT:
#endif
/* FIXME: Other definition types (N_TEXT, N_DATA, N_BSS, ...)? */
if (callback)
{
BOOL is_public = (stab_ptr->n_type & N_EXT);
BOOL is_global = is_public;
#ifdef N_PEXT
/* "private extern"; shared among compilation units in a shared
* library, but not accessible from outside the library. */
if (stab_ptr->n_type & N_PEXT)
{
is_public = FALSE;
is_global = TRUE;
}
#endif
if (*ptr == '_') ptr++;
stab_strcpy(symname, sizeof(symname), ptr);
callback(module, load_offset, symname, stab_ptr->n_value,
is_public, is_global, stab_ptr->n_other, compiland, user);
}
break;
default:
ERR("Unknown stab type 0x%02x\n", stab_ptr->n_type);
ERR("Unknown stab type 0x%02x\n", type);
break;
}
stabbuff[0] = '\0';
@@ -1529,7 +1679,8 @@ BOOL stabs_parse(struct module* module, unsigned long load_offset,
done:
HeapFree(GetProcessHeap(), 0, stabbuff);
stabs_free_includes();
HeapFree(GetProcessHeap(), 0, pending.vars);
HeapFree(GetProcessHeap(), 0, pending_block.objs);
HeapFree(GetProcessHeap(), 0, pending_func.objs);
return ret;
}
+111 -434
View File
@@ -27,40 +27,45 @@
#include <string.h>
#include <assert.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "dbghelp_private.h"
#include "winternl.h"
#include "wine/winbase16.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
enum st_mode {stm_start, stm_32bit, stm_16bit, stm_done};
static const char* wine_dbgstr_addr(const ADDRESS* addr)
static DWORD64 WINAPI addr_to_linear(HANDLE hProcess, HANDLE hThread, ADDRESS64* addr)
{
if (!addr) return "(null)";
LDT_ENTRY le;
switch (addr->Mode)
{
case AddrModeFlat:
return wine_dbg_sprintf("flat<%08x>", addr->Offset);
case AddrMode1616:
return wine_dbg_sprintf("1616<%04x:%04x>", addr->Segment, addr->Offset);
if (GetThreadSelectorEntry(hThread, addr->Segment, &le))
return (le.HighWord.Bits.BaseHi << 24) +
(le.HighWord.Bits.BaseMid << 16) + le.BaseLow + LOWORD(addr->Offset);
break;
case AddrMode1632:
return wine_dbg_sprintf("1632<%04x:%08x>", addr->Segment, addr->Offset);
if (GetThreadSelectorEntry(hThread, addr->Segment, &le))
return (le.HighWord.Bits.BaseHi << 24) +
(le.HighWord.Bits.BaseMid << 16) + le.BaseLow + addr->Offset;
break;
case AddrModeReal:
return wine_dbg_sprintf("real<%04x:%04x>", addr->Segment, addr->Offset);
return (DWORD)(LOWORD(addr->Segment) << 4) + addr->Offset;
case AddrModeFlat:
return addr->Offset;
default:
return "unknown";
FIXME("Unsupported (yet) mode (%x)\n", addr->Mode);
return 0;
}
FIXME("Failed to linearize address %04x:%s (mode %x)\n",
addr->Segment, wine_dbgstr_longlong(addr->Offset), addr->Mode);
return 0;
}
static BOOL CALLBACK read_mem(HANDLE hProcess, DWORD addr, void* buffer,
DWORD size, LPDWORD nread)
{
SIZE_T r;
if (!ReadProcessMemory(hProcess, (void*)addr, buffer, size, &r)) return FALSE;
if (!ReadProcessMemory(hProcess, (void*)(DWORD_PTR)addr, buffer, size, &r)) return FALSE;
if (nread) *nread = r;
return TRUE;
}
@@ -74,39 +79,6 @@ static BOOL CALLBACK read_mem64(HANDLE hProcess, DWORD64 addr, void* buffer,
return TRUE;
}
/* indexes in Reserved array */
#define __CurrentMode 0
#define __CurrentSwitch 1
#define __NextSwitch 2
#define curr_mode (frame->Reserved[__CurrentMode])
#define curr_switch (frame->Reserved[__CurrentSwitch])
#define next_switch (frame->Reserved[__NextSwitch])
struct stack_walk_callback
{
HANDLE hProcess;
HANDLE hThread;
BOOL is32;
union
{
struct
{
PREAD_PROCESS_MEMORY_ROUTINE f_read_mem;
PTRANSLATE_ADDRESS_ROUTINE f_xlat_adr;
PFUNCTION_TABLE_ACCESS_ROUTINE f_tabl_acs;
PGET_MODULE_BASE_ROUTINE f_modl_bas;
} s32;
struct
{
PREAD_PROCESS_MEMORY_ROUTINE64 f_read_mem;
PTRANSLATE_ADDRESS_ROUTINE64 f_xlat_adr;
PFUNCTION_TABLE_ACCESS_ROUTINE64 f_tabl_acs;
PGET_MODULE_BASE_ROUTINE64 f_modl_bas;
} s64;
} u;
};
static inline void addr_32to64(const ADDRESS* addr32, ADDRESS64* addr64)
{
addr64->Offset = (ULONG64)addr32->Offset;
@@ -121,379 +93,113 @@ static inline void addr_64to32(const ADDRESS64* addr64, ADDRESS* addr32)
addr32->Mode = addr64->Mode;
}
static inline BOOL sw_read_mem(struct stack_walk_callback* cb, DWORD addr, void* ptr, DWORD sz)
BOOL sw_read_mem(struct cpu_stack_walk* csw, DWORD64 addr, void* ptr, DWORD sz)
{
if (cb->is32)
return cb->u.s32.f_read_mem(cb->hProcess, addr, ptr, sz, NULL);
if (csw->is32)
return csw->u.s32.f_read_mem(csw->hProcess, addr, ptr, sz, NULL);
else
return cb->u.s64.f_read_mem(cb->hProcess, addr, ptr, sz, NULL);
return csw->u.s64.f_read_mem(csw->hProcess, addr, ptr, sz, NULL);
}
static inline DWORD sw_xlat_addr(struct stack_walk_callback* cb, ADDRESS* addr)
DWORD64 sw_xlat_addr(struct cpu_stack_walk* csw, ADDRESS64* addr)
{
if (addr->Mode == AddrModeFlat) return addr->Offset;
if (cb->is32) return cb->u.s32.f_xlat_adr(cb->hProcess, cb->hThread, addr);
if (cb->u.s64.f_xlat_adr)
if (csw->is32)
{
ADDRESS64 addr64;
ADDRESS addr32;
addr_32to64(addr, &addr64);
return cb->u.s64.f_xlat_adr(cb->hProcess, cb->hThread, &addr64);
addr_64to32(addr, &addr32);
return csw->u.s32.f_xlat_adr(csw->hProcess, csw->hThread, &addr32);
}
return addr_to_linear(cb->hProcess, cb->hThread, addr);
else if (csw->u.s64.f_xlat_adr)
return csw->u.s64.f_xlat_adr(csw->hProcess, csw->hThread, addr);
return addr_to_linear(csw->hProcess, csw->hThread, addr);
}
static inline void* sw_tabl_acs(struct stack_walk_callback* cb, DWORD addr)
void* sw_table_access(struct cpu_stack_walk* csw, DWORD64 addr)
{
if (cb->is32)
return cb->u.s32.f_tabl_acs(cb->hProcess, addr);
if (csw->is32)
return csw->u.s32.f_tabl_acs(csw->hProcess, addr);
else
return cb->u.s64.f_tabl_acs(cb->hProcess, addr);
return csw->u.s64.f_tabl_acs(csw->hProcess, addr);
}
static inline DWORD sw_modl_bas(struct stack_walk_callback* cb, DWORD addr)
DWORD64 sw_module_base(struct cpu_stack_walk* csw, DWORD64 addr)
{
if (cb->is32)
return cb->u.s32.f_modl_bas(cb->hProcess, addr);
if (csw->is32)
return csw->u.s32.f_modl_bas(csw->hProcess, addr);
else
return cb->u.s64.f_modl_bas(cb->hProcess, addr);
}
static BOOL stack_walk(struct stack_walk_callback* cb, LPSTACKFRAME frame)
{
STACK32FRAME frame32;
STACK16FRAME frame16;
char ch;
ADDRESS tmp;
DWORD p;
WORD val;
BOOL do_switch;
/* sanity check */
if (curr_mode >= stm_done) return FALSE;
TRACE("Enter: PC=%s Frame=%s Return=%s Stack=%s Mode=%s cSwitch=%08x nSwitch=%08x\n",
wine_dbgstr_addr(&frame->AddrPC),
wine_dbgstr_addr(&frame->AddrFrame),
wine_dbgstr_addr(&frame->AddrReturn),
wine_dbgstr_addr(&frame->AddrStack),
curr_mode == stm_start ? "start" : (curr_mode == stm_16bit ? "16bit" : "32bit"),
curr_switch, next_switch);
if (curr_mode == stm_start)
{
THREAD_BASIC_INFORMATION info;
if ((frame->AddrPC.Mode == AddrModeFlat) &&
(frame->AddrFrame.Mode != AddrModeFlat))
{
WARN("Bad AddrPC.Mode / AddrFrame.Mode combination\n");
goto done_err;
}
/* Init done */
curr_mode = (frame->AddrPC.Mode == AddrModeFlat) ?
stm_32bit : stm_16bit;
/* cur_switch holds address of WOW32Reserved field in TEB in debuggee
* address space
*/
if (NtQueryInformationThread(cb->hThread, ThreadBasicInformation, &info,
sizeof(info), NULL) == STATUS_SUCCESS)
{
curr_switch = (unsigned long)info.TebBaseAddress + FIELD_OFFSET(TEB, WOW32Reserved);
if (!sw_read_mem(cb, curr_switch, &next_switch, sizeof(next_switch)))
{
WARN("Can't read TEB:WOW32Reserved\n");
goto done_err;
}
if (curr_mode == stm_16bit)
{
if (!sw_read_mem(cb, next_switch, &frame32, sizeof(frame32)))
{
WARN("Bad stack frame 0x%08x\n", next_switch);
goto done_err;
}
curr_switch = (DWORD)frame32.frame16;
tmp.Mode = AddrMode1616;
tmp.Segment = SELECTOROF(curr_switch);
tmp.Offset = OFFSETOF(curr_switch);
if (!sw_read_mem(cb, sw_xlat_addr(cb, &tmp), &ch, sizeof(ch)))
curr_switch = 0xFFFFFFFF;
}
else
{
tmp.Mode = AddrMode1616;
tmp.Segment = SELECTOROF(next_switch);
tmp.Offset = OFFSETOF(next_switch);
p = sw_xlat_addr(cb, &tmp);
if (!sw_read_mem(cb, p, &frame16, sizeof(frame16)))
{
WARN("Bad stack frame 0x%08x\n", p);
goto done_err;
}
curr_switch = (DWORD)frame16.frame32;
if (!sw_read_mem(cb, curr_switch, &ch, sizeof(ch)))
curr_switch = 0xFFFFFFFF;
}
}
else
/* FIXME: this will allow to work when we're not attached to a live target,
* but the 16 <=> 32 switch facility won't be available.
*/
curr_switch = 0;
frame->AddrReturn.Mode = frame->AddrStack.Mode = (curr_mode == stm_16bit) ? AddrMode1616 : AddrModeFlat;
/* don't set up AddrStack on first call. Either the caller has set it up, or
* we will get it in the next frame
*/
memset(&frame->AddrBStore, 0, sizeof(frame->AddrBStore));
}
else
{
if (frame->AddrFrame.Offset == 0) goto done_err;
if (frame->AddrFrame.Mode == AddrModeFlat)
{
assert(curr_mode == stm_32bit);
do_switch = curr_switch && frame->AddrFrame.Offset >= curr_switch;
}
else
{
assert(curr_mode == stm_16bit);
do_switch = curr_switch &&
frame->AddrFrame.Segment == SELECTOROF(curr_switch) &&
frame->AddrFrame.Offset >= OFFSETOF(curr_switch);
}
if (do_switch)
{
if (curr_mode == stm_16bit)
{
if (!sw_read_mem(cb, next_switch, &frame32, sizeof(frame32)))
{
WARN("Bad stack frame 0x%08x\n", next_switch);
goto done_err;
}
frame->AddrPC.Mode = AddrModeFlat;
frame->AddrPC.Segment = 0;
frame->AddrPC.Offset = frame32.retaddr;
frame->AddrFrame.Mode = AddrModeFlat;
frame->AddrFrame.Segment = 0;
frame->AddrFrame.Offset = frame32.ebp;
frame->AddrStack.Mode = AddrModeFlat;
frame->AddrStack.Segment = 0;
frame->AddrReturn.Mode = AddrModeFlat;
frame->AddrReturn.Segment = 0;
next_switch = curr_switch;
tmp.Mode = AddrMode1616;
tmp.Segment = SELECTOROF(next_switch);
tmp.Offset = OFFSETOF(next_switch);
p = sw_xlat_addr(cb, &tmp);
if (!sw_read_mem(cb, p, &frame16, sizeof(frame16)))
{
WARN("Bad stack frame 0x%08x\n", p);
goto done_err;
}
curr_switch = (DWORD)frame16.frame32;
curr_mode = stm_32bit;
if (!sw_read_mem(cb, curr_switch, &ch, sizeof(ch)))
curr_switch = 0;
}
else
{
tmp.Mode = AddrMode1616;
tmp.Segment = SELECTOROF(next_switch);
tmp.Offset = OFFSETOF(next_switch);
p = sw_xlat_addr(cb, &tmp);
if (!sw_read_mem(cb, p, &frame16, sizeof(frame16)))
{
WARN("Bad stack frame 0x%08x\n", p);
goto done_err;
}
TRACE("Got a 16 bit stack switch:"
"\n\tframe32: %08lx"
"\n\tedx:%08x ecx:%08x ebp:%08x"
"\n\tds:%04x es:%04x fs:%04x gs:%04x"
"\n\tcall_from_ip:%08x module_cs:%04x relay=%08x"
"\n\tentry_ip:%04x entry_point:%08x"
"\n\tbp:%04x ip:%04x cs:%04x\n",
(unsigned long)frame16.frame32,
frame16.edx, frame16.ecx, frame16.ebp,
frame16.ds, frame16.es, frame16.fs, frame16.gs,
frame16.callfrom_ip, frame16.module_cs, frame16.relay,
frame16.entry_ip, frame16.entry_point,
frame16.bp, frame16.ip, frame16.cs);
frame->AddrPC.Mode = AddrMode1616;
frame->AddrPC.Segment = frame16.cs;
frame->AddrPC.Offset = frame16.ip;
frame->AddrFrame.Mode = AddrMode1616;
frame->AddrFrame.Segment = SELECTOROF(next_switch);
frame->AddrFrame.Offset = frame16.bp;
frame->AddrStack.Mode = AddrMode1616;
frame->AddrStack.Segment = SELECTOROF(next_switch);
frame->AddrReturn.Mode = AddrMode1616;
frame->AddrReturn.Segment = frame16.cs;
next_switch = curr_switch;
if (!sw_read_mem(cb, next_switch, &frame32, sizeof(frame32)))
{
WARN("Bad stack frame 0x%08x\n", next_switch);
goto done_err;
}
curr_switch = (DWORD)frame32.frame16;
tmp.Mode = AddrMode1616;
tmp.Segment = SELECTOROF(curr_switch);
tmp.Offset = OFFSETOF(curr_switch);
if (!sw_read_mem(cb, sw_xlat_addr(cb, &tmp), &ch, sizeof(ch)))
curr_switch = 0;
curr_mode = stm_16bit;
}
}
else
{
frame->AddrPC = frame->AddrReturn;
if (curr_mode == stm_16bit)
{
frame->AddrStack.Offset = frame->AddrFrame.Offset + 2 * sizeof(WORD);
/* "pop up" previous BP value */
if (!sw_read_mem(cb, sw_xlat_addr(cb, &frame->AddrFrame),
&val, sizeof(WORD)))
goto done_err;
frame->AddrFrame.Offset = val;
}
else
{
frame->AddrStack.Offset = frame->AddrFrame.Offset + 2 * sizeof(DWORD);
/* "pop up" previous EBP value */
if (!sw_read_mem(cb, frame->AddrFrame.Offset,
&frame->AddrFrame.Offset, sizeof(DWORD)))
goto done_err;
}
}
}
if (curr_mode == stm_16bit)
{
unsigned int i;
p = sw_xlat_addr(cb, &frame->AddrFrame);
if (!sw_read_mem(cb, p + sizeof(WORD), &val, sizeof(WORD)))
goto done_err;
frame->AddrReturn.Offset = val;
/* get potential cs if a far call was used */
if (!sw_read_mem(cb, p + 2 * sizeof(WORD), &val, sizeof(WORD)))
goto done_err;
if (frame->AddrFrame.Offset & 1)
frame->AddrReturn.Segment = val; /* far call assumed */
else
{
/* not explicitly marked as far call,
* but check whether it could be anyway
*/
if ((val & 7) == 7 && val != frame->AddrReturn.Segment)
{
LDT_ENTRY le;
if (GetThreadSelectorEntry(cb->hThread, val, &le) &&
(le.HighWord.Bits.Type & 0x08)) /* code segment */
{
/* it is very uncommon to push a code segment cs as
* a parameter, so this should work in most cases
*/
frame->AddrReturn.Segment = val;
}
}
}
frame->AddrFrame.Offset &= ~1;
/* we "pop" parameters as 16 bit entities... of course, this won't
* work if the parameter is in fact bigger than 16bit, but
* there's no way to know that here
*/
for (i = 0; i < sizeof(frame->Params) / sizeof(frame->Params[0]); i++)
{
sw_read_mem(cb, p + (2 + i) * sizeof(WORD), &val, sizeof(val));
frame->Params[i] = val;
}
}
else
{
if (!sw_read_mem(cb, frame->AddrFrame.Offset + sizeof(DWORD),
&frame->AddrReturn.Offset, sizeof(DWORD)))
{
WARN("Cannot read new frame offset %08x\n", frame->AddrFrame.Offset + (int)sizeof(DWORD));
goto done_err;
}
sw_read_mem(cb, frame->AddrFrame.Offset + 2 * sizeof(DWORD),
frame->Params, sizeof(frame->Params));
}
frame->Far = TRUE;
frame->Virtual = TRUE;
p = sw_xlat_addr(cb, &frame->AddrPC);
if (p && sw_modl_bas(cb, p))
frame->FuncTableEntry = sw_tabl_acs(cb, p);
else
frame->FuncTableEntry = NULL;
TRACE("Leave: PC=%s Frame=%s Return=%s Stack=%s Mode=%s cSwitch=%08x nSwitch=%08x FuncTable=%p\n",
wine_dbgstr_addr(&frame->AddrPC),
wine_dbgstr_addr(&frame->AddrFrame),
wine_dbgstr_addr(&frame->AddrReturn),
wine_dbgstr_addr(&frame->AddrStack),
curr_mode == stm_start ? "start" : (curr_mode == stm_16bit ? "16bit" : "32bit"),
curr_switch, next_switch, frame->FuncTableEntry);
return TRUE;
done_err:
curr_mode = stm_done;
return FALSE;
return csw->u.s64.f_modl_bas(csw->hProcess, addr);
}
/***********************************************************************
* StackWalk (DBGHELP.@)
*/
BOOL WINAPI StackWalk(DWORD MachineType, HANDLE hProcess, HANDLE hThread,
LPSTACKFRAME frame, PVOID ctx,
LPSTACKFRAME frame32, PVOID ctx,
PREAD_PROCESS_MEMORY_ROUTINE f_read_mem,
PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,
PTRANSLATE_ADDRESS_ROUTINE f_xlat_adr)
{
struct stack_walk_callback swcb;
struct cpu_stack_walk csw;
STACKFRAME64 frame64;
BOOL ret;
struct cpu* cpu;
TRACE("(%d, %p, %p, %p, %p, %p, %p, %p, %p)\n",
MachineType, hProcess, hThread, frame, ctx,
MachineType, hProcess, hThread, frame32, ctx,
f_read_mem, FunctionTableAccessRoutine,
GetModuleBaseRoutine, f_xlat_adr);
if (MachineType != IMAGE_FILE_MACHINE_I386)
if (!(cpu = cpu_find(MachineType)))
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
swcb.hProcess = hProcess;
swcb.hThread = hThread;
swcb.is32 = TRUE;
/* sigh... MS isn't even consistent in the func prototypes */
swcb.u.s32.f_read_mem = (f_read_mem) ? f_read_mem : read_mem;
swcb.u.s32.f_xlat_adr = (f_xlat_adr) ? f_xlat_adr : addr_to_linear;
swcb.u.s32.f_tabl_acs = (FunctionTableAccessRoutine) ? FunctionTableAccessRoutine : SymFunctionTableAccess;
swcb.u.s32.f_modl_bas = (GetModuleBaseRoutine) ? GetModuleBaseRoutine : SymGetModuleBase;
addr_32to64(&frame32->AddrPC, &frame64.AddrPC);
addr_32to64(&frame32->AddrReturn, &frame64.AddrReturn);
addr_32to64(&frame32->AddrFrame, &frame64.AddrFrame);
addr_32to64(&frame32->AddrStack, &frame64.AddrStack);
addr_32to64(&frame32->AddrBStore, &frame64.AddrBStore);
frame64.FuncTableEntry = frame32->FuncTableEntry; /* FIXME */
frame64.Far = frame32->Far;
frame64.Virtual = frame32->Virtual;
frame64.Reserved[0] = frame32->Reserved[0];
frame64.Reserved[1] = frame32->Reserved[1];
frame64.Reserved[2] = frame32->Reserved[2];
/* we don't handle KdHelp */
return stack_walk(&swcb, frame);
csw.hProcess = hProcess;
csw.hThread = hThread;
csw.is32 = TRUE;
/* sigh... MS isn't even consistent in the func prototypes */
csw.u.s32.f_read_mem = (f_read_mem) ? f_read_mem : read_mem;
csw.u.s32.f_xlat_adr = f_xlat_adr;
csw.u.s32.f_tabl_acs = (FunctionTableAccessRoutine) ? FunctionTableAccessRoutine : SymFunctionTableAccess;
csw.u.s32.f_modl_bas = (GetModuleBaseRoutine) ? GetModuleBaseRoutine : SymGetModuleBase;
if ((ret = cpu->stack_walk(&csw, &frame64)))
{
addr_64to32(&frame64.AddrPC, &frame32->AddrPC);
addr_64to32(&frame64.AddrReturn, &frame32->AddrReturn);
addr_64to32(&frame64.AddrFrame, &frame32->AddrFrame);
addr_64to32(&frame64.AddrStack, &frame32->AddrStack);
addr_64to32(&frame64.AddrBStore, &frame32->AddrBStore);
frame32->FuncTableEntry = frame64.FuncTableEntry; /* FIXME */
frame32->Params[0] = frame64.Params[0];
frame32->Params[1] = frame64.Params[1];
frame32->Params[2] = frame64.Params[2];
frame32->Params[3] = frame64.Params[3];
frame32->Far = frame64.Far;
frame32->Virtual = frame64.Virtual;
frame32->Reserved[0] = frame64.Reserved[0];
frame32->Reserved[1] = frame64.Reserved[1];
frame32->Reserved[2] = frame64.Reserved[2];
}
return ret;
}
@@ -501,78 +207,49 @@ BOOL WINAPI StackWalk(DWORD MachineType, HANDLE hProcess, HANDLE hThread,
* StackWalk64 (DBGHELP.@)
*/
BOOL WINAPI StackWalk64(DWORD MachineType, HANDLE hProcess, HANDLE hThread,
LPSTACKFRAME64 frame64, PVOID ctx,
LPSTACKFRAME64 frame, PVOID ctx,
PREAD_PROCESS_MEMORY_ROUTINE64 f_read_mem,
PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
PTRANSLATE_ADDRESS_ROUTINE64 f_xlat_adr)
{
struct stack_walk_callback swcb;
STACKFRAME frame32;
BOOL ret;
struct cpu_stack_walk csw;
struct cpu* cpu;
TRACE("(%d, %p, %p, %p, %p, %p, %p, %p, %p)\n",
MachineType, hProcess, hThread, frame64, ctx,
MachineType, hProcess, hThread, frame, ctx,
f_read_mem, FunctionTableAccessRoutine,
GetModuleBaseRoutine, f_xlat_adr);
if (MachineType != IMAGE_FILE_MACHINE_I386)
if (!(cpu = cpu_find(MachineType)))
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
addr_64to32(&frame64->AddrPC, &frame32.AddrPC);
addr_64to32(&frame64->AddrReturn, &frame32.AddrReturn);
addr_64to32(&frame64->AddrFrame, &frame32.AddrFrame);
addr_64to32(&frame64->AddrStack, &frame32.AddrStack);
addr_64to32(&frame64->AddrBStore, &frame32.AddrBStore);
frame32.FuncTableEntry = frame64->FuncTableEntry; /* FIXME */
frame32.Far = frame64->Far;
frame32.Virtual = frame64->Virtual;
frame32.Reserved[0] = (ULONG)frame64->Reserved[0];
frame32.Reserved[1] = (ULONG)frame64->Reserved[1];
frame32.Reserved[2] = (ULONG)frame64->Reserved[2];
/* we don't handle KdHelp */
swcb.hProcess = hProcess;
swcb.hThread = hThread;
swcb.is32 = FALSE;
csw.hProcess = hProcess;
csw.hThread = hThread;
csw.is32 = FALSE;
/* sigh... MS isn't even consistent in the func prototypes */
swcb.u.s64.f_read_mem = (f_read_mem) ? f_read_mem : read_mem64;
swcb.u.s64.f_xlat_adr = f_xlat_adr;
swcb.u.s64.f_tabl_acs = (FunctionTableAccessRoutine) ? FunctionTableAccessRoutine : SymFunctionTableAccess64;
swcb.u.s64.f_modl_bas = (GetModuleBaseRoutine) ? GetModuleBaseRoutine : SymGetModuleBase64;
csw.u.s64.f_read_mem = (f_read_mem) ? f_read_mem : read_mem64;
csw.u.s64.f_xlat_adr = (f_xlat_adr) ? f_xlat_adr : addr_to_linear;
csw.u.s64.f_tabl_acs = (FunctionTableAccessRoutine) ? FunctionTableAccessRoutine : SymFunctionTableAccess64;
csw.u.s64.f_modl_bas = (GetModuleBaseRoutine) ? GetModuleBaseRoutine : SymGetModuleBase64;
ret = stack_walk(&swcb, &frame32);
if (!cpu->stack_walk(&csw, frame)) return FALSE;
addr_32to64(&frame32.AddrPC, &frame64->AddrPC);
addr_32to64(&frame32.AddrReturn, &frame64->AddrReturn);
addr_32to64(&frame32.AddrFrame, &frame64->AddrFrame);
addr_32to64(&frame32.AddrStack, &frame64->AddrStack);
addr_32to64(&frame32.AddrBStore, &frame64->AddrBStore);
frame64->FuncTableEntry = frame32.FuncTableEntry; /* FIXME */
frame64->Params[0] = frame32.Params[0];
frame64->Params[1] = frame32.Params[1];
frame64->Params[2] = frame32.Params[2];
frame64->Params[3] = frame32.Params[3];
frame64->Far = frame32.Far;
frame64->Virtual = frame32.Virtual;
frame64->Reserved[0] = frame32.Reserved[0];
frame64->Reserved[1] = frame32.Reserved[1];
frame64->Reserved[2] = frame32.Reserved[2];
/* we don't handle KdHelp */
frame64->KdHelp.Thread = 0xC000FADE;
frame64->KdHelp.ThCallbackStack = 0x10;
frame64->KdHelp.ThCallbackBStore = 0;
frame64->KdHelp.NextCallback = 0;
frame64->KdHelp.FramePointer = 0;
frame64->KdHelp.KiCallUserMode = 0xD000DAFE;
frame64->KdHelp.KeUserCallbackDispatcher = 0xE000F000;
frame64->KdHelp.SystemRangeStart = 0xC0000000;
frame64->KdHelp.Reserved[0] /* KiUserExceptionDispatcher */ = 0xE0005000;
frame->KdHelp.Thread = 0xC000FADE;
frame->KdHelp.ThCallbackStack = 0x10;
frame->KdHelp.ThCallbackBStore = 0;
frame->KdHelp.NextCallback = 0;
frame->KdHelp.FramePointer = 0;
frame->KdHelp.KiCallUserMode = 0xD000DAFE;
frame->KdHelp.KeUserCallbackDispatcher = 0xE000F000;
frame->KdHelp.SystemRangeStart = 0xC0000000;
frame->KdHelp.Reserved[0] /* KiUserExceptionDispatcher */ = 0xE0005000;
return ret;
return TRUE;
}
/******************************************************************
+45 -28
View File
@@ -34,14 +34,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
struct pool_arena
{
struct pool_arena* next;
char* current;
struct list entry;
char *current;
char *end;
};
void pool_init(struct pool* a, unsigned arena_size)
void pool_init(struct pool* a, size_t arena_size)
{
list_init( &a->arena_list );
list_init( &a->arena_full );
a->arena_size = arena_size;
a->first = NULL;
}
void pool_destroy(struct pool* pool)
@@ -50,58 +52,73 @@ void pool_destroy(struct pool* pool)
struct pool_arena* next;
#ifdef USE_STATS
unsigned alloc, used, num;
size_t alloc, used, num;
alloc = used = num = 0;
arena = pool->first;
while (arena)
LIST_FOR_EACH_ENTRY( arena, &pool->arena_list, struct pool_arena, entry )
{
alloc += pool->arena_size;
alloc += arena->end - (char *)arena;
used += arena->current - (char*)arena;
num++;
}
LIST_FOR_EACH_ENTRY( arena, &pool->arena_full, struct pool_arena, entry )
{
alloc += arena->end - (char *)arena;
used += arena->current - (char*)arena;
num++;
arena = arena->next;
}
if (alloc == 0) alloc = 1; /* avoid division by zero */
FIXME("STATS: pool %p has allocated %u kbytes, used %u kbytes in %u arenas,\n"
"\t\t\t\tnon-allocation ratio: %.2f%%\n",
pool, alloc >> 10, used >> 10, num, 100.0 - (float)used / (float)alloc * 100.0);
FIXME("STATS: pool %p has allocated %u kbytes, used %u kbytes in %u arenas, non-allocation ratio: %.2f%%\n",
pool, (unsigned)(alloc >> 10), (unsigned)(used >> 10), (unsigned)num,
100.0 - (float)used / (float)alloc * 100.0);
#endif
arena = pool->first;
while (arena)
LIST_FOR_EACH_ENTRY_SAFE( arena, next, &pool->arena_list, struct pool_arena, entry )
{
next = arena->next;
list_remove( &arena->entry );
HeapFree(GetProcessHeap(), 0, arena);
}
LIST_FOR_EACH_ENTRY_SAFE( arena, next, &pool->arena_full, struct pool_arena, entry )
{
list_remove( &arena->entry );
HeapFree(GetProcessHeap(), 0, arena);
arena = next;
}
pool_init(pool, 0);
}
void* pool_alloc(struct pool* pool, unsigned len)
void* pool_alloc(struct pool* pool, size_t len)
{
struct pool_arena* arena;
void* ret;
size_t size;
len = (len + 3) & ~3; /* round up size on DWORD boundary */
assert(sizeof(struct pool_arena) + len <= pool->arena_size && len);
for (arena = pool->first; arena; arena = arena->next)
LIST_FOR_EACH_ENTRY( arena, &pool->arena_list, struct pool_arena, entry )
{
if ((char*)arena + pool->arena_size - arena->current >= len)
if (arena->end - arena->current >= len)
{
ret = arena->current;
arena->current += len;
if (arena->current + 16 >= arena->end)
{
list_remove( &arena->entry );
list_add_tail( &pool->arena_full, &arena->entry );
}
return ret;
}
}
arena = HeapAlloc(GetProcessHeap(), 0, pool->arena_size);
if (!arena) {ERR("OOM\n");return NULL;}
size = max( pool->arena_size, len );
arena = HeapAlloc(GetProcessHeap(), 0, size + sizeof(struct pool_arena));
if (!arena) return NULL;
ret = (char*)arena + sizeof(*arena);
arena->next = pool->first;
pool->first = arena;
ret = arena + 1;
arena->current = (char*)ret + len;
arena->end = (char*)ret + size;
if (arena->current + 16 >= arena->end)
list_add_tail( &pool->arena_full, &arena->entry );
else
list_add_head( &pool->arena_list, &arena->entry );
return ret;
}
@@ -298,7 +315,7 @@ unsigned sparse_array_length(const struct sparse_array* sa)
return sa->elements.num_elts;
}
unsigned hash_table_hash(const char* name, unsigned num_buckets)
static unsigned hash_table_hash(const char* name, unsigned num_buckets)
{
unsigned hash = 0;
while (*name)
+475 -176
View File
File diff suppressed because it is too large Load Diff
+46 -33
View File
@@ -304,6 +304,21 @@ struct symt_array* symt_new_array(struct module* module, int min, int max,
return sym;
}
static inline DWORD symt_array_count(struct module* module, const struct symt_array* array)
{
if (array->end < 0)
{
DWORD64 elem_size;
/* One could want to also set the array->end field in array, but we won't do it
* as long as all the get_type() helpers use const objects
*/
if (symt_get_info(module, array->base_type, TI_GET_LENGTH, &elem_size) && elem_size)
return -array->end / (DWORD)elem_size;
return 0;
}
return array->end - array->start + 1;
}
struct symt_function_signature* symt_new_function_signature(struct module* module,
struct symt* ret_type,
enum CV_call_e call_conv)
@@ -400,9 +415,9 @@ BOOL WINAPI SymEnumTypes(HANDLE hProcess, ULONG64 BaseOfDll,
for (i=0; i<vector_length(&pair.effective->vtypes); i++)
{
type = *(struct symt**)vector_at(&pair.effective->vtypes, i);
sym_info->TypeIndex = (DWORD)type;
sym_info->TypeIndex = symt_ptr2index(pair.effective, type);
sym_info->info = 0; /* FIXME */
symt_get_info(type, TI_GET_LENGTH, &size);
symt_get_info(pair.effective, type, TI_GET_LENGTH, &size);
sym_info->Size = size;
sym_info->ModBase = pair.requested->module.BaseOfImage;
sym_info->Flags = 0; /* FIXME */
@@ -462,8 +477,8 @@ BOOL WINAPI SymEnumTypesW(HANDLE hProcess, ULONG64 BaseOfDll,
*
* Retrieves information about a symt (either symbol or type)
*/
BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req,
void* pInfo)
BOOL symt_get_info(struct module* module, const struct symt* type,
IMAGEHLP_SYMBOL_TYPE_INFO req, void* pInfo)
{
unsigned len;
@@ -495,7 +510,7 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req,
for (i = 0; i < tifp->Count; i++)
{
if (!(pt = vector_at(v, tifp->Start + i))) return FALSE;
tifp->ChildId[i] = (DWORD)*pt;
tifp->ChildId[i] = symt_ptr2index(module, *pt);
}
}
break;
@@ -522,7 +537,7 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req,
case SymTagFuncDebugStart:
case SymTagFuncDebugEnd:
case SymTagLabel:
if (!symt_get_info(((const struct symt_hierarchy_point*)type)->parent,
if (!symt_get_info(module, ((const struct symt_hierarchy_point*)type)->parent,
req, pInfo))
return FALSE;
X(ULONG64) += ((const struct symt_hierarchy_point*)type)->loc.offset;
@@ -597,8 +612,7 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req,
switch (type->tag)
{
case SymTagArrayType:
X(DWORD) = ((const struct symt_array*)type)->end -
((const struct symt_array*)type)->start + 1;
X(DWORD) = symt_array_count(module, (const struct symt_array*)type);
break;
case SymTagFunctionType:
/* this seems to be wrong for (future) C++ methods, where 'this' parameter
@@ -639,18 +653,17 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req,
return FALSE;
X(DWORD64) = ((const struct symt_data*)type)->u.member.length;
break;
case SymTagArrayType:
if (!symt_get_info(((const struct symt_array*)type)->base_type,
case SymTagArrayType:
if (!symt_get_info(module, ((const struct symt_array*)type)->base_type,
TI_GET_LENGTH, pInfo))
return FALSE;
X(DWORD64) *= ((const struct symt_array*)type)->end -
((const struct symt_array*)type)->start + 1;
X(DWORD64) *= symt_array_count(module, (const struct symt_array*)type);
break;
case SymTagPublicSymbol:
X(DWORD64) = ((const struct symt_public*)type)->size;
break;
case SymTagTypedef:
return symt_get_info(((const struct symt_typedef*)type)->type, TI_GET_LENGTH, pInfo);
return symt_get_info(module, ((const struct symt_typedef*)type)->type, TI_GET_LENGTH, pInfo);
case SymTagThunk:
X(DWORD64) = ((const struct symt_thunk*)type)->size;
break;
@@ -670,19 +683,19 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req,
switch (type->tag)
{
case SymTagBlock:
X(DWORD) = (DWORD)((const struct symt_block*)type)->container;
X(DWORD) = symt_ptr2index(module, ((const struct symt_block*)type)->container);
break;
case SymTagData:
X(DWORD) = (DWORD)((const struct symt_data*)type)->container;
X(DWORD) = symt_ptr2index(module, ((const struct symt_data*)type)->container);
break;
case SymTagFunction:
X(DWORD) = (DWORD)((const struct symt_function*)type)->container;
X(DWORD) = symt_ptr2index(module, ((const struct symt_function*)type)->container);
break;
case SymTagThunk:
X(DWORD) = (DWORD)((const struct symt_thunk*)type)->container;
X(DWORD) = symt_ptr2index(module, ((const struct symt_thunk*)type)->container);
break;
case SymTagFunctionArgType:
X(DWORD) = (DWORD)((const struct symt_function_arg_type*)type)->container;
X(DWORD) = symt_ptr2index(module, ((const struct symt_function_arg_type*)type)->container);
break;
default:
FIXME("Unsupported sym-tag %s for get-lexical-parent\n",
@@ -750,29 +763,29 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req,
{
/* hierarchical => hierarchical */
case SymTagArrayType:
X(DWORD) = (DWORD)((const struct symt_array*)type)->base_type;
X(DWORD) = symt_ptr2index(module, ((const struct symt_array*)type)->base_type);
break;
case SymTagPointerType:
X(DWORD) = (DWORD)((const struct symt_pointer*)type)->pointsto;
X(DWORD) = symt_ptr2index(module, ((const struct symt_pointer*)type)->pointsto);
break;
case SymTagFunctionType:
X(DWORD) = (DWORD)((const struct symt_function_signature*)type)->rettype;
X(DWORD) = symt_ptr2index(module, ((const struct symt_function_signature*)type)->rettype);
break;
case SymTagTypedef:
X(DWORD) = (DWORD)((const struct symt_typedef*)type)->type;
X(DWORD) = symt_ptr2index(module, ((const struct symt_typedef*)type)->type);
break;
/* lexical => hierarchical */
case SymTagData:
X(DWORD) = (DWORD)((const struct symt_data*)type)->type;
X(DWORD) = symt_ptr2index(module, ((const struct symt_data*)type)->type);
break;
case SymTagFunction:
X(DWORD) = (DWORD)((const struct symt_function*)type)->type;
X(DWORD) = symt_ptr2index(module, ((const struct symt_function*)type)->type);
break;
case SymTagEnum:
X(DWORD) = (DWORD)((const struct symt_enum*)type)->base_type;
X(DWORD) = symt_ptr2index(module, ((const struct symt_enum*)type)->base_type);
break;
case SymTagFunctionArgType:
X(DWORD) = (DWORD)((const struct symt_function_arg_type*)type)->arg_type;
X(DWORD) = symt_ptr2index(module, ((const struct symt_function_arg_type*)type)->arg_type);
break;
default:
FIXME("Unsupported sym-tag %s for get-type\n",
@@ -806,7 +819,7 @@ BOOL symt_get_info(const struct symt* type, IMAGEHLP_SYMBOL_TYPE_INFO req,
break;
case TI_GET_ARRAYINDEXTYPEID:
if (type->tag != SymTagArrayType) return FALSE;
X(DWORD) = (DWORD)((const struct symt_array*)type)->index_type;
X(DWORD) = symt_ptr2index(module, ((const struct symt_array*)type)->index_type);
break;
case TI_GET_CLASSPARENTID:
@@ -854,7 +867,7 @@ BOOL WINAPI SymGetTypeInfo(HANDLE hProcess, DWORD64 ModBase,
return FALSE;
}
return symt_get_info((struct symt*)TypeId, GetType, pInfo);
return symt_get_info(pair.effective, symt_index2ptr(pair.effective, TypeId), GetType, pInfo);
}
/******************************************************************
@@ -865,15 +878,15 @@ BOOL WINAPI SymGetTypeFromName(HANDLE hProcess, ULONG64 BaseOfDll,
PCSTR Name, PSYMBOL_INFO Symbol)
{
struct process* pcs = process_find_by_handle(hProcess);
struct module* module;
struct module_pair pair;
struct symt* type;
if (!pcs) return FALSE;
module = module_find_by_addr(pcs, BaseOfDll, DMT_UNKNOWN);
if (!module) return FALSE;
type = symt_find_type_by_name(module, SymTagNull, Name);
pair.requested = module_find_by_addr(pcs, BaseOfDll, DMT_UNKNOWN);
if (!module_get_debug(&pair)) return FALSE;
type = symt_find_type_by_name(pair.effective, SymTagNull, Name);
if (!type) return FALSE;
Symbol->TypeIndex = (DWORD)type;
Symbol->TypeIndex = symt_ptr2index(pair.effective, type);
return TRUE;
}
+26
View File
@@ -0,0 +1,26 @@
/*
* Copyright 2009 Louis Lenders
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define WINE_FILEDESCRIPTION_STR "Wine Image Helper"
#define WINE_FILENAME_STR "dbghelp.dll"
#define WINE_FILEVERSION 5,1,2600,3264
#define WINE_FILEVERSION_STR "5.1.2600.3264"
#define WINE_PRODUCTVERSION 5,1,2600,3264
#define WINE_PRODUCTVERSION_STR "5.1.2600.3264"
#include "wine/wine_common_ver.rc"
+130
View File
@@ -0,0 +1,130 @@
/* Fault report handling
*
* Copyright 2007 Peter Dons Tychsen
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "winreg.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "errorrep.h"
WINE_DEFAULT_DEBUG_CHANNEL(faultrep);
static const WCHAR SZ_EXCLUSIONLIST_KEY[] = {
'S','o','f','t','w','a','r','e','\\',
'M','i','c','r','o','s','o','f','t','\\',
'P','C','H','e','a','l','t','h','\\',
'E','r','r','o','r','R','e','p','o','r','t','i','n','g','\\',
'E','x','c','l','u','s','i','o','n','L','i','s','t', 0};
/*************************************************************************
* AddERExcludedApplicationW [FAULTREP.@]
*
* Adds an application to a list of applications for which fault reports
* shouldn't be generated
*
* PARAMS
* lpAppFileName [I] The filename of the application executable
*
* RETURNS
* TRUE on success, FALSE of failure
*
* NOTES
* Wine doesn't use this data but stores it in the registry (in the same place
* as Windows would) in case it will be useful in a future version
*
* According to MSDN this function should succeed even if the user has no write
* access to HKLM. This probably means that there is no error checking.
*/
BOOL WINAPI AddERExcludedApplicationW(LPCWSTR lpAppFileName)
{
WCHAR *bslash;
DWORD value = 1;
HKEY hkey;
TRACE("(%s)\n", wine_dbgstr_w(lpAppFileName));
bslash = strrchrW(lpAppFileName, '\\');
if (bslash != NULL)
lpAppFileName = bslash + 1;
if (*lpAppFileName == '\0')
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (!RegCreateKeyW(HKEY_LOCAL_MACHINE, SZ_EXCLUSIONLIST_KEY, &hkey))
{
RegSetValueExW(hkey, lpAppFileName, 0, REG_DWORD, (LPBYTE)&value, sizeof(value));
RegCloseKey(hkey);
}
return TRUE;
}
/*************************************************************************
* AddERExcludedApplicationA [FAULTREP.@]
*
* See AddERExcludedApplicationW
*/
BOOL WINAPI AddERExcludedApplicationA(LPCSTR lpAppFileName)
{
int len = MultiByteToWideChar(CP_ACP, 0, lpAppFileName, -1, NULL, 0);
WCHAR *wstr;
BOOL ret;
TRACE("(%s)\n", wine_dbgstr_a(lpAppFileName));
if (len == 0)
return FALSE;
wstr = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*len);
MultiByteToWideChar(CP_ACP, 0, lpAppFileName, -1, wstr, len);
ret = AddERExcludedApplicationW(wstr);
HeapFree(GetProcessHeap(), 0, wstr);
return ret;
}
/*************************************************************************
* ReportFault [FAULTREP.@]
*/
EFaultRepRetVal WINAPI ReportFault(LPEXCEPTION_POINTERS pep, DWORD dwOpt)
{
FIXME("%p 0x%x stub\n", pep, dwOpt);
return frrvOk;
}
/***********************************************************************
* DllMain.
*/
BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved)
{
switch(reason)
{
case DLL_WINE_PREATTACH:
return FALSE;
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(inst);
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
+9
View File
@@ -0,0 +1,9 @@
<module name="faultrep" type="win32dll" baseaddress="${BASEADDRESS_FAULTREP}" installbase="system32" installname="faultrep.dll">
<importlibrary definition="faultrep.spec" />
<include base="fusion">.</include>
<include base="ReactOS">include/reactos/wine</include>
<define name="__WINESRC__" />
<library>wine</library>
<library>advapi32</library>
<file>faultrep.c</file>
</module>
+14
View File
@@ -0,0 +1,14 @@
@ stdcall AddERExcludedApplicationA(str)
@ stdcall AddERExcludedApplicationW(wstr)
@ stub CreateMinidumpA
@ stub CreateMinidumpW
@ stub ReportEREvent
@ stub ReportEREventDW
@ stdcall ReportFault(ptr long)
@ stub ReportFaultDWM
@ stub ReportFaultFromQueue
@ stub ReportFaultToQueue
@ stub ReportHang
@ stub ReportKernelFaultA
@ stub ReportKernelFaultDWW
@ stub ReportKernelFaultW
+12
View File
@@ -837,6 +837,12 @@ SearchPathA (
DWORD RetValue = 0;
NTSTATUS Status = STATUS_SUCCESS;
if (!lpFileName)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
RtlInitAnsiString (&Path,
(LPSTR)lpPath);
RtlInitAnsiString (&FileName,
@@ -985,6 +991,12 @@ SearchPathW(LPCWSTR lpPath,
{
DWORD ret = 0;
if (!lpFileName || !lpFileName[0])
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
/* If the name contains an explicit path, ignore the path */
if (ContainsPath(lpFileName))
{
+28 -40
View File
@@ -993,7 +993,7 @@ static INT PROFILE_GetSectionNames( LPWSTR buffer, UINT len )
*
*/
static INT PROFILE_GetString( LPCWSTR section, LPCWSTR key_name,
LPCWSTR def_val, LPWSTR buffer, UINT len, BOOL win32 )
LPCWSTR def_val, LPWSTR buffer, UINT len )
{
PROFILEKEY *key = NULL;
static const WCHAR empty_strW[] = { 0 };
@@ -1114,16 +1114,12 @@ UINT WINAPI GetProfileIntW( LPCWSTR section, LPCWSTR entry, INT def_val )
return GetPrivateProfileIntW( section, entry, def_val, L"win.ini" );
}
/*
* if win32, copy:
* - Section names if 'section' is NULL
* - Keys in a Section if 'entry' is NULL
* (see MSDN doc for GetPrivateProfileString)
/***********************************************************************
* GetPrivateProfileStringW (KERNEL32.@)
*/
static int PROFILE_GetPrivateProfileString( LPCWSTR section, LPCWSTR entry,
LPCWSTR def_val, LPWSTR buffer,
UINT len, LPCWSTR filename,
BOOL win32 )
DWORD WINAPI GetPrivateProfileStringW( LPCWSTR section, LPCWSTR entry,
LPCWSTR def_val, LPWSTR buffer,
DWORD len, LPCWSTR filename )
{
int ret;
LPWSTR defval_tmp = NULL;
@@ -1141,30 +1137,30 @@ static int PROFILE_GetPrivateProfileString( LPCWSTR section, LPCWSTR entry,
if (p >= def_val)
{
int len = (int)(p - def_val) + 1;
int len = (int)(p - def_val) + 1;
defval_tmp = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
if (!defval_tmp) return 0;
memcpy(defval_tmp, def_val, len * sizeof(WCHAR));
defval_tmp[len] = '\0';
def_val = defval_tmp;
defval_tmp = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
if (!defval_tmp) return 0;
memcpy(defval_tmp, def_val, len * sizeof(WCHAR));
defval_tmp[len] = '\0';
def_val = defval_tmp;
}
}
RtlEnterCriticalSection( &PROFILE_CritSect );
if (PROFILE_Open( filename, FALSE )) {
if (win32 && (section == NULL))
if (section == NULL)
ret = PROFILE_GetSectionNames(buffer, len);
else
/* PROFILE_GetString can handle the 'entry == NULL' case */
ret = PROFILE_GetString( section, entry, def_val, buffer, len, win32 );
ret = PROFILE_GetString( section, entry, def_val, buffer, len );
} else if (buffer && def_val) {
lstrcpynW( buffer, def_val, len );
ret = wcslen( buffer );
}
else
ret = 0;
else
ret = 0;
RtlLeaveCriticalSection( &PROFILE_CritSect );
@@ -1175,7 +1171,6 @@ static int PROFILE_GetPrivateProfileString( LPCWSTR section, LPCWSTR entry,
return ret;
}
/***********************************************************************
* GetPrivateProfileStringA (KERNEL32.@)
*/
@@ -1219,21 +1214,6 @@ DWORD WINAPI GetPrivateProfileStringA( LPCSTR section, LPCSTR entry,
return ret;
}
/***********************************************************************
* GetPrivateProfileStringW (KERNEL32.@)
*/
DWORD WINAPI GetPrivateProfileStringW( LPCWSTR section, LPCWSTR entry,
LPCWSTR def_val, LPWSTR buffer,
DWORD len, LPCWSTR filename )
{
DPRINT("(%S, %S, %S, %p, %d, %S)\n",
section, entry, def_val, buffer, len, filename);
return PROFILE_GetPrivateProfileString( section, entry, def_val,
buffer, len, filename, TRUE );
}
/***********************************************************************
* GetProfileStringA (KERNEL32.@)
*/
@@ -1244,7 +1224,6 @@ DWORD WINAPI GetProfileStringA( LPCSTR section, LPCSTR entry, LPCSTR def_val,
buffer, len, "win.ini" );
}
/***********************************************************************
* GetProfileStringW (KERNEL32.@)
*/
@@ -1853,10 +1832,19 @@ WritePrivateProfileStructA (LPCSTR section, LPCSTR key,
/***********************************************************************
* CloseProfileUserMapping
* OpenProfileUserMapping (KERNEL32.@)
*/
BOOL WINAPI
CloseProfileUserMapping(VOID)
BOOL WINAPI OpenProfileUserMapping(VOID)
{
DPRINT1("(), stub!\n");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/***********************************************************************
* CloseProfileUserMapping (KERNEL32.@)
*/
BOOL WINAPI CloseProfileUserMapping(VOID)
{
DPRINT1("(), stub!\n");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-8
View File
@@ -1156,14 +1156,6 @@ OpenDataFile(HANDLE hFile, DWORD dwUnused)
return FALSE;
}
BOOL
WINAPI
OpenProfileUserMapping(VOID)
{
STUB;
return FALSE;
}
BOOL
WINAPI
PrivMoveFileIdentityW(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3)
+1 -1
View File
@@ -495,7 +495,7 @@ DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path,DWORD dwFileAttributes,
static const WCHAR p1W[] = {'%','1',0};
WCHAR sTemp [MAX_PATH];
szExt = (LPWSTR) PathFindExtensionW(szFullPath);
szExt = PathFindExtensionW(szFullPath);
TRACE("szExt=%s\n", debugstr_w(szExt));
if ( szExt &&
HCR_MapTypeToValueW(szExt, sTemp, MAX_PATH, TRUE) &&
+8 -9
View File
@@ -1673,6 +1673,14 @@ UINT WINAPI SHAddFromPropSheetExtArray(HPSXA hpsxa, LPFNADDPROPSHEETPAGE lpfnAdd
return 0;
}
/*************************************************************************
* SHCreatePropSheetExtArray [SHELL32.168]
*/
HPSXA WINAPI SHCreatePropSheetExtArray(HKEY hKey, LPCWSTR pszSubKey, UINT max_iface)
{
return SHCreatePropSheetExtArrayEx(hKey, pszSubKey, max_iface, NULL);
}
/*************************************************************************
* SHCreatePropSheetExtArrayEx [SHELL32.194]
*/
@@ -1780,15 +1788,6 @@ HPSXA WINAPI SHCreatePropSheetExtArrayEx(HKEY hKey, LPCWSTR pszSubKey, UINT max_
return (HPSXA)psxa;
}
/*************************************************************************
* SHCreatePropSheetExtArray [SHELL32.168]
*/
HPSXA WINAPI SHCreatePropSheetExtArray(HKEY hKey, LPCWSTR pszSubKey, UINT max_iface)
{
return SHCreatePropSheetExtArrayEx(hKey, pszSubKey, max_iface, NULL);
}
/*************************************************************************
* SHReplaceFromPropSheetExtArray [SHELL32.170]
*/
+9 -3
View File
@@ -531,9 +531,15 @@ static DWORD SHNotifyMoveFileW(LPCWSTR src, LPCWSTR dest)
static DWORD SHNotifyCopyFileW(LPCWSTR src, LPCWSTR dest, BOOL bFailIfExists)
{
BOOL ret;
DWORD attribs;
TRACE("(%s %s %s)\n", debugstr_w(src), debugstr_w(dest), bFailIfExists ? "failIfExists" : "");
/* Destination file may already exist with read only attribute */
attribs = GetFileAttributesW(dest);
if (IsAttrib(attribs, FILE_ATTRIBUTE_READONLY))
SetFileAttributesW(dest, attribs & ~FILE_ATTRIBUTE_READONLY);
ret = CopyFileW(src, dest, bFailIfExists);
if (ret)
{
@@ -1479,7 +1485,7 @@ int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
/*************************************************************************
* SHFreeNameMappings [shell32.246]
*
* Free the mapping handle returned by SHFileoperation if FOF_WANTSMAPPINGHANDLE
* Free the mapping handle returned by SHFileOperation if FOF_WANTSMAPPINGHANDLE
* was specified.
*
* PARAMS
@@ -1496,12 +1502,12 @@ void WINAPI SHFreeNameMappings(HANDLE hNameMapping)
for (; i>= 0; i--)
{
LPSHNAMEMAPPINGW lp = DSA_GetItemPtr((HDSA)hNameMapping, i);
LPSHNAMEMAPPINGW lp = DSA_GetItemPtr(hNameMapping, i);
SHFree(lp->pszOldPath);
SHFree(lp->pszNewPath);
}
DSA_Destroy((HDSA)hNameMapping);
DSA_Destroy(hNameMapping);
}
}
File diff suppressed because it is too large Load Diff
+3
View File
@@ -103,6 +103,9 @@
<directory name="dnsapi">
<xi:include href="dnsapi/dnsapi.rbuild" />
</directory>
<directory name="faultrep">
<xi:include href="faultrep/faultrep.rbuild" />
</directory>
<directory name="fmifs">
<xi:include href="fmifs/fmifs.rbuild" />
</directory>
+210 -85
View File
@@ -23,6 +23,10 @@
#include "config.h"
#include "wine/port.h"
#if defined(__MINGW32__) || defined (_MSC_VER)
#include <ws2tcpip.h>
#endif
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -48,7 +52,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(wininet);
* Cookies are currently memory only.
* Cookies are NOT THREAD SAFE
* Cookies could use A LOT OF MEMORY. We need some kind of memory management here!
* Cookies should care about the expiry time
*/
typedef struct _cookie_domain cookie_domain;
@@ -62,7 +65,7 @@ struct _cookie
LPWSTR lpCookieName;
LPWSTR lpCookieData;
time_t expiry; /* FIXME: not used */
FILETIME expiry;
};
struct _cookie_domain
@@ -76,7 +79,7 @@ struct _cookie_domain
static struct list domain_list = LIST_INIT(domain_list);
static cookie *COOKIE_addCookie(cookie_domain *domain, LPCWSTR name, LPCWSTR data);
static cookie *COOKIE_addCookie(cookie_domain *domain, LPCWSTR name, LPCWSTR data, FILETIME expiry);
static cookie *COOKIE_findCookie(cookie_domain *domain, LPCWSTR lpszCookieName);
static void COOKIE_deleteCookie(cookie *deadCookie, BOOL deleteDomain);
static cookie_domain *COOKIE_addDomain(LPCWSTR domain, LPCWSTR path);
@@ -84,24 +87,16 @@ static void COOKIE_deleteDomain(cookie_domain *deadDomain);
/* adds a cookie to the domain */
static cookie *COOKIE_addCookie(cookie_domain *domain, LPCWSTR name, LPCWSTR data)
static cookie *COOKIE_addCookie(cookie_domain *domain, LPCWSTR name, LPCWSTR data, FILETIME expiry)
{
cookie *newCookie = HeapAlloc(GetProcessHeap(), 0, sizeof(cookie));
list_init(&newCookie->entry);
newCookie->lpCookieName = NULL;
newCookie->lpCookieData = NULL;
if (name)
{
newCookie->lpCookieName = HeapAlloc(GetProcessHeap(), 0, (strlenW(name) + 1)*sizeof(WCHAR));
lstrcpyW(newCookie->lpCookieName, name);
}
if (data)
{
newCookie->lpCookieData = HeapAlloc(GetProcessHeap(), 0, (strlenW(data) + 1)*sizeof(WCHAR));
lstrcpyW(newCookie->lpCookieData, data);
}
newCookie->expiry = expiry;
newCookie->lpCookieName = heap_strdupW(name);
newCookie->lpCookieData = heap_strdupW(data);
TRACE("added cookie %p (data is %s)\n", newCookie, debugstr_w(data) );
@@ -156,17 +151,8 @@ static cookie_domain *COOKIE_addDomain(LPCWSTR domain, LPCWSTR path)
list_init(&newDomain->cookie_list);
newDomain->lpCookieDomain = NULL;
newDomain->lpCookiePath = NULL;
if (domain)
{
newDomain->lpCookieDomain = HeapAlloc(GetProcessHeap(), 0, (strlenW(domain) + 1)*sizeof(WCHAR));
strcpyW(newDomain->lpCookieDomain, domain);
}
if (path)
{
newDomain->lpCookiePath = HeapAlloc(GetProcessHeap(), 0, (strlenW(path) + 1)*sizeof(WCHAR));
lstrcpyW(newDomain->lpCookiePath, path);
}
newDomain->lpCookieDomain = heap_strdupW(domain);
newDomain->lpCookiePath = heap_strdupW(path);
list_add_tail(&domain_list, &newDomain->entry);
@@ -191,7 +177,28 @@ static BOOL COOKIE_crackUrlSimple(LPCWSTR lpszUrl, LPWSTR hostName, int hostName
UrlComponents.dwHostNameLength = hostNameLen;
UrlComponents.dwUrlPathLength = pathLen;
return InternetCrackUrlW(lpszUrl, 0, 0, &UrlComponents);
if (!InternetCrackUrlW(lpszUrl, 0, 0, &UrlComponents)) return FALSE;
/* discard the webpage off the end of the path */
if (UrlComponents.dwUrlPathLength)
{
if (path[UrlComponents.dwUrlPathLength - 1] != '/')
{
WCHAR *ptr;
if ((ptr = strrchrW(path, '/'))) *(++ptr) = 0;
else
{
path[0] = '/';
path[1] = 0;
}
}
}
else if (pathLen >= 2)
{
path[0] = '/';
path[1] = 0;
}
return TRUE;
}
/* match a domain. domain must match if the domain is not NULL. path must match if the path is not NULL */
@@ -215,11 +222,22 @@ static BOOL COOKIE_matchDomain(LPCWSTR lpszCookieDomain, LPCWSTR lpszCookiePath,
}
if (lpszCookiePath)
{
INT len;
TRACE("comparing paths: %s with %s\n", debugstr_w(lpszCookiePath), debugstr_w(searchDomain->lpCookiePath));
/* paths match at the beginning. so a path of /foo would match
* /foobar and /foo/bar
*/
if (!searchDomain->lpCookiePath)
return FALSE;
if (strcmpW(lpszCookiePath, searchDomain->lpCookiePath))
if (allow_partial)
{
len = lstrlenW(searchDomain->lpCookiePath);
if (strncmpiW(searchDomain->lpCookiePath, lpszCookiePath, len)!=0)
return FALSE;
}
else if (strcmpW(lpszCookiePath, searchDomain->lpCookiePath))
return FALSE;
}
return TRUE;
}
@@ -262,6 +280,7 @@ BOOL WINAPI InternetGetCookieW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
struct list * cursor;
unsigned int cnt = 0, domain_count = 0, cookie_count = 0;
WCHAR hostName[2048], path[2048];
FILETIME tm;
TRACE("(%s, %s, %p, %p)\n", debugstr_w(lpszUrl),debugstr_w(lpszCookieName),
lpCookieData, lpdwSize);
@@ -276,10 +295,12 @@ BOOL WINAPI InternetGetCookieW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
ret = COOKIE_crackUrlSimple(lpszUrl, hostName, sizeof(hostName)/sizeof(hostName[0]), path, sizeof(path)/sizeof(path[0]));
if (!ret || !hostName[0]) return FALSE;
GetSystemTimeAsFileTime(&tm);
LIST_FOR_EACH(cursor, &domain_list)
{
cookie_domain *cookiesDomain = LIST_ENTRY(cursor, cookie_domain, entry);
if (COOKIE_matchDomain(hostName, NULL /* FIXME: path */, cookiesDomain, TRUE))
if (COOKIE_matchDomain(hostName, path, cookiesDomain, TRUE))
{
struct list * cursor;
domain_count++;
@@ -288,6 +309,14 @@ BOOL WINAPI InternetGetCookieW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
LIST_FOR_EACH(cursor, &cookiesDomain->cookie_list)
{
cookie *thisCookie = LIST_ENTRY(cursor, cookie, entry);
/* check for expiry */
if ((thisCookie->expiry.dwLowDateTime != 0 || thisCookie->expiry.dwHighDateTime != 0) && CompareFileTime(&tm,&thisCookie->expiry) > 0)
{
TRACE("Found expired cookie. deleting\n");
COOKIE_deleteCookie(thisCookie, FALSE);
continue;
}
if (lpCookieData == NULL) /* return the size of the buffer required to lpdwSize */
{
unsigned int len;
@@ -356,27 +385,16 @@ BOOL WINAPI InternetGetCookieA(LPCSTR lpszUrl, LPCSTR lpszCookieName,
LPSTR lpCookieData, LPDWORD lpdwSize)
{
DWORD len;
LPWSTR szCookieData = NULL, szUrl = NULL, szCookieName = NULL;
LPWSTR szCookieData = NULL, url, name;
BOOL r;
TRACE("(%s,%s,%p)\n", debugstr_a(lpszUrl), debugstr_a(lpszCookieName),
lpCookieData);
if( lpszUrl )
{
len = MultiByteToWideChar( CP_ACP, 0, lpszUrl, -1, NULL, 0 );
szUrl = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, lpszUrl, -1, szUrl, len );
}
url = heap_strdupAtoW(lpszUrl);
name = heap_strdupAtoW(lpszCookieName);
if( lpszCookieName )
{
len = MultiByteToWideChar( CP_ACP, 0, lpszCookieName, -1, NULL, 0 );
szCookieName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, lpszCookieName, -1, szCookieName, len );
}
r = InternetGetCookieW( szUrl, szCookieName, NULL, &len );
r = InternetGetCookieW( url, name, NULL, &len );
if( r )
{
szCookieData = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
@@ -386,7 +404,7 @@ BOOL WINAPI InternetGetCookieA(LPCSTR lpszUrl, LPCSTR lpszCookieName,
}
else
{
r = InternetGetCookieW( szUrl, szCookieName, szCookieData, &len );
r = InternetGetCookieW( url, name, szCookieData, &len );
*lpdwSize = WideCharToMultiByte( CP_ACP, 0, szCookieData, len,
lpCookieData, *lpdwSize, NULL, NULL );
@@ -394,8 +412,8 @@ BOOL WINAPI InternetGetCookieA(LPCSTR lpszUrl, LPCSTR lpszCookieName,
}
HeapFree( GetProcessHeap(), 0, szCookieData );
HeapFree( GetProcessHeap(), 0, szCookieName );
HeapFree( GetProcessHeap(), 0, szUrl );
HeapFree( GetProcessHeap(), 0, name );
HeapFree( GetProcessHeap(), 0, url );
return r;
}
@@ -405,27 +423,129 @@ static BOOL set_cookie(LPCWSTR domain, LPCWSTR path, LPCWSTR cookie_name, LPCWST
cookie_domain *thisCookieDomain = NULL;
cookie *thisCookie;
struct list *cursor;
LPWSTR data, value;
WCHAR *ptr;
FILETIME expiry;
BOOL expired = FALSE;
value = data = heap_strdupW(cookie_data);
if (!data)
{
ERR("could not allocate %zu bytes for the cookie data buffer\n", (strlenW(cookie_data) + 1) * sizeof(WCHAR));
return FALSE;
}
memset(&expiry,0,sizeof(expiry));
/* lots of information can be parsed out of the cookie value */
ptr = data;
for (;;)
{
static const WCHAR szDomain[] = {'d','o','m','a','i','n','=',0};
static const WCHAR szPath[] = {'p','a','t','h','=',0};
static const WCHAR szExpires[] = {'e','x','p','i','r','e','s','=',0};
static const WCHAR szSecure[] = {'s','e','c','u','r','e',0};
static const WCHAR szHttpOnly[] = {'h','t','t','p','o','n','l','y',0};
if (!(ptr = strchrW(ptr,';'))) break;
*ptr++ = 0;
if (value != data)
HeapFree(GetProcessHeap(), 0, value);
value = HeapAlloc(GetProcessHeap(), 0, (ptr - data) * sizeof(WCHAR));
if (value == NULL)
{
HeapFree(GetProcessHeap(), 0, data);
ERR("could not allocate %zu bytes for the cookie value buffer\n", (ptr - data) * sizeof(WCHAR));
return FALSE;
}
strcpyW(value, data);
while (*ptr == ' ') ptr++; /* whitespace */
if (strncmpiW(ptr, szDomain, 7) == 0)
{
ptr+=strlenW(szDomain);
domain = ptr;
TRACE("Parsing new domain %s\n",debugstr_w(domain));
}
else if (strncmpiW(ptr, szPath, 5) == 0)
{
ptr+=strlenW(szPath);
path = ptr;
TRACE("Parsing new path %s\n",debugstr_w(path));
}
else if (strncmpiW(ptr, szExpires, 8) == 0)
{
FILETIME ft;
SYSTEMTIME st;
FIXME("persistent cookies not handled (%s)\n",debugstr_w(ptr));
ptr+=strlenW(szExpires);
if (InternetTimeToSystemTimeW(ptr, &st, 0))
{
SystemTimeToFileTime(&st, &expiry);
GetSystemTimeAsFileTime(&ft);
if (CompareFileTime(&ft,&expiry) > 0)
{
TRACE("Cookie already expired.\n");
expired = TRUE;
}
}
}
else if (strncmpiW(ptr, szSecure, 6) == 0)
{
FIXME("secure not handled (%s)\n",debugstr_w(ptr));
ptr += strlenW(szSecure);
}
else if (strncmpiW(ptr, szHttpOnly, 8) == 0)
{
FIXME("httponly not handled (%s)\n",debugstr_w(ptr));
ptr += strlenW(szHttpOnly);
}
else if (*ptr)
{
FIXME("Unknown additional option %s\n",debugstr_w(ptr));
break;
}
}
LIST_FOR_EACH(cursor, &domain_list)
{
thisCookieDomain = LIST_ENTRY(cursor, cookie_domain, entry);
if (COOKIE_matchDomain(domain, NULL /* FIXME: path */, thisCookieDomain, FALSE))
if (COOKIE_matchDomain(domain, path, thisCookieDomain, FALSE))
break;
thisCookieDomain = NULL;
}
if (!thisCookieDomain)
thisCookieDomain = COOKIE_addDomain(domain, path);
{
if (!expired)
thisCookieDomain = COOKIE_addDomain(domain, path);
else
{
HeapFree(GetProcessHeap(),0,data);
if (value != data) HeapFree(GetProcessHeap(), 0, value);
return TRUE;
}
}
if ((thisCookie = COOKIE_findCookie(thisCookieDomain, cookie_name)))
COOKIE_deleteCookie(thisCookie, FALSE);
TRACE("setting cookie %s=%s for domain %s\n", debugstr_w(cookie_name),
debugstr_w(cookie_data), debugstr_w(thisCookieDomain->lpCookieDomain));
TRACE("setting cookie %s=%s for domain %s path %s\n", debugstr_w(cookie_name),
debugstr_w(value), debugstr_w(thisCookieDomain->lpCookieDomain),debugstr_w(thisCookieDomain->lpCookiePath));
if (!COOKIE_addCookie(thisCookieDomain, cookie_name, cookie_data))
if (!expired && !COOKIE_addCookie(thisCookieDomain, cookie_name, value, expiry))
{
HeapFree(GetProcessHeap(),0,data);
if (value != data) HeapFree(GetProcessHeap(), 0, value);
return FALSE;
}
HeapFree(GetProcessHeap(),0,data);
if (value != data) HeapFree(GetProcessHeap(), 0, value);
return TRUE;
}
@@ -454,28 +574,26 @@ BOOL WINAPI InternetSetCookieW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
return FALSE;
}
hostName[0] = path[0] = 0;
hostName[0] = 0;
ret = COOKIE_crackUrlSimple(lpszUrl, hostName, sizeof(hostName)/sizeof(hostName[0]), path, sizeof(path)/sizeof(path[0]));
if (!ret || !hostName[0]) return FALSE;
if (!lpszCookieName)
{
unsigned int len;
WCHAR *cookie, *data;
len = strlenW(lpCookieData);
if (!(cookie = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR))))
cookie = heap_strdupW(lpCookieData);
if (!cookie)
{
SetLastError(ERROR_OUTOFMEMORY);
return FALSE;
}
strcpyW(cookie, lpCookieData);
/* some apps (or is it us??) try to add a cookie with no cookie name, but
* the cookie data in the form of name[=data].
*/
if (!(data = strchrW(cookie, '='))) data = cookie + len;
else data++;
if (!(data = strchrW(cookie, '='))) data = cookie + strlenW(cookie);
else *data++ = 0;
ret = set_cookie(hostName, path, cookie, data);
@@ -499,39 +617,21 @@ BOOL WINAPI InternetSetCookieW(LPCWSTR lpszUrl, LPCWSTR lpszCookieName,
BOOL WINAPI InternetSetCookieA(LPCSTR lpszUrl, LPCSTR lpszCookieName,
LPCSTR lpCookieData)
{
DWORD len;
LPWSTR szCookieData = NULL, szUrl = NULL, szCookieName = NULL;
LPWSTR data, url, name;
BOOL r;
TRACE("(%s,%s,%s)\n", debugstr_a(lpszUrl),
debugstr_a(lpszCookieName), debugstr_a(lpCookieData));
if( lpszUrl )
{
len = MultiByteToWideChar( CP_ACP, 0, lpszUrl, -1, NULL, 0 );
szUrl = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, lpszUrl, -1, szUrl, len );
}
url = heap_strdupAtoW(lpszUrl);
name = heap_strdupAtoW(lpszCookieName);
data = heap_strdupAtoW(lpCookieData);
if( lpszCookieName )
{
len = MultiByteToWideChar( CP_ACP, 0, lpszCookieName, -1, NULL, 0 );
szCookieName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, lpszCookieName, -1, szCookieName, len );
}
r = InternetSetCookieW( url, name, data );
if( lpCookieData )
{
len = MultiByteToWideChar( CP_ACP, 0, lpCookieData, -1, NULL, 0 );
szCookieData = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, lpCookieData, -1, szCookieData, len );
}
r = InternetSetCookieW( szUrl, szCookieName, szCookieData );
HeapFree( GetProcessHeap(), 0, szCookieData );
HeapFree( GetProcessHeap(), 0, szCookieName );
HeapFree( GetProcessHeap(), 0, szUrl );
HeapFree( GetProcessHeap(), 0, data );
HeapFree( GetProcessHeap(), 0, name );
HeapFree( GetProcessHeap(), 0, url );
return r;
}
@@ -692,3 +792,28 @@ BOOL WINAPI InternetSetPerSiteCookieDecisionW( LPCWSTR pchHostName, DWORD dwDeci
FIXME("(%s, 0x%08x) stub\n", debugstr_w(pchHostName), dwDecision);
return FALSE;
}
/***********************************************************************
* IsDomainLegalCookieDomainW (WININET.@)
*/
BOOL WINAPI IsDomainLegalCookieDomainW( LPCWSTR s1, LPCWSTR s2 )
{
const WCHAR *p;
FIXME("(%s, %s)\n", debugstr_w(s1), debugstr_w(s2));
if (!s1 || !s2)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (s1[0] == '.' || !s1[0] || s2[0] == '.' || !s2[0])
{
SetLastError(ERROR_INVALID_NAME);
return FALSE;
}
if (!(p = strchrW(s2, '.'))) return FALSE;
if (strchrW(p + 1, '.') && !strcmpW(p + 1, s1)) return TRUE;
else if (!strcmpW(s1, s2)) return TRUE;
return FALSE;
}
+201 -53
View File
@@ -21,6 +21,10 @@
#include "config.h"
#include "wine/port.h"
#if defined(__MINGW32__) || defined (_MSC_VER)
#include <ws2tcpip.h>
#endif
#include <stdarg.h>
#include "windef.h"
@@ -58,22 +62,23 @@ struct WININET_ErrorDlgParams
*/
static BOOL WININET_GetProxyServer( HINTERNET hRequest, LPWSTR szBuf, DWORD sz )
{
LPWININETHTTPREQW lpwhr;
LPWININETHTTPSESSIONW lpwhs = NULL;
LPWININETAPPINFOW hIC = NULL;
http_request_t *lpwhr;
http_session_t *lpwhs = NULL;
appinfo_t *hIC = NULL;
BOOL ret = FALSE;
LPWSTR p;
lpwhr = (LPWININETHTTPREQW) WININET_GetObject( hRequest );
lpwhr = (http_request_t*) WININET_GetObject( hRequest );
if (NULL == lpwhr)
return FALSE;
return FALSE;
lpwhs = lpwhr->lpHttpSession;
if (NULL == lpwhs)
return FALSE;
goto done;
hIC = lpwhs->lpAppInfo;
if (NULL == hIC)
return FALSE;
goto done;
lstrcpynW(szBuf, hIC->lpszProxy, sz);
@@ -82,7 +87,39 @@ static BOOL WININET_GetProxyServer( HINTERNET hRequest, LPWSTR szBuf, DWORD sz )
if (p)
*p = 0;
return TRUE;
ret = TRUE;
done:
WININET_Release( &lpwhr->hdr );
return ret;
}
/***********************************************************************
* WININET_GetServer
*
* Determine the name of the web server
*/
static BOOL WININET_GetServer( HINTERNET hRequest, LPWSTR szBuf, DWORD sz )
{
http_request_t *lpwhr;
http_session_t *lpwhs = NULL;
BOOL ret = FALSE;
lpwhr = (http_request_t*) WININET_GetObject( hRequest );
if (NULL == lpwhr)
return FALSE;
lpwhs = lpwhr->lpHttpSession;
if (NULL == lpwhs)
goto done;
lstrcpynW(szBuf, lpwhs->lpszHostName, sz);
ret = TRUE;
done:
WININET_Release( &lpwhr->hdr );
return ret;
}
/***********************************************************************
@@ -90,16 +127,20 @@ static BOOL WININET_GetProxyServer( HINTERNET hRequest, LPWSTR szBuf, DWORD sz )
*
* Determine the name of the (basic) Authentication realm
*/
static BOOL WININET_GetAuthRealm( HINTERNET hRequest, LPWSTR szBuf, DWORD sz )
static BOOL WININET_GetAuthRealm( HINTERNET hRequest, LPWSTR szBuf, DWORD sz, BOOL proxy )
{
LPWSTR p, q;
DWORD index;
DWORD index, query;
static const WCHAR szRealm[] = { 'r','e','a','l','m','=',0 };
/* extract the Realm from the proxy response and show it */
if (proxy)
query = HTTP_QUERY_PROXY_AUTHENTICATE;
else
query = HTTP_QUERY_WWW_AUTHENTICATE;
/* extract the Realm from the response and show it */
index = 0;
if( !HttpQueryInfoW( hRequest, HTTP_QUERY_PROXY_AUTHENTICATE,
szBuf, &sz, &index) )
if( !HttpQueryInfoW( hRequest, query, szBuf, &sz, &index) )
return FALSE;
/*
@@ -109,11 +150,10 @@ static BOOL WININET_GetAuthRealm( HINTERNET hRequest, LPWSTR szBuf, DWORD sz )
p = strchrW( szBuf, ' ' );
if( !p || strncmpW( p+1, szRealm, strlenW(szRealm) ) )
{
ERR("proxy response wrong? (%s)\n", debugstr_w(szBuf));
ERR("response wrong? (%s)\n", debugstr_w(szBuf));
return FALSE;
}
/* remove quotes */
p += 7;
if( *p == '"' )
@@ -194,44 +234,62 @@ static BOOL WININET_GetSetPassword( HWND hdlg, LPCWSTR szServer,
}
/***********************************************************************
* WININET_SetProxyAuthorization
* WININET_SetAuthorization
*/
static BOOL WININET_SetProxyAuthorization( HINTERNET hRequest,
LPWSTR username, LPWSTR password )
static BOOL WININET_SetAuthorization( HINTERNET hRequest, LPWSTR username,
LPWSTR password, BOOL proxy )
{
LPWININETHTTPREQW lpwhr;
LPWININETHTTPSESSIONW lpwhs;
LPWININETAPPINFOW hIC;
LPWSTR p;
http_request_t *lpwhr;
http_session_t *lpwhs;
BOOL ret = FALSE;
LPWSTR p, q;
lpwhr = (LPWININETHTTPREQW) WININET_GetObject( hRequest );
lpwhr = (http_request_t*) WININET_GetObject( hRequest );
if( !lpwhr )
return FALSE;
return FALSE;
lpwhs = lpwhr->lpHttpSession;
if (NULL == lpwhs || lpwhs->hdr.htype != WH_HHTTPSESSION)
{
INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE);
return FALSE;
goto done;
}
hIC = lpwhs->lpAppInfo;
p = HeapAlloc( GetProcessHeap(), 0, (strlenW( username ) + 1)*sizeof(WCHAR) );
p = heap_strdupW(username);
if( !p )
return FALSE;
lstrcpyW( p, username );
hIC->lpszProxyUsername = p;
goto done;
p = HeapAlloc( GetProcessHeap(), 0, (strlenW( password ) + 1)*sizeof(WCHAR) );
if( !p )
return FALSE;
lstrcpyW( p, password );
hIC->lpszProxyPassword = p;
q = heap_strdupW(password);
if( !q )
{
HeapFree(GetProcessHeap(), 0, username);
goto done;
}
return TRUE;
if (proxy)
{
appinfo_t *hIC = lpwhs->lpAppInfo;
HeapFree(GetProcessHeap(), 0, hIC->lpszProxyUsername);
hIC->lpszProxyUsername = p;
HeapFree(GetProcessHeap(), 0, hIC->lpszProxyPassword);
hIC->lpszProxyPassword = q;
}
else
{
HeapFree(GetProcessHeap(), 0, lpwhs->lpszUserName);
lpwhs->lpszUserName = p;
HeapFree(GetProcessHeap(), 0, lpwhs->lpszPassword);
lpwhs->lpszPassword = q;
}
ret = TRUE;
done:
WININET_Release( &lpwhr->hdr );
return ret;
}
/***********************************************************************
@@ -254,7 +312,7 @@ static INT_PTR WINAPI WININET_ProxyPasswordDialog(
/* extract the Realm from the proxy response and show it */
if( WININET_GetAuthRealm( params->hRequest,
szRealm, sizeof szRealm/sizeof(WCHAR)) )
szRealm, sizeof szRealm/sizeof(WCHAR), TRUE ) )
{
hitem = GetDlgItem( hdlg, IDC_REALM );
SetWindowTextW( hitem, szRealm );
@@ -297,13 +355,97 @@ static INT_PTR WINAPI WININET_ProxyPasswordDialog(
if( hitem &&
SendMessageW( hitem, BM_GETSTATE, 0, 0 ) &&
WININET_GetAuthRealm( params->hRequest,
szRealm, sizeof szRealm/sizeof(WCHAR)) &&
szRealm, sizeof szRealm/sizeof(WCHAR), TRUE ) &&
WININET_GetProxyServer( params->hRequest,
szServer, sizeof szServer/sizeof(WCHAR)) )
{
WININET_GetSetPassword( hdlg, szServer, szRealm, TRUE );
}
WININET_SetProxyAuthorization( params->hRequest, username, password );
WININET_SetAuthorization( params->hRequest, username, password, TRUE );
EndDialog( hdlg, ERROR_INTERNET_FORCE_RETRY );
return TRUE;
}
if( wParam == IDCANCEL )
{
EndDialog( hdlg, 0 );
return TRUE;
}
break;
}
return FALSE;
}
/***********************************************************************
* WININET_PasswordDialog
*/
static INT_PTR WINAPI WININET_PasswordDialog(
HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
HWND hitem;
struct WININET_ErrorDlgParams *params;
WCHAR szRealm[0x80], szServer[0x80];
if( uMsg == WM_INITDIALOG )
{
TRACE("WM_INITDIALOG (%08lx)\n", lParam);
/* save the parameter list */
params = (struct WININET_ErrorDlgParams*) lParam;
SetWindowLongPtrW( hdlg, GWLP_USERDATA, lParam );
/* extract the Realm from the response and show it */
if( WININET_GetAuthRealm( params->hRequest,
szRealm, sizeof szRealm/sizeof(WCHAR), FALSE ) )
{
hitem = GetDlgItem( hdlg, IDC_REALM );
SetWindowTextW( hitem, szRealm );
}
/* extract the name of the server */
if( WININET_GetServer( params->hRequest,
szServer, sizeof szServer/sizeof(WCHAR)) )
{
hitem = GetDlgItem( hdlg, IDC_SERVER );
SetWindowTextW( hitem, szServer );
}
WININET_GetSetPassword( hdlg, szServer, szRealm, FALSE );
return TRUE;
}
params = (struct WININET_ErrorDlgParams*)
GetWindowLongPtrW( hdlg, GWLP_USERDATA );
switch( uMsg )
{
case WM_COMMAND:
if( wParam == IDOK )
{
WCHAR username[0x20], password[0x20];
username[0] = 0;
hitem = GetDlgItem( hdlg, IDC_USERNAME );
if( hitem )
GetWindowTextW( hitem, username, sizeof username/sizeof(WCHAR) );
password[0] = 0;
hitem = GetDlgItem( hdlg, IDC_PASSWORD );
if( hitem )
GetWindowTextW( hitem, password, sizeof password/sizeof(WCHAR) );
hitem = GetDlgItem( hdlg, IDC_SAVEPASSWORD );
if( hitem &&
SendMessageW( hitem, BM_GETSTATE, 0, 0 ) &&
WININET_GetAuthRealm( params->hRequest,
szRealm, sizeof szRealm/sizeof(WCHAR), FALSE ) &&
WININET_GetServer( params->hRequest,
szServer, sizeof szServer/sizeof(WCHAR)) )
{
WININET_GetSetPassword( hdlg, szServer, szRealm, TRUE );
}
WININET_SetAuthorization( params->hRequest, username, password, FALSE );
EndDialog( hdlg, ERROR_INTERNET_FORCE_RETRY );
return TRUE;
@@ -362,17 +504,23 @@ DWORD WINAPI InternetErrorDlg(HWND hWnd, HINTERNET hRequest,
switch( dwError )
{
case ERROR_SUCCESS:
if( !(dwFlags & FLAGS_ERROR_UI_FILTER_FOR_ERRORS ) )
return 0;
dwStatus = WININET_GetConnectionStatus( hRequest );
if( HTTP_STATUS_PROXY_AUTH_REQ != dwStatus )
return ERROR_SUCCESS;
return DialogBoxParamW( hwininet, MAKEINTRESOURCEW( IDD_PROXYDLG ),
hWnd, WININET_ProxyPasswordDialog, (LPARAM) &params );
case ERROR_INTERNET_INCORRECT_PASSWORD:
return DialogBoxParamW( hwininet, MAKEINTRESOURCEW( IDD_PROXYDLG ),
hWnd, WININET_ProxyPasswordDialog, (LPARAM) &params );
if( !dwError && !(dwFlags & FLAGS_ERROR_UI_FILTER_FOR_ERRORS ) )
return 0;
dwStatus = WININET_GetConnectionStatus( hRequest );
switch (dwStatus)
{
case HTTP_STATUS_PROXY_AUTH_REQ:
return DialogBoxParamW( hwininet, MAKEINTRESOURCEW( IDD_PROXYDLG ),
hWnd, WININET_ProxyPasswordDialog, (LPARAM) &params );
case HTTP_STATUS_DENIED:
return DialogBoxParamW( hwininet, MAKEINTRESOURCEW( IDD_AUTHDLG ),
hWnd, WININET_PasswordDialog, (LPARAM) &params );
default:
WARN("unhandled status %u\n", dwStatus);
return 0;
}
case ERROR_INTERNET_HTTP_TO_HTTPS_ON_REDIR:
case ERROR_INTERNET_INVALID_CA:
+620 -423
View File
File diff suppressed because it is too large Load Diff
+2075 -1372
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+111 -80
View File
@@ -42,12 +42,7 @@
# include <sys/socket.h>
#endif
#if defined(__MINGW32__) || defined (_MSC_VER)
#include "ws2tcpip.h"
#ifndef MSG_WAITALL
#define MSG_WAITALL 0
#endif
#else
#if !defined(__MINGW32__) && !defined(_MSC_VER)
#define closesocket close
#define ioctlsocket ioctl
#endif /* __MINGW32__ */
@@ -62,33 +57,51 @@ typedef struct
BOOL useSSL;
int socketFD;
void *ssl_s;
char *peek_msg;
char *peek_msg_mem;
size_t peek_len;
} WININET_NETCONNECTION;
static inline LPWSTR WININET_strdupW( LPCWSTR str )
static inline LPWSTR heap_strdupW(LPCWSTR str)
{
LPWSTR ret = HeapAlloc( GetProcessHeap(), 0, (strlenW(str) + 1)*sizeof(WCHAR) );
if (ret) strcpyW( ret, str );
LPWSTR ret = NULL;
if(str) {
DWORD size;
size = (strlenW(str)+1)*sizeof(WCHAR);
ret = HeapAlloc(GetProcessHeap(), 0, size);
if(ret)
memcpy(ret, str, size);
}
return ret;
}
static inline LPWSTR WININET_strdup_AtoW( LPCSTR str )
static inline WCHAR *heap_strdupAtoW(const char *str)
{
int len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0);
LPWSTR ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
if (ret)
MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len);
LPWSTR ret = NULL;
if(str) {
DWORD len;
len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
ret = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
if(ret)
MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
}
return ret;
}
static inline LPSTR WININET_strdup_WtoA( LPCWSTR str )
static inline char *heap_strdupWtoA(LPCWSTR str)
{
int len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL);
LPSTR ret = HeapAlloc( GetProcessHeap(), 0, len );
if (ret)
WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL);
char *ret = NULL;
if(str) {
DWORD size = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL);
ret = HeapAlloc(GetProcessHeap(), 0, size);
if(ret)
WideCharToMultiByte(CP_ACP, 0, str, -1, ret, size, NULL, NULL);
}
return ret;
}
@@ -124,24 +137,25 @@ typedef enum
#define INET_OPENURL 0x0001
#define INET_CALLBACKW 0x0002
typedef struct _WININETHANDLEHEADER WININETHANDLEHEADER, *LPWININETHANDLEHEADER;
typedef struct _object_header_t object_header_t;
typedef struct {
void (*Destroy)(WININETHANDLEHEADER*);
void (*CloseConnection)(WININETHANDLEHEADER*);
DWORD (*QueryOption)(WININETHANDLEHEADER*,DWORD,void*,DWORD*,BOOL);
DWORD (*SetOption)(WININETHANDLEHEADER*,DWORD,void*,DWORD);
DWORD (*ReadFile)(WININETHANDLEHEADER*,void*,DWORD,DWORD*);
DWORD (*ReadFileExA)(WININETHANDLEHEADER*,INTERNET_BUFFERSA*,DWORD,DWORD_PTR);
BOOL (*WriteFile)(WININETHANDLEHEADER*,const void*,DWORD,DWORD*);
DWORD (*QueryDataAvailable)(WININETHANDLEHEADER*,DWORD*,DWORD,DWORD_PTR);
DWORD (*FindNextFileW)(WININETHANDLEHEADER*,void*);
} HANDLEHEADERVtbl;
void (*Destroy)(object_header_t*);
void (*CloseConnection)(object_header_t*);
DWORD (*QueryOption)(object_header_t*,DWORD,void*,DWORD*,BOOL);
DWORD (*SetOption)(object_header_t*,DWORD,void*,DWORD);
DWORD (*ReadFile)(object_header_t*,void*,DWORD,DWORD*);
DWORD (*ReadFileExA)(object_header_t*,INTERNET_BUFFERSA*,DWORD,DWORD_PTR);
DWORD (*ReadFileExW)(object_header_t*,INTERNET_BUFFERSW*,DWORD,DWORD_PTR);
DWORD (*WriteFile)(object_header_t*,const void*,DWORD,DWORD*);
DWORD (*QueryDataAvailable)(object_header_t*,DWORD*,DWORD,DWORD_PTR);
DWORD (*FindNextFileW)(object_header_t*,void*);
} object_vtbl_t;
struct _WININETHANDLEHEADER
struct _object_header_t
{
WH_TYPE htype;
const HANDLEHEADERVtbl *vtbl;
const object_vtbl_t *vtbl;
HINTERNET hInternet;
DWORD dwFlags;
DWORD_PTR dwContext;
@@ -156,28 +170,29 @@ struct _WININETHANDLEHEADER
typedef struct
{
WININETHANDLEHEADER hdr;
object_header_t hdr;
LPWSTR lpszAgent;
LPWSTR lpszProxy;
LPWSTR lpszProxyBypass;
LPWSTR lpszProxyUsername;
LPWSTR lpszProxyPassword;
DWORD dwAccessType;
} WININETAPPINFOW, *LPWININETAPPINFOW;
} appinfo_t;
typedef struct
{
WININETHANDLEHEADER hdr;
WININETAPPINFOW *lpAppInfo;
object_header_t hdr;
appinfo_t *lpAppInfo;
LPWSTR lpszHostName; /* the final destination of the request */
LPWSTR lpszServerName; /* the name of the server we directly connect to */
LPWSTR lpszUserName;
LPWSTR lpszPassword;
INTERNET_PORT nHostPort; /* the final destination port of the request */
INTERNET_PORT nServerPort; /* the port of the server we directly connect to */
struct sockaddr_in socketAddress;
} WININETHTTPSESSIONW, *LPWININETHTTPSESSIONW;
struct sockaddr_storage socketAddress;
socklen_t sa_len;
} http_session_t;
#define HDR_ISREQUEST 0x0001
#define HDR_COMMADELIMITED 0x0002
@@ -194,25 +209,38 @@ typedef struct
struct HttpAuthInfo;
typedef struct gzip_stream_t gzip_stream_t;
typedef struct
{
WININETHANDLEHEADER hdr;
WININETHTTPSESSIONW *lpHttpSession;
object_header_t hdr;
http_session_t *lpHttpSession;
LPWSTR lpszPath;
LPWSTR lpszVerb;
LPWSTR lpszRawHeaders;
WININET_NETCONNECTION netConnection;
LPWSTR lpszVersion;
LPWSTR lpszStatusText;
DWORD dwContentLength; /* total number of bytes to be read */
DWORD dwContentRead; /* bytes of the content read so far */
DWORD dwBytesToWrite;
DWORD dwBytesWritten;
HTTPHEADERW *pCustHeaders;
DWORD nCustHeaders;
HANDLE hCacheFile;
LPWSTR lpszCacheFile;
struct HttpAuthInfo *pAuthInfo;
struct HttpAuthInfo *pProxyAuthInfo;
} WININETHTTPREQW, *LPWININETHTTPREQW;
CRITICAL_SECTION read_section; /* section to protect the following fields */
DWORD dwContentLength; /* total number of bytes to be read */
DWORD dwContentRead; /* bytes of the content read so far */
BOOL read_chunked; /* are we reading in chunked mode? */
DWORD read_pos; /* current read position in read_buf */
DWORD read_size; /* valid data size in read_buf */
BYTE read_buf[4096]; /* buffer for already read but not returned data */
BOOL decoding;
gzip_stream_t *gzip_stream;
} http_request_t;
@@ -297,6 +325,12 @@ struct WORKREQ_HTTPSENDREQUESTW
BOOL bEndRequest;
};
struct WORKREQ_HTTPENDREQUESTW
{
DWORD dwFlags;
DWORD_PTR dwContext;
};
struct WORKREQ_SENDCALLBACK
{
DWORD_PTR dwContext;
@@ -320,10 +354,15 @@ struct WORKREQ_INTERNETREADFILEEXA
LPINTERNET_BUFFERSA lpBuffersOut;
};
struct WORKREQ_INTERNETREADFILEEXW
{
LPINTERNET_BUFFERSW lpBuffersOut;
};
typedef struct WORKREQ
{
void (*asyncproc)(struct WORKREQ*);
WININETHANDLEHEADER *hdr;
object_header_t *hdr;
union {
struct WORKREQ_FTPPUTFILEW FtpPutFileW;
@@ -338,77 +377,69 @@ typedef struct WORKREQ
struct WORKREQ_FTPRENAMEFILEW FtpRenameFileW;
struct WORKREQ_FTPFINDNEXTW FtpFindNextW;
struct WORKREQ_HTTPSENDREQUESTW HttpSendRequestW;
struct WORKREQ_HTTPENDREQUESTW HttpEndRequestW;
struct WORKREQ_SENDCALLBACK SendCallback;
struct WORKREQ_INTERNETOPENURLW InternetOpenUrlW;
struct WORKREQ_INTERNETOPENURLW InternetOpenUrlW;
struct WORKREQ_INTERNETREADFILEEXA InternetReadFileExA;
struct WORKREQ_INTERNETREADFILEEXW InternetReadFileExW;
} u;
} WORKREQUEST, *LPWORKREQUEST;
HINTERNET WININET_AllocHandle( LPWININETHANDLEHEADER info );
LPWININETHANDLEHEADER WININET_GetObject( HINTERNET hinternet );
LPWININETHANDLEHEADER WININET_AddRef( LPWININETHANDLEHEADER info );
BOOL WININET_Release( LPWININETHANDLEHEADER info );
HINTERNET WININET_AllocHandle( object_header_t *info );
object_header_t *WININET_GetObject( HINTERNET hinternet );
object_header_t *WININET_AddRef( object_header_t *info );
BOOL WININET_Release( object_header_t *info );
BOOL WININET_FreeHandle( HINTERNET hinternet );
DWORD INET_QueryOption(DWORD,void*,DWORD*,BOOL);
time_t ConvertTimeString(LPCWSTR asctime);
HINTERNET FTP_Connect(LPWININETAPPINFOW hIC, LPCWSTR lpszServerName,
HINTERNET FTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName,
INTERNET_PORT nServerPort, LPCWSTR lpszUserName,
LPCWSTR lpszPassword, DWORD dwFlags, DWORD_PTR dwContext,
DWORD dwInternalFlags);
HINTERNET HTTP_Connect(LPWININETAPPINFOW hIC, LPCWSTR lpszServerName,
INTERNET_PORT nServerPort, LPCWSTR lpszUserName,
LPCWSTR lpszPassword, DWORD dwFlags, DWORD_PTR dwContext,
DWORD dwInternalFlags);
DWORD HTTP_Connect(appinfo_t*,LPCWSTR,
INTERNET_PORT nServerPort, LPCWSTR lpszUserName,
LPCWSTR lpszPassword, DWORD dwFlags, DWORD_PTR dwContext,
DWORD dwInternalFlags, HINTERNET*);
BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort,
struct sockaddr_in *psa);
struct sockaddr *psa, socklen_t *sa_len);
void INTERNET_SetLastError(DWORD dwError);
DWORD INTERNET_GetLastError(void);
BOOL INTERNET_AsyncCall(LPWORKREQUEST lpWorkRequest);
DWORD INTERNET_AsyncCall(LPWORKREQUEST lpWorkRequest);
LPSTR INTERNET_GetResponseBuffer(void);
LPSTR INTERNET_GetNextLine(INT nSocket, LPDWORD dwLen);
BOOLAPI HTTP_HttpSendRequestW(LPWININETHTTPREQW lpwhr, LPCWSTR lpszHeaders,
DWORD dwHeaderLength, LPVOID lpOptional, DWORD dwOptionalLength,
DWORD dwContentLength, BOOL bEndRequest);
INTERNETAPI HINTERNET WINAPI HTTP_HttpOpenRequestW(LPWININETHTTPSESSIONW lpwhs,
LPCWSTR lpszVerb, LPCWSTR lpszObjectName, LPCWSTR lpszVersion,
LPCWSTR lpszReferrer , LPCWSTR *lpszAcceptTypes,
DWORD dwFlags, DWORD_PTR dwContext);
BOOL HTTP_FinishedReading(LPWININETHTTPREQW lpwhr);
VOID SendAsyncCallback(LPWININETHANDLEHEADER hdr, DWORD_PTR dwContext,
VOID SendAsyncCallback(object_header_t *hdr, DWORD_PTR dwContext,
DWORD dwInternetStatus, LPVOID lpvStatusInfo,
DWORD dwStatusInfoLength);
VOID INTERNET_SendCallback(LPWININETHANDLEHEADER hdr, DWORD_PTR dwContext,
VOID INTERNET_SendCallback(object_header_t *hdr, DWORD_PTR dwContext,
DWORD dwInternetStatus, LPVOID lpvStatusInfo,
DWORD dwStatusInfoLength);
LPHTTPHEADERW HTTP_GetHeader(LPWININETHTTPREQW lpwhr, LPCWSTR header);
BOOL NETCON_connected(WININET_NETCONNECTION *connection);
BOOL NETCON_init(WININET_NETCONNECTION *connnection, BOOL useSSL);
BOOL NETCON_create(WININET_NETCONNECTION *connection, int domain,
DWORD NETCON_init(WININET_NETCONNECTION *connnection, BOOL useSSL);
void NETCON_unload(void);
DWORD NETCON_create(WININET_NETCONNECTION *connection, int domain,
int type, int protocol);
BOOL NETCON_close(WININET_NETCONNECTION *connection);
BOOL NETCON_connect(WININET_NETCONNECTION *connection, const struct sockaddr *serv_addr,
DWORD NETCON_close(WININET_NETCONNECTION *connection);
DWORD NETCON_connect(WININET_NETCONNECTION *connection, const struct sockaddr *serv_addr,
unsigned int addrlen);
BOOL NETCON_secure_connect(WININET_NETCONNECTION *connection, LPCWSTR hostname);
BOOL NETCON_send(WININET_NETCONNECTION *connection, const void *msg, size_t len, int flags,
DWORD NETCON_secure_connect(WININET_NETCONNECTION *connection, LPWSTR hostname);
DWORD NETCON_send(WININET_NETCONNECTION *connection, const void *msg, size_t len, int flags,
int *sent /* out */);
BOOL NETCON_recv(WININET_NETCONNECTION *connection, void *buf, size_t len, int flags,
DWORD NETCON_recv(WININET_NETCONNECTION *connection, void *buf, size_t len, int flags,
int *recvd /* out */);
BOOL NETCON_query_data_available(WININET_NETCONNECTION *connection, DWORD *available);
BOOL NETCON_getNextLine(WININET_NETCONNECTION *connection, LPSTR lpszBuffer, LPDWORD dwBuffer);
LPCVOID NETCON_GetCert(WININET_NETCONNECTION *connection);
DWORD NETCON_set_timeout(WININET_NETCONNECTION *connection, BOOL send, int value);
int sock_get_error(int);
extern void URLCacheContainers_CreateDefaults(void);
extern void URLCacheContainers_DeleteAll(void);
+354 -299
View File
@@ -23,6 +23,12 @@
#include "config.h"
#include "wine/port.h"
#define NONAMELESSUNION
#if defined(__MINGW32__) || defined (_MSC_VER)
#include <ws2tcpip.h>
#endif
#include <sys/types.h>
#ifdef HAVE_POLL_H
#include <poll.h>
@@ -33,10 +39,12 @@
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_SYS_FILIO_H
# include <sys/filio.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
@@ -55,9 +63,6 @@
#undef FAR
#undef DSA
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#include <stdarg.h>
#include <stdlib.h>
@@ -81,7 +86,7 @@
#include "winsock2.h"
#define RESPONSE_TIMEOUT 30 /* FROM internet.c */
#define sock_get_error(x) WSAGetLastError()
WINE_DEFAULT_DEBUG_CHANNEL(wininet);
@@ -95,11 +100,23 @@ WINE_DEFAULT_DEBUG_CHANNEL(wininet);
#include <openssl/err.h>
static CRITICAL_SECTION init_ssl_cs;
static CRITICAL_SECTION_DEBUG init_ssl_cs_debug =
{
0, 0, &init_ssl_cs,
{ &init_ssl_cs_debug.ProcessLocksList,
&init_ssl_cs_debug.ProcessLocksList },
0, 0, { (DWORD_PTR)(__FILE__ ": init_ssl_cs") }
};
static CRITICAL_SECTION init_ssl_cs = { &init_ssl_cs_debug, -1, 0, 0, 0, 0 };
static void *OpenSSL_ssl_handle;
static void *OpenSSL_crypto_handle;
static SSL_METHOD *meth;
static SSL_CTX *ctx;
static int hostname_idx;
static int error_idx;
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
@@ -107,6 +124,7 @@ static SSL_CTX *ctx;
MAKE_FUNCPTR(SSL_library_init);
MAKE_FUNCPTR(SSL_load_error_strings);
MAKE_FUNCPTR(SSLv23_method);
MAKE_FUNCPTR(SSL_CTX_free);
MAKE_FUNCPTR(SSL_CTX_new);
MAKE_FUNCPTR(SSL_new);
MAKE_FUNCPTR(SSL_free);
@@ -115,46 +133,240 @@ MAKE_FUNCPTR(SSL_connect);
MAKE_FUNCPTR(SSL_shutdown);
MAKE_FUNCPTR(SSL_write);
MAKE_FUNCPTR(SSL_read);
MAKE_FUNCPTR(SSL_pending);
MAKE_FUNCPTR(SSL_get_ex_new_index);
MAKE_FUNCPTR(SSL_get_ex_data);
MAKE_FUNCPTR(SSL_set_ex_data);
MAKE_FUNCPTR(SSL_get_ex_data_X509_STORE_CTX_idx);
MAKE_FUNCPTR(SSL_get_verify_result);
MAKE_FUNCPTR(SSL_get_peer_certificate);
MAKE_FUNCPTR(SSL_CTX_get_timeout);
MAKE_FUNCPTR(SSL_CTX_set_timeout);
MAKE_FUNCPTR(SSL_CTX_set_default_verify_paths);
MAKE_FUNCPTR(i2d_X509);
MAKE_FUNCPTR(SSL_CTX_set_verify);
MAKE_FUNCPTR(X509_STORE_CTX_get_ex_data);
/* OpenSSL's libcrypto functions that we use */
MAKE_FUNCPTR(BIO_new_fp);
MAKE_FUNCPTR(CRYPTO_num_locks);
MAKE_FUNCPTR(CRYPTO_set_id_callback);
MAKE_FUNCPTR(CRYPTO_set_locking_callback);
MAKE_FUNCPTR(ERR_free_strings);
MAKE_FUNCPTR(ERR_get_error);
MAKE_FUNCPTR(ERR_error_string);
MAKE_FUNCPTR(i2d_X509);
MAKE_FUNCPTR(sk_num);
MAKE_FUNCPTR(sk_value);
#undef MAKE_FUNCPTR
static CRITICAL_SECTION *ssl_locks;
static unsigned int num_ssl_locks;
static unsigned long ssl_thread_id(void)
{
return GetCurrentThreadId();
}
static void ssl_lock_callback(int mode, int type, const char *file, int line)
{
if (mode & CRYPTO_LOCK)
EnterCriticalSection(&ssl_locks[type]);
else
LeaveCriticalSection(&ssl_locks[type]);
}
static PCCERT_CONTEXT X509_to_cert_context(X509 *cert)
{
unsigned char* buffer,*p;
INT len;
BOOL malloced = FALSE;
PCCERT_CONTEXT ret;
p = NULL;
len = pi2d_X509(cert,&p);
/*
* SSL 0.9.7 and above malloc the buffer if it is null.
* however earlier version do not and so we would need to alloc the buffer.
*
* see the i2d_X509 man page for more details.
*/
if (!p)
{
buffer = HeapAlloc(GetProcessHeap(),0,len);
p = buffer;
len = pi2d_X509(cert,&p);
}
else
{
buffer = p;
malloced = TRUE;
}
ret = CertCreateCertificateContext(X509_ASN_ENCODING,buffer,len);
if (malloced)
free(buffer);
else
HeapFree(GetProcessHeap(),0,buffer);
return ret;
}
static DWORD netconn_verify_cert(PCCERT_CONTEXT cert, HCERTSTORE store,
WCHAR *server)
{
BOOL ret;
CERT_CHAIN_PARA chainPara = { sizeof(chainPara), { 0 } };
PCCERT_CHAIN_CONTEXT chain;
char oid_server_auth[] = szOID_PKIX_KP_SERVER_AUTH;
char *server_auth[] = { oid_server_auth };
DWORD err = ERROR_SUCCESS;
TRACE("verifying %s\n", debugstr_w(server));
chainPara.RequestedUsage.Usage.cUsageIdentifier = 1;
chainPara.RequestedUsage.Usage.rgpszUsageIdentifier = server_auth;
if ((ret = CertGetCertificateChain(NULL, cert, NULL, store, &chainPara, 0,
NULL, &chain)))
{
if (chain->TrustStatus.dwErrorStatus)
{
if (chain->TrustStatus.dwErrorStatus & CERT_TRUST_IS_NOT_TIME_VALID)
err = ERROR_INTERNET_SEC_CERT_DATE_INVALID;
else if (chain->TrustStatus.dwErrorStatus &
CERT_TRUST_IS_UNTRUSTED_ROOT)
err = ERROR_INTERNET_INVALID_CA;
else if ((chain->TrustStatus.dwErrorStatus &
CERT_TRUST_IS_OFFLINE_REVOCATION) ||
(chain->TrustStatus.dwErrorStatus &
CERT_TRUST_REVOCATION_STATUS_UNKNOWN))
err = ERROR_INTERNET_SEC_CERT_NO_REV;
else if (chain->TrustStatus.dwErrorStatus & CERT_TRUST_IS_REVOKED)
err = ERROR_INTERNET_SEC_CERT_REVOKED;
else if (chain->TrustStatus.dwErrorStatus &
CERT_TRUST_IS_NOT_VALID_FOR_USAGE)
err = ERROR_INTERNET_SEC_INVALID_CERT;
else
err = ERROR_INTERNET_SEC_INVALID_CERT;
}
else
{
CERT_CHAIN_POLICY_PARA policyPara;
SSL_EXTRA_CERT_CHAIN_POLICY_PARA sslExtraPolicyPara;
CERT_CHAIN_POLICY_STATUS policyStatus;
sslExtraPolicyPara.u.cbSize = sizeof(sslExtraPolicyPara);
sslExtraPolicyPara.dwAuthType = AUTHTYPE_SERVER;
sslExtraPolicyPara.pwszServerName = server;
policyPara.cbSize = sizeof(policyPara);
policyPara.dwFlags = 0;
policyPara.pvExtraPolicyPara = &sslExtraPolicyPara;
ret = CertVerifyCertificateChainPolicy(CERT_CHAIN_POLICY_SSL,
chain, &policyPara, &policyStatus);
/* Any error in the policy status indicates that the
* policy couldn't be verified.
*/
if (ret && policyStatus.dwError)
{
if (policyStatus.dwError == CERT_E_CN_NO_MATCH)
err = ERROR_INTERNET_SEC_CERT_CN_INVALID;
else
err = ERROR_INTERNET_SEC_INVALID_CERT;
}
}
CertFreeCertificateChain(chain);
}
TRACE("returning %08x\n", err);
return err;
}
static int netconn_secure_verify(int preverify_ok, X509_STORE_CTX *ctx)
{
SSL *ssl;
WCHAR *server;
BOOL ret = FALSE;
ssl = pX509_STORE_CTX_get_ex_data(ctx,
pSSL_get_ex_data_X509_STORE_CTX_idx());
server = pSSL_get_ex_data(ssl, hostname_idx);
if (preverify_ok)
{
HCERTSTORE store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0,
CERT_STORE_CREATE_NEW_FLAG, NULL);
if (store)
{
X509 *cert;
int i;
PCCERT_CONTEXT endCert = NULL;
ret = TRUE;
for (i = 0; ret && i < psk_num((struct stack_st *)ctx->chain); i++)
{
PCCERT_CONTEXT context;
cert = (X509 *)psk_value((struct stack_st *)ctx->chain, i);
if ((context = X509_to_cert_context(cert)))
{
if (i == 0)
ret = CertAddCertificateContextToStore(store, context,
CERT_STORE_ADD_ALWAYS, &endCert);
else
ret = CertAddCertificateContextToStore(store, context,
CERT_STORE_ADD_ALWAYS, NULL);
CertFreeCertificateContext(context);
}
}
if (!endCert) ret = FALSE;
if (ret)
{
DWORD_PTR err = netconn_verify_cert(endCert, store, server);
if (err)
{
pSSL_set_ex_data(ssl, error_idx, (void *)err);
ret = FALSE;
}
}
CertFreeCertificateContext(endCert);
CertCloseStore(store, 0);
}
}
return ret;
}
#endif
BOOL NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL)
DWORD NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL)
{
connection->useSSL = FALSE;
connection->socketFD = -1;
if (useSSL)
{
#if defined(SONAME_LIBSSL) && defined(SONAME_LIBCRYPTO)
int i;
TRACE("using SSL connection\n");
EnterCriticalSection(&init_ssl_cs);
if (OpenSSL_ssl_handle) /* already initialized everything */
return TRUE;
{
LeaveCriticalSection(&init_ssl_cs);
return ERROR_SUCCESS;
}
OpenSSL_ssl_handle = wine_dlopen(SONAME_LIBSSL, RTLD_NOW, NULL, 0);
if (!OpenSSL_ssl_handle)
{
ERR("trying to use a SSL connection, but couldn't load %s. Expect trouble.\n",
SONAME_LIBSSL);
INTERNET_SetLastError(ERROR_INTERNET_SECURITY_CHANNEL_ERROR);
return FALSE;
LeaveCriticalSection(&init_ssl_cs);
return ERROR_INTERNET_SECURITY_CHANNEL_ERROR;
}
OpenSSL_crypto_handle = wine_dlopen(SONAME_LIBCRYPTO, RTLD_NOW, NULL, 0);
if (!OpenSSL_crypto_handle)
{
ERR("trying to use a SSL connection, but couldn't load %s. Expect trouble.\n",
SONAME_LIBCRYPTO);
INTERNET_SetLastError(ERROR_INTERNET_SECURITY_CHANNEL_ERROR);
return FALSE;
LeaveCriticalSection(&init_ssl_cs);
return ERROR_INTERNET_SECURITY_CHANNEL_ERROR;
}
/* mmm nice ugly macroness */
@@ -163,13 +375,14 @@ BOOL NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL)
if (!p##x) \
{ \
ERR("failed to load symbol %s\n", #x); \
INTERNET_SetLastError(ERROR_INTERNET_SECURITY_CHANNEL_ERROR); \
return FALSE; \
LeaveCriticalSection(&init_ssl_cs); \
return ERROR_INTERNET_SECURITY_CHANNEL_ERROR; \
}
DYNSSL(SSL_library_init);
DYNSSL(SSL_load_error_strings);
DYNSSL(SSLv23_method);
DYNSSL(SSL_CTX_free);
DYNSSL(SSL_CTX_new);
DYNSSL(SSL_new);
DYNSSL(SSL_free);
@@ -178,12 +391,18 @@ BOOL NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL)
DYNSSL(SSL_shutdown);
DYNSSL(SSL_write);
DYNSSL(SSL_read);
DYNSSL(SSL_pending);
DYNSSL(SSL_get_ex_new_index);
DYNSSL(SSL_get_ex_data);
DYNSSL(SSL_set_ex_data);
DYNSSL(SSL_get_ex_data_X509_STORE_CTX_idx);
DYNSSL(SSL_get_verify_result);
DYNSSL(SSL_get_peer_certificate);
DYNSSL(SSL_CTX_get_timeout);
DYNSSL(SSL_CTX_set_timeout);
DYNSSL(SSL_CTX_set_default_verify_paths);
DYNSSL(i2d_X509);
DYNSSL(SSL_CTX_set_verify);
DYNSSL(X509_STORE_CTX_get_ex_data);
#undef DYNSSL
#define DYNCRYPTO(x) \
@@ -191,12 +410,19 @@ BOOL NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL)
if (!p##x) \
{ \
ERR("failed to load symbol %s\n", #x); \
INTERNET_SetLastError(ERROR_INTERNET_SECURITY_CHANNEL_ERROR); \
return FALSE; \
LeaveCriticalSection(&init_ssl_cs); \
return ERROR_INTERNET_SECURITY_CHANNEL_ERROR; \
}
DYNCRYPTO(BIO_new_fp);
DYNCRYPTO(CRYPTO_num_locks);
DYNCRYPTO(CRYPTO_set_id_callback);
DYNCRYPTO(CRYPTO_set_locking_callback);
DYNCRYPTO(ERR_free_strings);
DYNCRYPTO(ERR_get_error);
DYNCRYPTO(ERR_error_string);
DYNCRYPTO(i2d_X509);
DYNCRYPTO(sk_num);
DYNCRYPTO(sk_value);
#undef DYNCRYPTO
pSSL_library_init();
@@ -204,15 +430,75 @@ BOOL NETCON_init(WININET_NETCONNECTION *connection, BOOL useSSL)
pBIO_new_fp(stderr, BIO_NOCLOSE); /* FIXME: should use winedebug stuff */
meth = pSSLv23_method();
connection->peek_msg = NULL;
connection->peek_msg_mem = NULL;
ctx = pSSL_CTX_new(meth);
if (!pSSL_CTX_set_default_verify_paths(ctx))
{
ERR("SSL_CTX_set_default_verify_paths failed: %s\n",
pERR_error_string(pERR_get_error(), 0));
LeaveCriticalSection(&init_ssl_cs);
return ERROR_OUTOFMEMORY;
}
hostname_idx = pSSL_get_ex_new_index(0, (void *)"hostname index",
NULL, NULL, NULL);
if (hostname_idx == -1)
{
ERR("SSL_get_ex_new_index failed; %s\n",
pERR_error_string(pERR_get_error(), 0));
LeaveCriticalSection(&init_ssl_cs);
return ERROR_OUTOFMEMORY;
}
error_idx = pSSL_get_ex_new_index(0, (void *)"error index",
NULL, NULL, NULL);
if (error_idx == -1)
{
ERR("SSL_get_ex_new_index failed; %s\n",
pERR_error_string(pERR_get_error(), 0));
LeaveCriticalSection(&init_ssl_cs);
return ERROR_OUTOFMEMORY;
}
pSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, netconn_secure_verify);
pCRYPTO_set_id_callback(ssl_thread_id);
num_ssl_locks = pCRYPTO_num_locks();
ssl_locks = HeapAlloc(GetProcessHeap(), 0, num_ssl_locks * sizeof(CRITICAL_SECTION));
if (!ssl_locks)
{
LeaveCriticalSection(&init_ssl_cs);
return ERROR_OUTOFMEMORY;
}
for (i = 0; i < num_ssl_locks; i++)
InitializeCriticalSection(&ssl_locks[i]);
pCRYPTO_set_locking_callback(ssl_lock_callback);
LeaveCriticalSection(&init_ssl_cs);
#else
FIXME("can't use SSL, not compiled in.\n");
INTERNET_SetLastError(ERROR_INTERNET_SECURITY_CHANNEL_ERROR);
return FALSE;
return ERROR_INTERNET_SECURITY_CHANNEL_ERROR;
#endif
}
return TRUE;
return ERROR_SUCCESS;
}
void NETCON_unload(void)
{
#if defined(SONAME_LIBSSL) && defined(SONAME_LIBCRYPTO)
if (OpenSSL_crypto_handle)
{
pERR_free_strings();
wine_dlclose(OpenSSL_crypto_handle, NULL, 0);
}
if (OpenSSL_ssl_handle)
{
if (ctx)
pSSL_CTX_free(ctx);
wine_dlclose(OpenSSL_ssl_handle, NULL, 0);
}
if (ssl_locks)
{
int i;
for (i = 0; i < num_ssl_locks; i++) DeleteCriticalSection(&ssl_locks[i]);
HeapFree(GetProcessHeap(), 0, ssl_locks);
}
#endif
}
BOOL NETCON_connected(WININET_NETCONNECTION *connection)
@@ -223,9 +509,8 @@ BOOL NETCON_connected(WININET_NETCONNECTION *connection)
return TRUE;
}
#if 0
/* translate a unix error code into a winsock one */
static int sock_get_error( int err )
int sock_get_error( int err )
{
#if !defined(__MINGW32__) && !defined (_MSC_VER)
switch (err)
@@ -290,47 +575,39 @@ static int sock_get_error( int err )
#endif
return err;
}
#endif
/******************************************************************************
* NETCON_create
* Basically calls 'socket()'
*/
BOOL NETCON_create(WININET_NETCONNECTION *connection, int domain,
DWORD NETCON_create(WININET_NETCONNECTION *connection, int domain,
int type, int protocol)
{
#ifdef SONAME_LIBSSL
if (connection->useSSL)
return FALSE;
return ERROR_NOT_SUPPORTED;
#endif
connection->socketFD = socket(domain, type, protocol);
if (connection->socketFD == -1)
{
INTERNET_SetLastError(sock_get_error(errno));
return FALSE;
}
return TRUE;
return sock_get_error(errno);
return ERROR_SUCCESS;
}
/******************************************************************************
* NETCON_close
* Basically calls 'close()' unless we should use SSL
*/
BOOL NETCON_close(WININET_NETCONNECTION *connection)
DWORD NETCON_close(WININET_NETCONNECTION *connection)
{
int result;
if (!NETCON_connected(connection)) return FALSE;
if (!NETCON_connected(connection)) return ERROR_SUCCESS;
#ifdef SONAME_LIBSSL
if (connection->useSSL)
{
HeapFree(GetProcessHeap(),0,connection->peek_msg_mem);
connection->peek_msg = NULL;
connection->peek_msg_mem = NULL;
connection->peek_len = 0;
pSSL_shutdown(connection->ssl_s);
pSSL_free(connection->ssl_s);
connection->ssl_s = NULL;
@@ -343,52 +620,34 @@ BOOL NETCON_close(WININET_NETCONNECTION *connection)
connection->socketFD = -1;
if (result == -1)
{
INTERNET_SetLastError(sock_get_error(errno));
return FALSE;
}
return TRUE;
return sock_get_error(errno);
return ERROR_SUCCESS;
}
#ifdef SONAME_LIBSSL
static BOOL check_hostname(X509 *cert, char *hostname)
{
/* FIXME: implement */
return TRUE;
}
#endif
/******************************************************************************
* NETCON_secure_connect
* Initiates a secure connection over an existing plaintext connection.
*/
BOOL NETCON_secure_connect(WININET_NETCONNECTION *connection, LPCWSTR hostname)
DWORD NETCON_secure_connect(WININET_NETCONNECTION *connection, LPWSTR hostname)
{
DWORD res = ERROR_NOT_SUPPORTED;
#ifdef SONAME_LIBSSL
long verify_res;
X509 *cert;
int len;
char *hostname_unix;
/* can't connect if we are already connected */
if (connection->useSSL)
{
ERR("already connected\n");
return FALSE;
return ERROR_INTERNET_CANNOT_CONNECT;
}
ctx = pSSL_CTX_new(meth);
if (!pSSL_CTX_set_default_verify_paths(ctx))
{
ERR("SSL_CTX_set_default_verify_paths failed: %s\n",
pERR_error_string(pERR_get_error(), 0));
INTERNET_SetLastError(ERROR_OUTOFMEMORY);
return FALSE;
}
connection->ssl_s = pSSL_new(ctx);
if (!connection->ssl_s)
{
ERR("SSL_new failed: %s\n",
pERR_error_string(pERR_get_error(), 0));
INTERNET_SetLastError(ERROR_OUTOFMEMORY);
res = ERROR_OUTOFMEMORY;
goto fail;
}
@@ -396,23 +655,25 @@ BOOL NETCON_secure_connect(WININET_NETCONNECTION *connection, LPCWSTR hostname)
{
ERR("SSL_set_fd failed: %s\n",
pERR_error_string(pERR_get_error(), 0));
INTERNET_SetLastError(ERROR_INTERNET_SECURITY_CHANNEL_ERROR);
res = ERROR_INTERNET_SECURITY_CHANNEL_ERROR;
goto fail;
}
if (pSSL_connect(connection->ssl_s) <= 0)
{
ERR("SSL_connect failed: %s\n",
pERR_error_string(pERR_get_error(), 0));
INTERNET_SetLastError(ERROR_INTERNET_SECURITY_CHANNEL_ERROR);
res = (DWORD_PTR)pSSL_get_ex_data(connection->ssl_s, error_idx);
if (!res)
res = ERROR_INTERNET_SECURITY_CHANNEL_ERROR;
ERR("SSL_connect failed: %d\n", res);
goto fail;
}
pSSL_set_ex_data(connection->ssl_s, hostname_idx, hostname);
cert = pSSL_get_peer_certificate(connection->ssl_s);
if (!cert)
{
ERR("no certificate for server %s\n", debugstr_w(hostname));
/* FIXME: is this the best error? */
INTERNET_SetLastError(ERROR_INTERNET_INVALID_CA);
res = ERROR_INTERNET_INVALID_CA;
goto fail;
}
verify_res = pSSL_get_verify_result(connection->ssl_s);
@@ -423,25 +684,8 @@ BOOL NETCON_secure_connect(WININET_NETCONNECTION *connection, LPCWSTR hostname)
* the moment */
}
len = WideCharToMultiByte(CP_UNIXCP, 0, hostname, -1, NULL, 0, NULL, NULL);
hostname_unix = HeapAlloc(GetProcessHeap(), 0, len);
if (!hostname_unix)
{
INTERNET_SetLastError(ERROR_OUTOFMEMORY);
goto fail;
}
WideCharToMultiByte(CP_UNIXCP, 0, hostname, -1, hostname_unix, len, NULL, NULL);
if (!check_hostname(cert, hostname_unix))
{
HeapFree(GetProcessHeap(), 0, hostname_unix);
INTERNET_SetLastError(ERROR_INTERNET_SEC_CERT_CN_INVALID);
goto fail;
}
HeapFree(GetProcessHeap(), 0, hostname_unix);
connection->useSSL = TRUE;
return TRUE;
return ERROR_SUCCESS;
fail:
if (connection->ssl_s)
@@ -451,32 +695,29 @@ fail:
connection->ssl_s = NULL;
}
#endif
return FALSE;
return res;
}
/******************************************************************************
* NETCON_connect
* Connects to the specified address.
*/
BOOL NETCON_connect(WININET_NETCONNECTION *connection, const struct sockaddr *serv_addr,
DWORD NETCON_connect(WININET_NETCONNECTION *connection, const struct sockaddr *serv_addr,
unsigned int addrlen)
{
int result;
if (!NETCON_connected(connection)) return FALSE;
result = connect(connection->socketFD, serv_addr, addrlen);
if (result == -1)
{
WARN("Unable to connect to host (%s)\n", strerror(errno));
INTERNET_SetLastError(sock_get_error(errno));
closesocket(connection->socketFD);
connection->socketFD = -1;
return FALSE;
return sock_get_error(errno);
}
return TRUE;
return ERROR_SUCCESS;
}
/******************************************************************************
@@ -484,19 +725,16 @@ BOOL NETCON_connect(WININET_NETCONNECTION *connection, const struct sockaddr *se
* Basically calls 'send()' unless we should use SSL
* number of chars send is put in *sent
*/
BOOL NETCON_send(WININET_NETCONNECTION *connection, const void *msg, size_t len, int flags,
DWORD NETCON_send(WININET_NETCONNECTION *connection, const void *msg, size_t len, int flags,
int *sent /* out */)
{
if (!NETCON_connected(connection)) return FALSE;
if (!NETCON_connected(connection)) return ERROR_INTERNET_CONNECTION_ABORTED;
if (!connection->useSSL)
{
*sent = send(connection->socketFD, msg, len, flags);
if (*sent == -1)
{
INTERNET_SetLastError(sock_get_error(errno));
return FALSE;
}
return TRUE;
return sock_get_error(errno);
return ERROR_SUCCESS;
}
else
{
@@ -505,10 +743,10 @@ BOOL NETCON_send(WININET_NETCONNECTION *connection, const void *msg, size_t len,
FIXME("SSL_write doesn't support any flags (%08x)\n", flags);
*sent = pSSL_write(connection->ssl_s, msg, len);
if (*sent < 1 && len)
return FALSE;
return TRUE;
return ERROR_INTERNET_CONNECTION_ABORTED;
return ERROR_SUCCESS;
#else
return FALSE;
return ERROR_NOT_SUPPORTED;
#endif
}
}
@@ -518,77 +756,25 @@ BOOL NETCON_send(WININET_NETCONNECTION *connection, const void *msg, size_t len,
* Basically calls 'recv()' unless we should use SSL
* number of chars received is put in *recvd
*/
BOOL NETCON_recv(WININET_NETCONNECTION *connection, void *buf, size_t len, int flags,
DWORD NETCON_recv(WININET_NETCONNECTION *connection, void *buf, size_t len, int flags,
int *recvd /* out */)
{
*recvd = 0;
if (!NETCON_connected(connection)) return FALSE;
if (!NETCON_connected(connection)) return ERROR_INTERNET_CONNECTION_ABORTED;
if (!len)
return TRUE;
return ERROR_SUCCESS;
if (!connection->useSSL)
{
*recvd = recv(connection->socketFD, buf, len, flags);
if (*recvd == -1)
{
INTERNET_SetLastError(sock_get_error(errno));
return FALSE;
}
return TRUE;
return *recvd == -1 ? sock_get_error(errno) : ERROR_SUCCESS;
}
else
{
#ifdef SONAME_LIBSSL
if (flags & ~(MSG_PEEK|MSG_WAITALL))
FIXME("SSL_read does not support the following flag: %08x\n", flags);
/* this ugly hack is all for MSG_PEEK. eww gross */
if (flags & MSG_PEEK && !connection->peek_msg)
{
connection->peek_msg = connection->peek_msg_mem = HeapAlloc(GetProcessHeap(), 0, (sizeof(char) * len) + 1);
}
else if (flags & MSG_PEEK && connection->peek_msg)
{
if (len < connection->peek_len)
FIXME("buffer isn't big enough. Do the expect us to wrap?\n");
*recvd = min(len, connection->peek_len);
memcpy(buf, connection->peek_msg, *recvd);
return TRUE;
}
else if (connection->peek_msg)
{
*recvd = min(len, connection->peek_len);
memcpy(buf, connection->peek_msg, *recvd);
connection->peek_len -= *recvd;
connection->peek_msg += *recvd;
if (connection->peek_len == 0)
{
HeapFree(GetProcessHeap(), 0, connection->peek_msg_mem);
connection->peek_msg_mem = NULL;
connection->peek_msg = NULL;
}
/* check if we got enough data from the peek buffer */
if (!(flags & MSG_WAITALL) || (*recvd == len))
return TRUE;
/* otherwise, fall through */
}
*recvd += pSSL_read(connection->ssl_s, (char*)buf + *recvd, len - *recvd);
if (flags & MSG_PEEK) /* must copy stuff into buffer */
{
connection->peek_len = *recvd;
if (!*recvd)
{
HeapFree(GetProcessHeap(), 0, connection->peek_msg_mem);
connection->peek_msg_mem = NULL;
connection->peek_msg = NULL;
}
else
memcpy(connection->peek_msg, buf, *recvd);
}
if (*recvd < 1 && len)
return FALSE;
return TRUE;
*recvd = pSSL_read(connection->ssl_s, buf, len);
return *recvd > 0 ? ERROR_SUCCESS : ERROR_INTERNET_CONNECTION_ABORTED;
#else
return FALSE;
return ERROR_NOT_SUPPORTED;
#endif
}
}
@@ -604,13 +790,9 @@ BOOL NETCON_query_data_available(WININET_NETCONNECTION *connection, DWORD *avail
if (!NETCON_connected(connection))
return FALSE;
#ifdef SONAME_LIBSSL
if (connection->peek_msg) *available = connection->peek_len;
#endif
#ifdef FIONREAD
if (!connection->useSSL)
{
#ifdef FIONREAD
int unread;
int retval = ioctlsocket(connection->socketFD, FIONREAD, &unread);
if (!retval)
@@ -618,155 +800,28 @@ BOOL NETCON_query_data_available(WININET_NETCONNECTION *connection, DWORD *avail
TRACE("%d bytes of queued, but unread data\n", unread);
*available += unread;
}
}
#endif
return TRUE;
}
/******************************************************************************
* NETCON_getNextLine
*/
BOOL NETCON_getNextLine(WININET_NETCONNECTION *connection, LPSTR lpszBuffer, LPDWORD dwBuffer)
{
TRACE("\n");
if (!NETCON_connected(connection)) return FALSE;
if (!connection->useSSL)
{
struct timeval tv;
fd_set infd;
BOOL bSuccess = FALSE;
DWORD nRecv = 0;
FD_ZERO(&infd);
FD_SET(connection->socketFD, &infd);
tv.tv_sec=RESPONSE_TIMEOUT;
tv.tv_usec=0;
while (nRecv < *dwBuffer)
{
if (select(connection->socketFD+1,&infd,NULL,NULL,&tv) > 0)
{
if (recv(connection->socketFD, &lpszBuffer[nRecv], 1, 0) <= 0)
{
INTERNET_SetLastError(sock_get_error(errno));
goto lend;
}
if (lpszBuffer[nRecv] == '\n')
{
bSuccess = TRUE;
break;
}
if (lpszBuffer[nRecv] != '\r')
nRecv++;
}
else
{
INTERNET_SetLastError(ERROR_INTERNET_TIMEOUT);
goto lend;
}
}
lend: /* FIXME: don't use labels */
if (bSuccess)
{
lpszBuffer[nRecv++] = '\0';
*dwBuffer = nRecv;
TRACE(":%u %s\n", nRecv, lpszBuffer);
return TRUE;
}
else
{
return FALSE;
}
}
else
{
#ifdef SONAME_LIBSSL
long prev_timeout;
DWORD nRecv = 0;
BOOL success = TRUE;
prev_timeout = pSSL_CTX_get_timeout(ctx);
pSSL_CTX_set_timeout(ctx, RESPONSE_TIMEOUT);
while (nRecv < *dwBuffer)
{
int recv = 1;
if (!NETCON_recv(connection, &lpszBuffer[nRecv], 1, 0, &recv))
{
INTERNET_SetLastError(ERROR_CONNECTION_ABORTED);
success = FALSE;
}
if (lpszBuffer[nRecv] == '\n')
{
success = TRUE;
break;
}
if (lpszBuffer[nRecv] != '\r')
nRecv++;
}
pSSL_CTX_set_timeout(ctx, prev_timeout);
if (success)
{
lpszBuffer[nRecv++] = '\0';
*dwBuffer = nRecv;
TRACE("_SSL:%u %s\n", nRecv, lpszBuffer);
return TRUE;
}
return FALSE;
#else
return FALSE;
*available = pSSL_pending(connection->ssl_s);
#endif
}
return TRUE;
}
LPCVOID NETCON_GetCert(WININET_NETCONNECTION *connection)
{
#ifdef SONAME_LIBSSL
X509* cert;
unsigned char* buffer,*p;
INT len;
BOOL malloced = FALSE;
LPCVOID r = NULL;
if (!connection->useSSL)
return NULL;
cert = pSSL_get_peer_certificate(connection->ssl_s);
p = NULL;
len = pi2d_X509(cert,&p);
/*
* SSL 0.9.7 and above malloc the buffer if it is null.
* however earlier version do not and so we would need to alloc the buffer.
*
* see the i2d_X509 man page for more details.
*/
if (!p)
{
buffer = HeapAlloc(GetProcessHeap(),0,len);
p = buffer;
len = pi2d_X509(cert,&p);
}
else
{
buffer = p;
malloced = TRUE;
}
r = CertCreateCertificateContext(X509_ASN_ENCODING,buffer,len);
if (malloced)
free(buffer);
else
HeapFree(GetProcessHeap(),0,buffer);
r = X509_to_cert_context(cert);
return r;
#else
return NULL;
@@ -788,7 +843,7 @@ DWORD NETCON_set_timeout(WININET_NETCONNECTION *connection, BOOL send, int value
tv.tv_usec = (value % 1000) * 1000;
result = setsockopt(connection->socketFD, SOL_SOCKET,
send ? SO_SNDTIMEO : SO_RCVTIMEO, &tv,
send ? SO_SNDTIMEO : SO_RCVTIMEO, (void*)&tv,
sizeof(tv));
if (result == -1)
+5
View File
@@ -18,6 +18,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <windef.h>
#include <winuser.h>
#define IDD_AUTHDLG 0x399
#define IDD_PROXYDLG 0x400
#define IDC_PROXY 0x401
@@ -25,5 +29,6 @@
#define IDC_USERNAME 0x403
#define IDC_PASSWORD 0x404
#define IDC_SAVEPASSWORD 0x405
#define IDC_SERVER 0x406
#define IDS_LANCONNECTION 0x500
+11 -7
View File
@@ -43,24 +43,28 @@
#include "wininet_Bg.rc"
#include "wininet_Cs.rc"
#include "wininet_Da.rc"
#include "wininet_De.rc"
#include "wininet_En.rc"
#include "wininet_Eo.rc"
#include "wininet_Es.rc"
#include "wininet_Fi.rc"
#include "wininet_Fr.rc"
#include "wininet_Hu.rc"
#include "wininet_It.rc"
#include "wininet_Ja.rc"
#include "wininet_Ko.rc"
#include "wininet_Nl.rc"
#include "wininet_No.rc"
#include "wininet_Pl.rc"
#include "wininet_Sv.rc"
#include "wininet_Uk.rc"
#include "wininet_Tr.rc"
/* UTF-8 */
#include "wininet_De.rc"
#include "wininet_Fr.rc"
#include "wininet_Ja.rc"
#include "wininet_Lt.rc"
#include "wininet_No.rc"
#include "wininet_Pt.rc"
#include "wininet_Ro.rc"
#include "wininet_Ru.rc"
#include "wininet_Si.rc"
#include "wininet_Sv.rc"
#include "wininet_Uk.rc"
#include "wininet_Tr.rc"
#include "wininet_Zh.rc"
+118 -74
View File
@@ -465,7 +465,6 @@ static void URLCacheContainer_CloseIndex(URLCACHECONTAINER * pContainer)
static BOOL URLCacheContainers_AddContainer(LPCWSTR cache_prefix, LPCWSTR path, LPWSTR mutex_name)
{
URLCACHECONTAINER * pContainer = HeapAlloc(GetProcessHeap(), 0, sizeof(URLCACHECONTAINER));
int path_len = strlenW(path);
int cache_prefix_len = strlenW(cache_prefix);
if (!pContainer)
@@ -476,15 +475,13 @@ static BOOL URLCacheContainers_AddContainer(LPCWSTR cache_prefix, LPCWSTR path,
pContainer->hMapping = NULL;
pContainer->file_size = 0;
pContainer->path = HeapAlloc(GetProcessHeap(), 0, (path_len + 1) * sizeof(WCHAR));
pContainer->path = heap_strdupW(path);
if (!pContainer->path)
{
HeapFree(GetProcessHeap(), 0, pContainer);
return FALSE;
}
memcpy(pContainer->path, path, (path_len + 1) * sizeof(WCHAR));
pContainer->cache_prefix = HeapAlloc(GetProcessHeap(), 0, (cache_prefix_len + 1) * sizeof(WCHAR));
if (!pContainer->cache_prefix)
{
@@ -593,6 +590,9 @@ static DWORD URLCacheContainers_FindContainerW(LPCWSTR lpwszUrl, URLCACHECONTAIN
TRACE("searching for prefix for URL: %s\n", debugstr_w(lpwszUrl));
if(!lpwszUrl)
return ERROR_INVALID_PARAMETER;
LIST_FOR_EACH_ENTRY(pContainer, &UrlContainers, URLCACHECONTAINER, entry)
{
int prefix_len = strlenW(pContainer->cache_prefix);
@@ -609,17 +609,15 @@ static DWORD URLCacheContainers_FindContainerW(LPCWSTR lpwszUrl, URLCACHECONTAIN
static DWORD URLCacheContainers_FindContainerA(LPCSTR lpszUrl, URLCACHECONTAINER ** ppContainer)
{
LPWSTR url = NULL;
DWORD ret;
LPWSTR lpwszUrl;
int url_len = MultiByteToWideChar(CP_ACP, 0, lpszUrl, -1, NULL, 0);
if (url_len && (lpwszUrl = HeapAlloc(GetProcessHeap(), 0, url_len * sizeof(WCHAR))))
{
MultiByteToWideChar(CP_ACP, 0, lpszUrl, -1, lpwszUrl, url_len);
ret = URLCacheContainers_FindContainerW(lpwszUrl, ppContainer);
HeapFree(GetProcessHeap(), 0, lpwszUrl);
return ret;
}
return GetLastError();
if (lpszUrl && !(url = heap_strdupAtoW(lpszUrl)))
return ERROR_OUTOFMEMORY;
ret = URLCacheContainers_FindContainerW(url, ppContainer);
HeapFree(GetProcessHeap(), 0, url);
return ret;
}
static BOOL URLCacheContainers_Enum(LPCWSTR lpwszSearchPattern, DWORD dwIndex, URLCACHECONTAINER ** ppContainer)
@@ -692,6 +690,7 @@ static LPURLCACHE_HEADER URLCacheContainer_LockIndex(URLCACHECONTAINER * pContai
* of the memory mapped file */
if (pHeader->dwFileSize != pContainer->file_size)
{
UnmapViewOfFile( pHeader );
URLCacheContainer_CloseIndex(pContainer);
error = URLCacheContainer_OpenIndex(pContainer);
if (error != ERROR_SUCCESS)
@@ -1240,17 +1239,15 @@ static BOOL URLCache_FindHash(LPCURLCACHE_HEADER pHeader, LPCSTR lpszUrl, struct
static BOOL URLCache_FindHashW(LPCURLCACHE_HEADER pHeader, LPCWSTR lpszUrl, struct _HASH_ENTRY ** ppHashEntry)
{
LPSTR urlA;
int url_len;
BOOL ret;
url_len = WideCharToMultiByte(CP_ACP, 0, lpszUrl, -1, NULL, 0, NULL, NULL);
urlA = HeapAlloc(GetProcessHeap(), 0, url_len * sizeof(CHAR));
urlA = heap_strdupWtoA(lpszUrl);
if (!urlA)
{
SetLastError(ERROR_OUTOFMEMORY);
return FALSE;
}
WideCharToMultiByte(CP_ACP, 0, lpszUrl, -1, urlA, url_len, NULL, NULL);
ret = URLCache_FindHash(pHeader, urlA, ppHashEntry);
HeapFree(GetProcessHeap(), 0, urlA);
return ret;
@@ -1451,6 +1448,28 @@ static BOOL URLCache_EnumHashTableEntries(LPCURLCACHE_HEADER pHeader, const HASH
return FALSE;
}
/***********************************************************************
* FreeUrlCacheSpaceA (WININET.@)
*
*/
BOOL WINAPI FreeUrlCacheSpaceA(LPCSTR lpszCachePath, DWORD dwSize, DWORD dwFilter)
{
FIXME("stub!\n");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/***********************************************************************
* FreeUrlCacheSpaceW (WININET.@)
*
*/
BOOL WINAPI FreeUrlCacheSpaceW(LPCWSTR lpszCachePath, DWORD dwSize, DWORD dwFilter)
{
FIXME("stub!\n");
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/***********************************************************************
* GetUrlCacheEntryInfoExA (WININET.@)
*
@@ -1482,7 +1501,11 @@ BOOL WINAPI GetUrlCacheEntryInfoExA(
return FALSE;
}
if (dwFlags != 0)
{
FIXME("Undocumented flag(s): %x\n", dwFlags);
SetLastError(ERROR_FILE_NOT_FOUND);
return FALSE;
}
return GetUrlCacheEntryInfoA(lpszUrl, lpCacheEntryInfo, lpdwCacheEntryInfoBufSize);
}
@@ -1682,7 +1705,11 @@ BOOL WINAPI GetUrlCacheEntryInfoExW(
return FALSE;
}
if (dwFlags != 0)
{
FIXME("Undocumented flag(s): %x\n", dwFlags);
SetLastError(ERROR_FILE_NOT_FOUND);
return FALSE;
}
return GetUrlCacheEntryInfoW(lpszUrl, lpCacheEntryInfo, lpdwCacheEntryInfoBufSize);
}
@@ -1869,6 +1896,13 @@ BOOL WINAPI RetrieveUrlCacheEntryFileA(
}
pUrlEntry = (URL_CACHEFILE_ENTRY *)pEntry;
if (!pUrlEntry->dwOffsetLocalName)
{
URLCacheContainer_UnlockIndex(pContainer, pHeader);
SetLastError(ERROR_INVALID_DATA);
return FALSE;
}
TRACE("Found URL: %s\n", (LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl);
TRACE("Header info: %s\n", (LPBYTE)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo);
@@ -1958,6 +1992,13 @@ BOOL WINAPI RetrieveUrlCacheEntryFileW(
}
pUrlEntry = (URL_CACHEFILE_ENTRY *)pEntry;
if (!pUrlEntry->dwOffsetLocalName)
{
URLCacheContainer_UnlockIndex(pContainer, pHeader);
SetLastError(ERROR_INVALID_DATA);
return FALSE;
}
TRACE("Found URL: %s\n", (LPSTR)pUrlEntry + pUrlEntry->dwOffsetUrl);
TRACE("Header info: %s\n", (LPBYTE)pUrlEntry + pUrlEntry->dwOffsetHeaderInfo);
@@ -2142,21 +2183,16 @@ BOOL WINAPI CreateUrlCacheEntryA(
IN DWORD dwReserved
)
{
DWORD len;
WCHAR *url_name;
WCHAR *file_extension;
WCHAR file_name[MAX_PATH];
BOOL bSuccess = FALSE;
DWORD dwError = 0;
if ((len = MultiByteToWideChar(CP_ACP, 0, lpszUrlName, -1, NULL, 0)) != 0 &&
(url_name = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR))) != 0)
if (lpszUrlName && (url_name = heap_strdupAtoW(lpszUrlName)))
{
MultiByteToWideChar(CP_ACP, 0, lpszUrlName, -1, url_name, len);
if ((len = MultiByteToWideChar(CP_ACP, 0, lpszFileExtension, -1, NULL, 0)) != 0 &&
(file_extension = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR))) != 0)
if (lpszFileExtension && (file_extension = heap_strdupAtoW(lpszFileExtension)))
{
MultiByteToWideChar(CP_ACP, 0, lpszFileExtension, -1, file_extension, len);
if (CreateUrlCacheEntryW(url_name, dwExpectedFileSize, file_extension, file_name, dwReserved))
{
if (WideCharToMultiByte(CP_ACP, 0, file_name, -1, lpszFileName, MAX_PATH, NULL, NULL) < MAX_PATH)
@@ -2211,7 +2247,11 @@ BOOL WINAPI CreateUrlCacheEntryW(
BOOL bFound = FALSE;
int count;
DWORD error;
HANDLE hFile;
FILETIME ft;
static const WCHAR szWWW[] = {'w','w','w',0};
static const WCHAR fmt[] = {'%','0','8','X','%','s',0};
TRACE("(%s, 0x%08x, %s, %p, 0x%08x)\n",
debugstr_w(lpszUrlName),
@@ -2221,11 +2261,7 @@ BOOL WINAPI CreateUrlCacheEntryW(
dwReserved);
if (dwReserved)
{
ERR("dwReserved != 0\n");
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
FIXME("dwReserved 0x%08x\n", dwReserved);
lpszUrlEnd = lpszUrlName + strlenW(lpszUrlName);
@@ -2318,7 +2354,6 @@ BOOL WINAPI CreateUrlCacheEntryW(
for (i = 0; i < 255; i++)
{
static const WCHAR szFormat[] = {'[','%','u',']','%','s',0};
HANDLE hFile;
WCHAR *p;
wsprintfW(lpszFileNameNoPath + countnoextension, szFormat, i, szExtension);
@@ -2346,6 +2381,18 @@ BOOL WINAPI CreateUrlCacheEntryW(
}
}
GetSystemTimeAsFileTime(&ft);
wsprintfW(lpszFileNameNoPath + countnoextension, fmt, ft.dwLowDateTime, szExtension);
TRACE("Trying: %s\n", debugstr_w(lpszFileName));
hFile = CreateFileW(lpszFileName, GENERIC_READ, 0, NULL, CREATE_NEW, 0, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
CloseHandle(hFile);
return TRUE;
}
WARN("Could not find a unique filename\n");
return FALSE;
}
@@ -2447,25 +2494,17 @@ static BOOL CommitUrlCacheEntryInternal(
if (!(pHeader = URLCacheContainer_LockIndex(pContainer)))
return FALSE;
len = WideCharToMultiByte(CP_ACP, 0, lpszUrlName, -1, NULL, 0, NULL, NULL);
lpszUrlNameA = HeapAlloc(GetProcessHeap(), 0, len * sizeof(char));
lpszUrlNameA = heap_strdupWtoA(lpszUrlName);
if (!lpszUrlNameA)
{
error = GetLastError();
goto cleanup;
}
WideCharToMultiByte(CP_ACP, 0, lpszUrlName, -1, lpszUrlNameA, len, NULL, NULL);
if (lpszFileExtension)
if (lpszFileExtension && !(lpszFileExtensionA = heap_strdupWtoA(lpszFileExtension)))
{
len = WideCharToMultiByte(CP_ACP, 0, lpszFileExtension, -1, NULL, 0, NULL, NULL);
lpszFileExtensionA = HeapAlloc(GetProcessHeap(), 0, len * sizeof(char));
if (!lpszFileExtensionA)
{
error = GetLastError();
goto cleanup;
}
WideCharToMultiByte(CP_ACP, 0, lpszFileExtension, -1, lpszFileExtensionA, len, NULL, NULL);
error = GetLastError();
goto cleanup;
}
if (URLCache_FindHash(pHeader, lpszUrlNameA, &pHashEntry))
@@ -2622,7 +2661,6 @@ BOOL WINAPI CommitUrlCacheEntryA(
IN LPCSTR lpszOriginalUrl
)
{
DWORD len;
WCHAR *url_name = NULL;
WCHAR *local_file_name = NULL;
WCHAR *original_url = NULL;
@@ -2638,35 +2676,27 @@ BOOL WINAPI CommitUrlCacheEntryA(
debugstr_a(lpszFileExtension),
debugstr_a(lpszOriginalUrl));
len = MultiByteToWideChar(CP_ACP, 0, lpszUrlName, -1, NULL, 0);
url_name = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
url_name = heap_strdupAtoW(lpszUrlName);
if (!url_name)
goto cleanup;
MultiByteToWideChar(CP_ACP, 0, lpszUrlName, -1, url_name, len);
if (lpszLocalFileName)
{
len = MultiByteToWideChar(CP_ACP, 0, lpszLocalFileName, -1, NULL, 0);
local_file_name = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
local_file_name = heap_strdupAtoW(lpszLocalFileName);
if (!local_file_name)
goto cleanup;
MultiByteToWideChar(CP_ACP, 0, lpszLocalFileName, -1, local_file_name, len);
}
if (lpszFileExtension)
{
len = MultiByteToWideChar(CP_ACP, 0, lpszFileExtension, -1, NULL, 0);
file_extension = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
file_extension = heap_strdupAtoW(lpszFileExtension);
if (!file_extension)
goto cleanup;
MultiByteToWideChar(CP_ACP, 0, lpszFileExtension, -1, file_extension, len);
}
if (lpszOriginalUrl)
{
len = MultiByteToWideChar(CP_ACP, 0, lpszOriginalUrl, -1, NULL, 0);
original_url = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
original_url = heap_strdupAtoW(lpszOriginalUrl);
if (!original_url)
goto cleanup;
MultiByteToWideChar(CP_ACP, 0, lpszOriginalUrl, -1, original_url, len);
}
bSuccess = CommitUrlCacheEntryInternal(url_name, local_file_name, ExpireTime, LastModifiedTime,
@@ -2712,12 +2742,8 @@ BOOL WINAPI CommitUrlCacheEntryW(
debugstr_w(lpszFileExtension),
debugstr_w(lpszOriginalUrl));
if (!lpHeaderInfo ||
((len = WideCharToMultiByte(CP_ACP, 0, lpHeaderInfo, -1, NULL, 0, NULL, NULL)) != 0 &&
(header_info = HeapAlloc(GetProcessHeap(), 0, sizeof(CHAR) * len)) != 0))
if (!lpHeaderInfo || (header_info = heap_strdupWtoA(lpHeaderInfo)))
{
if (header_info)
WideCharToMultiByte(CP_ACP, 0, lpHeaderInfo, -1, header_info, len, NULL, NULL);
if (CommitUrlCacheEntryInternal(lpszUrlName, lpszLocalFileName, ExpireTime, LastModifiedTime,
CacheEntryType, (LPBYTE)header_info, len, lpszFileExtension, lpszOriginalUrl))
{
@@ -2940,19 +2966,16 @@ BOOL WINAPI DeleteUrlCacheEntryW(LPCWSTR lpszUrlName)
struct _HASH_ENTRY * pHashEntry;
CACHEFILE_ENTRY * pEntry;
LPSTR urlA;
int url_len;
DWORD error;
TRACE("(%s)\n", debugstr_w(lpszUrlName));
url_len = WideCharToMultiByte(CP_ACP, 0, lpszUrlName, -1, NULL, 0, NULL, NULL);
urlA = HeapAlloc(GetProcessHeap(), 0, url_len * sizeof(CHAR));
urlA = heap_strdupWtoA(lpszUrlName);
if (!urlA)
{
SetLastError(ERROR_OUTOFMEMORY);
return FALSE;
}
WideCharToMultiByte(CP_ACP, 0, lpszUrlName, -1, urlA, url_len, NULL, NULL);
error = URLCacheContainers_FindContainerW(lpszUrlName, &pContainer);
if (error != ERROR_SUCCESS)
@@ -3133,14 +3156,12 @@ INTERNETAPI HANDLE WINAPI FindFirstUrlCacheEntryA(LPCSTR lpszUrlSearchPattern,
pEntryHandle->dwMagic = URLCACHE_FIND_ENTRY_HANDLE_MAGIC;
if (lpszUrlSearchPattern)
{
int len = MultiByteToWideChar(CP_ACP, 0, lpszUrlSearchPattern, -1, NULL, 0);
pEntryHandle->lpszUrlSearchPattern = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
pEntryHandle->lpszUrlSearchPattern = heap_strdupAtoW(lpszUrlSearchPattern);
if (!pEntryHandle->lpszUrlSearchPattern)
{
HeapFree(GetProcessHeap(), 0, pEntryHandle);
return NULL;
}
MultiByteToWideChar(CP_ACP, 0, lpszUrlSearchPattern, -1, pEntryHandle->lpszUrlSearchPattern, len);
}
else
pEntryHandle->lpszUrlSearchPattern = NULL;
@@ -3174,14 +3195,12 @@ INTERNETAPI HANDLE WINAPI FindFirstUrlCacheEntryW(LPCWSTR lpszUrlSearchPattern,
pEntryHandle->dwMagic = URLCACHE_FIND_ENTRY_HANDLE_MAGIC;
if (lpszUrlSearchPattern)
{
int len = strlenW(lpszUrlSearchPattern);
pEntryHandle->lpszUrlSearchPattern = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
pEntryHandle->lpszUrlSearchPattern = heap_strdupW(lpszUrlSearchPattern);
if (!pEntryHandle->lpszUrlSearchPattern)
{
HeapFree(GetProcessHeap(), 0, pEntryHandle);
return NULL;
}
memcpy(pEntryHandle->lpszUrlSearchPattern, lpszUrlSearchPattern, (len + 1) * sizeof(WCHAR));
}
else
pEntryHandle->lpszUrlSearchPattern = NULL;
@@ -3623,10 +3642,26 @@ BOOL WINAPI IsUrlCacheEntryExpiredW( LPCWSTR url, DWORD dwFlags, FILETIME* pftLa
/***********************************************************************
* GetDiskInfoA (WININET.@)
*/
BOOL WINAPI GetDiskInfoA(PCSTR p0, PDWORD p1, PDWORDLONG p2, PDWORDLONG p3)
BOOL WINAPI GetDiskInfoA(PCSTR path, PDWORD cluster_size, PDWORDLONG free, PDWORDLONG total)
{
FIXME("(%p, %p, %p, %p)\n", p0, p1, p2, p3);
return FALSE;
BOOL ret;
ULARGE_INTEGER bytes_free, bytes_total;
TRACE("(%s, %p, %p, %p)\n", debugstr_a(path), cluster_size, free, total);
if (!path)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if ((ret = GetDiskFreeSpaceExA(path, NULL, &bytes_total, &bytes_free)))
{
if (cluster_size) *cluster_size = 1;
if (free) *free = bytes_free.QuadPart;
if (total) *total = bytes_total.QuadPart;
}
return ret;
}
/***********************************************************************
@@ -3637,3 +3672,12 @@ DWORD WINAPI RegisterUrlCacheNotification(LPVOID a, DWORD b, DWORD c, DWORD d, D
FIXME("(%p %x %x %x %x %x)\n", a, b, c, d, e, f);
return 0;
}
/***********************************************************************
* IncrementUrlCacheHeaderData (WININET.@)
*/
BOOL WINAPI IncrementUrlCacheHeaderData(DWORD index, LPDWORD data)
{
FIXME("(%u, %p)\n", index, data);
return FALSE;
}
+75 -13
View File
@@ -25,6 +25,10 @@
#include "config.h"
#include "wine/port.h"
#if defined(__MINGW32__) || defined (_MSC_VER)
#include <ws2tcpip.h>
#endif
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
@@ -40,6 +44,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(wininet);
#ifndef HAVE_GETADDRINFO
/* critical section to protect non-reentrant gethostbyname() */
static CRITICAL_SECTION cs_gethostbyname;
static CRITICAL_SECTION_DEBUG critsect_debug =
@@ -50,6 +56,8 @@ static CRITICAL_SECTION_DEBUG critsect_debug =
};
static CRITICAL_SECTION cs_gethostbyname = { &critsect_debug, -1, 0, 0, 0, 0 };
#endif
#define TIME_STRING_LEN 30
time_t ConvertTimeString(LPCWSTR asctime)
@@ -137,12 +145,18 @@ time_t ConvertTimeString(LPCWSTR asctime)
BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort,
struct sockaddr_in *psa)
struct sockaddr *psa, socklen_t *sa_len)
{
WCHAR *found;
char *name;
int len, sz;
#ifdef HAVE_GETADDRINFO
struct addrinfo *res, hints;
int ret;
#else
struct hostent *phe;
struct sockaddr_in *sin = (struct sockaddr_in *)psa;
#endif
TRACE("%s\n", debugstr_w(lpszServerName));
@@ -158,27 +172,75 @@ BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort,
len = strlenW(lpszServerName);
sz = WideCharToMultiByte( CP_UNIXCP, 0, lpszServerName, len, NULL, 0, NULL, NULL );
name = HeapAlloc(GetProcessHeap(), 0, sz+1);
if (!(name = HeapAlloc( GetProcessHeap(), 0, sz + 1 ))) return FALSE;
WideCharToMultiByte( CP_UNIXCP, 0, lpszServerName, len, name, sz, NULL, NULL );
name[sz] = 0;
#ifdef HAVE_GETADDRINFO
memset( &hints, 0, sizeof(struct addrinfo) );
/* Prefer IPv4 to IPv6 addresses, since some servers do not listen on
* their IPv6 addresses even though they have IPv6 addresses in the DNS.
*/
hints.ai_family = AF_INET;
ret = getaddrinfo( name, NULL, &hints, &res );
HeapFree( GetProcessHeap(), 0, name );
if (ret != 0)
{
TRACE("failed to get IPv4 address of %s (%s), retrying with IPv6\n", debugstr_w(lpszServerName), gai_strerror(ret));
hints.ai_family = AF_INET6;
ret = getaddrinfo( name, NULL, &hints, &res );
if (ret != 0)
{
TRACE("failed to get address of %s (%s)\n", debugstr_w(lpszServerName), gai_strerror(ret));
return FALSE;
}
}
if (*sa_len < res->ai_addrlen)
{
WARN("address too small\n");
freeaddrinfo( res );
return FALSE;
}
*sa_len = res->ai_addrlen;
memcpy( psa, res->ai_addr, res->ai_addrlen );
/* Copy port */
switch (res->ai_family)
{
case AF_INET:
((struct sockaddr_in *)psa)->sin_port = htons(nServerPort);
break;
case AF_INET6:
((struct sockaddr_in6 *)psa)->sin6_port = htons(nServerPort);
break;
}
freeaddrinfo( res );
#else
EnterCriticalSection( &cs_gethostbyname );
phe = gethostbyname(name);
HeapFree( GetProcessHeap(), 0, name );
if (NULL == phe)
{
TRACE("Failed to get hostname: (%s)\n", debugstr_w(lpszServerName) );
TRACE("failed to get address of %s (%d)\n", debugstr_w(lpszServerName), h_errno);
LeaveCriticalSection( &cs_gethostbyname );
return FALSE;
}
memset(psa,0,sizeof(struct sockaddr_in));
memcpy((char *)&psa->sin_addr, phe->h_addr, phe->h_length);
psa->sin_family = phe->h_addrtype;
psa->sin_port = htons(nServerPort);
if (*sa_len < sizeof(struct sockaddr_in))
{
WARN("address too small\n");
LeaveCriticalSection( &cs_gethostbyname );
return FALSE;
}
*sa_len = sizeof(struct sockaddr_in);
memset(sin,0,sizeof(struct sockaddr_in));
memcpy((char *)&sin->sin_addr, phe->h_addr, phe->h_length);
sin->sin_family = phe->h_addrtype;
sin->sin_port = htons(nServerPort);
LeaveCriticalSection( &cs_gethostbyname );
#endif
return TRUE;
}
@@ -224,7 +286,7 @@ static const char *get_callback_name(DWORD dwInternetStatus) {
return "Unknown";
}
VOID INTERNET_SendCallback(LPWININETHANDLEHEADER hdr, DWORD_PTR dwContext,
VOID INTERNET_SendCallback(object_header_t *hdr, DWORD_PTR dwContext,
DWORD dwInternetStatus, LPVOID lpvStatusInfo,
DWORD dwStatusInfoLength)
{
@@ -244,11 +306,11 @@ VOID INTERNET_SendCallback(LPWININETHANDLEHEADER hdr, DWORD_PTR dwContext,
case INTERNET_STATUS_NAME_RESOLVED:
case INTERNET_STATUS_CONNECTING_TO_SERVER:
case INTERNET_STATUS_CONNECTED_TO_SERVER:
lpvNewInfo = WININET_strdup_AtoW(lpvStatusInfo);
lpvNewInfo = heap_strdupAtoW(lpvStatusInfo);
break;
case INTERNET_STATUS_RESOLVING_NAME:
case INTERNET_STATUS_REDIRECT:
lpvNewInfo = WININET_strdupW(lpvStatusInfo);
lpvNewInfo = heap_strdupW(lpvStatusInfo);
break;
}
}else {
@@ -262,7 +324,7 @@ VOID INTERNET_SendCallback(LPWININETHANDLEHEADER hdr, DWORD_PTR dwContext,
break;
case INTERNET_STATUS_RESOLVING_NAME:
case INTERNET_STATUS_REDIRECT:
lpvNewInfo = WININET_strdup_WtoA(lpvStatusInfo);
lpvNewInfo = heap_strdupWtoA(lpvStatusInfo);
break;
}
}
@@ -294,7 +356,7 @@ static void SendAsyncCallbackProc(WORKREQUEST *workRequest)
HeapFree(GetProcessHeap(), 0, req->lpvStatusInfo);
}
VOID SendAsyncCallback(LPWININETHANDLEHEADER hdr, DWORD_PTR dwContext,
void SendAsyncCallback(object_header_t *hdr, DWORD_PTR dwContext,
DWORD dwInternetStatus, LPVOID lpvStatusInfo,
DWORD dwStatusInfoLength)
{
+1
View File
@@ -22,6 +22,7 @@
<library>secur32</library>
<library>crypt32</library>
<library>ws2_32</library>
<library>pseh</library>
<file>cookie.c</file>
<file>dialogs.c</file>
<file>ftp.c</file>
+8 -8
View File
@@ -1,5 +1,5 @@
101 stub -noname DoConnectoidsExist
102 stub -noname GetDiskInfoA
102 stdcall -noname GetDiskInfoA(str ptr ptr ptr)
103 stub -noname PerformOperationOverUrlCacheA
104 stub -noname HttpCheckDavComplianceA
105 stub -noname HttpCheckDavComplianceW
@@ -9,7 +9,7 @@
111 stub -noname ExportCookieFileW
112 stub -noname IsProfilesEnabled
116 stub -noname IsDomainlegalCookieDomainA
117 stub -noname IsDomainLegalCookieDomainW
117 stdcall -noname IsDomainLegalCookieDomainW(wstr wstr)
118 stub -noname FindP3PPolicySymbol
120 stub -noname MapResourceToPolicy
121 stub -noname GetP3PPolicy
@@ -50,8 +50,8 @@
@ stdcall FindNextUrlCacheGroup(long ptr ptr)
@ stub ForceNexusLookup
@ stub ForceNexusLookupExW
@ stub FreeUrlCacheSpaceA
@ stub FreeUrlCacheSpaceW
@ stdcall FreeUrlCacheSpaceA(str long long)
@ stdcall FreeUrlCacheSpaceW(wstr long long)
@ stdcall FtpCommandA(long long long str ptr ptr)
@ stdcall FtpCommandW(long long long wstr ptr ptr)
@ stdcall FtpCreateDirectoryA(ptr str)
@@ -109,7 +109,7 @@
@ stdcall HttpSendRequestExA(long ptr ptr long long)
@ stdcall HttpSendRequestExW(long ptr ptr long long)
@ stdcall HttpSendRequestW(ptr wstr long ptr long)
@ stub IncrementUrlCacheHeaderData
@ stdcall IncrementUrlCacheHeaderData(long ptr)
@ stub InternetAlgIdToStringA
@ stub InternetAlgIdToStringW
@ stdcall InternetAttemptConnect(long)
@@ -213,10 +213,10 @@
@ stdcall IsUrlCacheEntryExpiredW(wstr long ptr)
@ stub LoadUrlCacheContent
@ stub ParseX509EncodedCertificateForListBoxEntry
@ stub PrivacyGetZonePreferenceW # (long long ptr ptr ptr)
@ stub PrivacySetZonePreferenceW # (long long long wstr)
@ stdcall PrivacyGetZonePreferenceW(long long ptr ptr ptr)
@ stdcall PrivacySetZonePreferenceW(long long long wstr)
@ stdcall ReadUrlCacheEntryStream(ptr long ptr ptr long)
@ stub RegisterUrlCacheNotification
@ stdcall RegisterUrlCacheNotification(ptr long long long long long)
@ stdcall ResumeSuspendedDownload(long long)
@ stdcall RetrieveUrlCacheEntryFileA(str ptr ptr long)
@ stdcall RetrieveUrlCacheEntryFileW(wstr ptr ptr long)
+2
View File
@@ -16,6 +16,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT
IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
+2
View File
@@ -19,6 +19,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
/* Czech strings in CP1250 */
+2
View File
@@ -16,6 +16,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_DANISH, SUBLANG_DEFAULT
IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
+27 -2
View File
@@ -1,5 +1,6 @@
/*
* Copyright 2004 Henning Gerhardt
* Copyright 2009 André Hentschel
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -16,6 +17,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
#pragma code_page(65001)
LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL
IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
@@ -25,8 +30,8 @@ FONT 8, "MS Shell Dlg"
{
LTEXT "Geben Sie Benutzernamen und Kennwort ein:", -1, 40, 6, 150, 15
LTEXT "Proxy", -1, 40, 26, 50, 10
LTEXT "Realm", -1, 40, 46, 50, 10
LTEXT "Ben&utzername", -1, 40, 66, 50, 10
LTEXT "Bereich", -1, 40, 46, 50, 10
LTEXT "Ben&utzer", -1, 40, 66, 50, 10
LTEXT "Kenn&wort", -1, 40, 86, 50, 10
LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0
LTEXT "" IDC_REALM, 80, 46, 150, 14, 0
@@ -38,6 +43,26 @@ FONT 8, "MS Shell Dlg"
PUSHBUTTON "Abbrechen", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP
}
IDD_AUTHDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Benutzeranmeldung"
FONT 8, "MS Shell Dlg"
{
LTEXT "Geben Sie Benutzernamen und Kennwort ein:", -1, 40, 6, 150, 15
LTEXT "Server", -1, 40, 26, 50, 10
LTEXT "Bereich", -1, 40, 46, 50, 10
LTEXT "Benutzer", -1, 40, 66, 50, 10
LTEXT "Kennwort", -1, 40, 86, 50, 10
LTEXT "" IDC_SERVER, 80, 26, 150, 14, 0
LTEXT "" IDC_REALM, 80, 46, 150, 14, 0
EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP
EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD
CHECKBOX "Dieses &Kennwort speichern (unsicher)", IDC_SAVEPASSWORD,
80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
PUSHBUTTON "Abbrechen", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP
}
STRINGTABLE DISCARDABLE
{
IDS_LANCONNECTION "LAN Verbindung"
+22
View File
@@ -16,6 +16,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT
IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
@@ -38,6 +40,26 @@ FONT 8, "MS Shell Dlg"
PUSHBUTTON "Cancel", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP
}
IDD_AUTHDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Authentication Required"
FONT 8, "MS Shell Dlg"
{
LTEXT "Please enter your username and password:", -1, 40, 6, 150, 15
LTEXT "Server", -1, 40, 26, 50, 10
LTEXT "Realm", -1, 40, 46, 50, 10
LTEXT "User", -1, 40, 66, 50, 10
LTEXT "Password", -1, 40, 86, 50, 10
LTEXT "" IDC_SERVER, 80, 26, 150, 14, 0
LTEXT "" IDC_REALM, 80, 46, 150, 14, 0
EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP
EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD
CHECKBOX "&Save this password (insecure)", IDC_SAVEPASSWORD,
80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
PUSHBUTTON "Cancel", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP
}
STRINGTABLE DISCARDABLE
{
IDS_LANCONNECTION "LAN Connection"
+2
View File
@@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_ESPERANTO, SUBLANG_DEFAULT
IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
+2
View File
@@ -16,6 +16,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL
IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
+2
View File
@@ -16,6 +16,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_FINNISH, SUBLANG_DEFAULT
IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
+43 -17
View File
@@ -3,8 +3,9 @@
* French language support
*
* Copyright 2003 Mike McCormack for CodeWeavers
* Copyright 2003 Vincent Béron
* Copyright 2003 Vincent Béron
* Copyright 2005 Jonathan Ernst
* Copyright 2009 Frédéric Delanoy
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -21,29 +22,54 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
/* UTF-8 */
#pragma code_page(65001)
LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 218, 150
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Entrez le mot de passe réseau"
CAPTION "Entrez le mot de passe réseau"
FONT 8, "MS Shell Dlg"
{
LTEXT "Entrez votre nom d'utilisateur et votre mot de passe :", -1, 40, 6, 150, 15
LTEXT "Mandataire", -1, 40, 26, 50, 10
LTEXT "Domaine", -1, 40, 46, 50, 10
LTEXT "Utilisateur", -1, 40, 66, 50, 10
LTEXT "Mot de passe", -1, 40, 86, 50, 10
LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0
LTEXT "" IDC_REALM, 80, 46, 150, 14, 0
EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP
EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD
CHECKBOX "&Enregistrer ce mot de passe (risqué)", IDC_SAVEPASSWORD,
80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
PUSHBUTTON "Annuler", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP
LTEXT "Entrez votre nom d'utilisateur et votre mot de passe :", -1, 10, 8, 173, 12
LTEXT "Serveur mandataire", -1, 10, 28, 50, 17
LTEXT "Domaine", -1, 10, 50, 50, 10
LTEXT "Utilisateur", -1, 10, 71, 50, 10
LTEXT "Mot de passe", -1, 10, 90, 50, 10
LTEXT "" IDC_PROXY, 58, 28, 150, 14, 0
LTEXT "" IDC_REALM, 58, 48, 150, 14, 0
EDITTEXT IDC_USERNAME, 58, 68, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP
EDITTEXT IDC_PASSWORD, 58, 88, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD
CHECKBOX "&Enregistrer ce mot de passe (risqué)", IDC_SAVEPASSWORD,
58, 108, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
PUSHBUTTON "OK", IDOK, 87, 128, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
PUSHBUTTON "Annuler", IDCANCEL, 147, 128, 56, 14, WS_GROUP | WS_TABSTOP
}
IDD_AUTHDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 218, 150
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Authentification requise"
FONT 8, "MS Shell Dlg"
{
LTEXT "Entrez votre nom d'utilisateur et votre mot de passe :", -1, 10, 8, 173, 12
LTEXT "Serveur", -1, 10, 28, 50, 17
LTEXT "Domaine", -1, 10, 50, 50, 10
LTEXT "Utilisateur", -1, 10, 71, 50, 10
LTEXT "Mot de passe", -1, 10, 90, 50, 10
LTEXT "" IDC_SERVER, 58, 28, 150, 14, 0
LTEXT "" IDC_REALM, 58, 48, 150, 14, 0
EDITTEXT IDC_USERNAME, 58, 68, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP
EDITTEXT IDC_PASSWORD, 58, 88, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD
CHECKBOX "&Enregistrer ce mot de passe (risqué)", IDC_SAVEPASSWORD,
58, 108, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
PUSHBUTTON "OK", IDOK, 87, 128, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
PUSHBUTTON "Annuler", IDCANCEL, 147, 128, 56, 14, WS_GROUP | WS_TABSTOP
}
STRINGTABLE DISCARDABLE
{
IDS_LANCONNECTION "Connexion LAN"
IDS_LANCONNECTION "Connexion réseau local (LAN)"
}
+2
View File
@@ -16,6 +16,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT
IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
+22
View File
@@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL
IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
@@ -40,6 +42,26 @@ FONT 8, "MS Shell Dlg"
PUSHBUTTON "Annulla", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP
}
IDD_AUTHDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Autenticazione richiesta"
FONT 8, "MS Shell Dlg"
{
LTEXT "Inserire il nome utente e la password:", -1, 40, 6, 150, 15
LTEXT "Server", -1, 40, 26, 50, 10
LTEXT "Realm", -1, 40, 46, 50, 10
LTEXT "Utente", -1, 40, 66, 50, 10
LTEXT "Password", -1, 40, 86, 50, 10
LTEXT "" IDC_SERVER, 80, 26, 150, 14, 0
LTEXT "" IDC_REALM, 80, 46, 150, 14, 0
EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP
EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD
CHECKBOX "&Memorizza la password (RISCHIOSO)", IDC_SAVEPASSWORD,
80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
PUSHBUTTON "Annulla", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP
}
STRINGTABLE DISCARDABLE
{
IDS_LANCONNECTION "Connessione LAN"
+2 -2
View File
@@ -16,6 +16,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
/* UTF-8 */
#pragma code_page(65001)
@@ -45,5 +47,3 @@ STRINGTABLE DISCARDABLE
{
IDS_LANCONNECTION "LAN 接続"
}
#pragma code_page(default)
+2
View File
@@ -16,6 +16,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT
IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
+69
View File
@@ -0,0 +1,69 @@
/*
* Copyright 2009 Aurimas Fišeras <[email protected]>
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
/* UTF-8 */
#pragma code_page(65001)
LANGUAGE LANG_LITHUANIAN, SUBLANG_NEUTRAL
IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Įveskite tinklo slaptažodį"
FONT 8, "MS Shell Dlg"
{
LTEXT "Įveskite savo naudotojo vardą ir slaptažodį:", -1, 40, 6, 150, 15
LTEXT "Įgaliot. serv.", -1, 40, 26, 50, 10
LTEXT "Sritis", -1, 40, 46, 50, 10
LTEXT "Naudotojas", -1, 40, 66, 50, 10
LTEXT "Slaptažodis", -1, 40, 86, 50, 10
LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0
LTEXT "" IDC_REALM, 80, 46, 150, 14, 0
EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP
EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD
CHECKBOX "Į&rašyti šį slaptažodį (nesaugu)", IDC_SAVEPASSWORD,
80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
PUSHBUTTON "Gerai", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
PUSHBUTTON "Atsisakyti", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP
}
IDD_AUTHDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Reikalingas tapatumo nustatymas"
FONT 8, "MS Shell Dlg"
{
LTEXT "Įveskite savo naudotojo vardą ir slaptažodį:", -1, 40, 6, 150, 15
LTEXT "Serveris", -1, 40, 26, 50, 10
LTEXT "Sritis", -1, 40, 46, 50, 10
LTEXT "Naudotojas", -1, 40, 66, 50, 10
LTEXT "Slaptažodis", -1, 40, 86, 50, 10
LTEXT "" IDC_SERVER, 80, 26, 150, 14, 0
LTEXT "" IDC_REALM, 80, 46, 150, 14, 0
EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP
EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD
CHECKBOX "Į&rašyti šį slaptažodį (nesaugu)", IDC_SAVEPASSWORD,
80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
PUSHBUTTON "Gerai", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
PUSHBUTTON "Atsisakyti", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP
}
STRINGTABLE DISCARDABLE
{
IDS_LANCONNECTION "Vietinio tinklo ryšys"
}
+22
View File
@@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL
IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
@@ -40,6 +42,26 @@ FONT 8, "MS Shell Dlg"
PUSHBUTTON "Annuleren", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP
}
IDD_AUTHDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Authenticatie vereist"
FONT 8, "MS Shell Dlg"
{
LTEXT "Voer uw gebruikersnaam en wachtwoord in:", -1, 40, 6, 150, 15
LTEXT "Server", -1, 40, 26, 50, 10
LTEXT "Realm", -1, 40, 46, 50, 10
LTEXT "Gebruikersnaam", -1, 40, 66, 50, 10
LTEXT "Wachtwoord", -1, 40, 86, 50, 10
LTEXT "" IDC_SERVER, 80, 26, 150, 14, 0
LTEXT "" IDC_REALM, 80, 46, 150, 14, 0
EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP
EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD
CHECKBOX "&Wachtwoord opslaan (onveilig)", IDC_SAVEPASSWORD,
80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
PUSHBUTTON "Annuleren", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP
}
STRINGTABLE DISCARDABLE
{
IDS_LANCONNECTION "LAN Verbinding"
+26 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright 2005 Alexander N. Sørnes <[email protected]>
* Copyright 2005-2009 Alexander N. Sørnes <[email protected]>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -16,6 +16,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
#pragma code_page(65001)
LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL
IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
@@ -25,7 +29,7 @@ FONT 8, "MS Shell Dlg"
{
LTEXT "Skriv inn brukernavnet og passordet ditt:", -1, 40, 6, 150, 15
LTEXT "Mellomtjener", -1, 40, 26, 50, 10
LTEXT "Område", -1, 40, 46, 50, 10
LTEXT "Område", -1, 40, 46, 50, 10
LTEXT "Bruker", -1, 40, 66, 50, 10
LTEXT "Passord", -1, 40, 86, 50, 10
LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0
@@ -38,6 +42,26 @@ FONT 8, "MS Shell Dlg"
PUSHBUTTON "Avbryt", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP
}
IDD_AUTHDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Pålogging"
FONT 8, "MS Shell Dlg"
{
LTEXT "Oppgi brukernavn og passord:", -1, 40, 6, 150, 15
LTEXT "Tjener", -1, 40, 26, 50, 10
LTEXT "Område", -1, 40, 46, 50, 10
LTEXT "Bruker", -1, 40, 66, 50, 10
LTEXT "Passord", -1, 40, 86, 50, 10
LTEXT "" IDC_SERVER, 80, 26, 150, 14, 0
LTEXT "" IDC_REALM, 80, 46, 150, 14, 0
EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP
EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD
CHECKBOX "Lagre pa&ssordet (sikkerhetsrisiko)", IDC_SAVEPASSWORD,
80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
PUSHBUTTON "Avbryt", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP
}
STRINGTABLE DISCARDABLE
{
IDS_LANCONNECTION "Lokal nettverksforbindelse"
+2
View File
@@ -17,6 +17,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_POLISH, SUBLANG_DEFAULT
IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
+29 -5
View File
@@ -1,6 +1,7 @@
/*
* Copyright 2003 Marcelo Duarte
* Copyright 2006-2007 Américo José Melo
* Copyright 2006-2007 Américo José Melo
* Copyright 2009 Ricardo Filipe
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -17,6 +18,10 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
#pragma code_page(65001)
LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN
IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
@@ -24,10 +29,10 @@ STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Entrar Senha da Rede"
FONT 8, "MS Shell Dlg"
{
LTEXT "Por favor, entre com o nome de usuário e a senha:", -1, 40, 6, 150, 15
LTEXT "Por favor, entre com o nome de usuário e a senha:", -1, 40, 6, 150, 15
LTEXT "Proxy", -1, 40, 26, 50, 10
LTEXT "Realm", -1, 40, 46, 50, 10
LTEXT "Usuário", -1, 40, 66, 50, 10
LTEXT "Usuário", -1, 40, 66, 50, 10
LTEXT "Senha", -1, 40, 86, 50, 10
LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0
LTEXT "" IDC_REALM, 80, 46, 150, 14, 0
@@ -61,17 +66,36 @@ FONT 8, "MS Shell Dlg"
PUSHBUTTON "Cancelar", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP
}
IDD_AUTHDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Autenticação necessária"
FONT 8, "MS Shell Dlg"
{
LTEXT "Por favor insira o seu nome de utilizador e palavra-passe:", -1, 40, 6, 150, 15
LTEXT "Servidor", -1, 40, 26, 50, 10
LTEXT "Reino", -1, 40, 46, 50, 10
LTEXT "Utilizador", -1, 40, 66, 50, 10
LTEXT "Palavra-passe", -1, 40, 86, 50, 10
LTEXT "" IDC_SERVER, 80, 26, 150, 14, 0
LTEXT "" IDC_REALM, 80, 46, 150, 14, 0
EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP
EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD
CHECKBOX "&Guardar esta palavra-passe (inseguro)", IDC_SAVEPASSWORD,
80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
PUSHBUTTON "Cancelar", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP
}
LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN
STRINGTABLE DISCARDABLE
{
IDS_LANCONNECTION "Conexão LAN"
IDS_LANCONNECTION "Conexão LAN"
}
LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE
STRINGTABLE DISCARDABLE
{
IDS_LANCONNECTION "Ligação LAN"
IDS_LANCONNECTION "Ligação LAN"
}
+23 -3
View File
@@ -17,6 +17,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL
#pragma code_page(65001)
@@ -28,7 +30,7 @@ FONT 8, "MS Shell Dlg"
{
LTEXT "Introduceți numele de utilizator și parola:", -1, 40, 6, 150, 15
LTEXT "Proxy", -1, 40, 26, 50, 10
LTEXT "Realm", -1, 40, 46, 50, 10
LTEXT "Domeniu", -1, 40, 46, 50, 10
LTEXT "Utilizator", -1, 40, 66, 50, 10
LTEXT "Parolă", -1, 40, 86, 50, 10
LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0
@@ -41,9 +43,27 @@ FONT 8, "MS Shell Dlg"
PUSHBUTTON "Renunță", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP
}
IDD_AUTHDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Autentificare necesară"
FONT 8, "MS Shell Dlg"
{
LTEXT "Introduceți numele de utilizator și parola:", -1, 40, 6, 150, 15
LTEXT "Server", -1, 40, 26, 50, 10
LTEXT "Domeniu", -1, 40, 46, 50, 10
LTEXT "Utilizator", -1, 40, 66, 50, 10
LTEXT "Parolă", -1, 40, 86, 50, 10
LTEXT "" IDC_SERVER, 80, 26, 150, 14, 0
LTEXT "" IDC_REALM, 80, 46, 150, 14, 0
EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP
EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD
CHECKBOX "&Salvează această parolă (nesigur)", IDC_SAVEPASSWORD,
80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
PUSHBUTTON "Renunță", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP
}
STRINGTABLE DISCARDABLE
{
IDS_LANCONNECTION "Conexiune LAN"
}
#pragma code_page(default)
+34 -9
View File
@@ -18,29 +18,54 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
/* UTF-8 */
#pragma code_page(65001)
LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Ввод сетевого пароля"
CAPTION "Ввод сетевого пароля"
FONT 8, "MS Shell Dlg"
{
LTEXT "Введите имя пользователя и пароль:", -1, 40, 6, 150, 15
LTEXT "Прокси", -1, 40, 26, 50, 10
LTEXT "Домен", -1, 40, 46, 50, 10
LTEXT "Пользователь", -1, 40, 66, 50, 10
LTEXT "Пароль", -1, 40, 86, 50, 10
LTEXT "Введите имя пользователя и пароль:", -1, 40, 6, 150, 15
LTEXT "Прокси", -1, 40, 26, 50, 10
LTEXT "Домен", -1, 40, 46, 50, 10
LTEXT "Пользователь", -1, 40, 66, 50, 10
LTEXT "Пароль", -1, 40, 86, 50, 10
LTEXT "" IDC_PROXY, 80, 26, 150, 14, 0
LTEXT "" IDC_REALM, 80, 46, 150, 14, 0
EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP
EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD
CHECKBOX "&Сохранить этот пароль (небезопасно)", IDC_SAVEPASSWORD,
CHECKBOX "&Сохранить этот пароль (небезопасно)", IDC_SAVEPASSWORD,
80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
PUSHBUTTON "Отмена", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP
PUSHBUTTON "Отмена", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP
}
IDD_AUTHDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Требуется идентификация"
FONT 8, "MS Shell Dlg"
{
LTEXT "Введите имя пользователя и пароль:", -1, 40, 6, 150, 15
LTEXT "Сервер", -1, 40, 26, 50, 10
LTEXT "Домен", -1, 40, 46, 50, 10
LTEXT "Пользователь", -1, 40, 66, 50, 10
LTEXT "Пароль", -1, 40, 86, 50, 10
LTEXT "" IDC_SERVER, 80, 26, 150, 14, 0
LTEXT "" IDC_REALM, 80, 46, 150, 14, 0
EDITTEXT IDC_USERNAME, 80, 66, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP
EDITTEXT IDC_PASSWORD, 80, 86, 150, 14, ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | ES_PASSWORD
CHECKBOX "&Сохранить этот пароль (небезопасно)", IDC_SAVEPASSWORD,
80, 106, 150, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
PUSHBUTTON "OK", IDOK, 98, 126, 56, 14, WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON
PUSHBUTTON "Отмена", IDCANCEL, 158, 126, 56, 14, WS_GROUP | WS_TABSTOP
}
STRINGTABLE DISCARDABLE
{
IDS_LANCONNECTION "Сетевое подключение"
IDS_LANCONNECTION "Сетевое подключение"
}
+2 -2
View File
@@ -16,6 +16,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
#pragma code_page(65001)
LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT
@@ -44,5 +46,3 @@ STRINGTABLE DISCARDABLE
{
IDS_LANCONNECTION "LAN povezava"
}
#pragma code_page(default)
+2
View File
@@ -16,6 +16,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL
IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
+2
View File
@@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT
IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154
+2
View File
@@ -18,6 +18,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "resource.h"
LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT
IDD_PROXYDLG DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 250, 154

Some files were not shown because too many files have changed in this diff Show More