diff --git a/base/applications/cmdutils/comp/comp.c b/base/applications/cmdutils/comp/comp.c index 0bec824bf9f..15a0db4ffdf 100644 --- a/base/applications/cmdutils/comp/comp.c +++ b/base/applications/cmdutils/comp/comp.c @@ -58,7 +58,6 @@ VOID Usage(VOID) int _tmain (int argc, TCHAR *argv[]) { INT i; - INT LineLen1, LineLen2; FILE *fp1, *fp2; // file pointers PTCHAR Line1 = (TCHAR *)malloc(STRBUF * sizeof(TCHAR)); PTCHAR Line2 = (TCHAR *)malloc(STRBUF * sizeof(TCHAR)); @@ -156,8 +155,8 @@ int _tmain (int argc, TCHAR *argv[]) _tprintf(_T("Comparing %s and %s...\n"), File1, File2); - while ((LineLen1 = GetLine(Line1, fp1) != 0) && - (LineLen2 = GetLine(Line2, fp2) != 0)) + while ((GetLine(Line1, fp1) != 0) && + (GetLine(Line2, fp2) != 0)) { // LineCount++; while ((*Line1 != '\0') && (*Line2 != '\0')) diff --git a/base/applications/cmdutils/find/find.c b/base/applications/cmdutils/find/find.c index 55118d3279d..7121f5f7d61 100644 --- a/base/applications/cmdutils/find/find.c +++ b/base/applications/cmdutils/find/find.c @@ -125,11 +125,12 @@ find_str (char *sz, FILE *p, int invert_search, void usage (void) { - TCHAR lpUsage[4096]; + WCHAR wszUsage[4096]; + char oemUsage[4096]; - LoadString( GetModuleHandle(NULL), IDS_USAGE, (LPTSTR)lpUsage, 4096); - CharToOem(lpUsage, lpUsage); - printf( lpUsage ); + LoadStringW (GetModuleHandleW (NULL), IDS_USAGE, wszUsage, sizeof(wszUsage) / sizeof(wszUsage[0])); + CharToOemW (wszUsage, oemUsage); + fputs (oemUsage, stdout); } @@ -139,7 +140,8 @@ main (int argc, char **argv) { char *opt, *needle = NULL; int ret = 0; - TCHAR lpMessage[4096]; + WCHAR wszMessage[4096]; + char oemMessage[4096]; int invert_search = 0; /* flag to invert the search */ int count_lines = 0; /* flag to whether/not count lines */ @@ -216,9 +218,9 @@ main (int argc, char **argv) { /* We were not able to find a file. Display a message and set the exit status. */ - LoadString( GetModuleHandle(NULL), IDS_NO_SUCH_FILE, (LPTSTR)lpMessage, 4096); - CharToOem(lpMessage, lpMessage); - fprintf (stderr, lpMessage, *argv);// + LoadStringW (GetModuleHandleW (NULL), IDS_NO_SUCH_FILE, wszMessage, sizeof(wszMessage) / sizeof(wszMessage[0])); + CharToOemW (wszMessage, oemMessage); + fprintf (stderr, oemMessage, *argv); } else { @@ -235,9 +237,9 @@ main (int argc, char **argv) } else { - LoadString(GetModuleHandle(NULL), IDS_CANNOT_OPEN, (LPTSTR)lpMessage, 4096); - CharToOem(lpMessage, lpMessage); - fprintf (stderr, lpMessage, + LoadStringW (GetModuleHandleW (NULL), IDS_CANNOT_OPEN, wszMessage, sizeof(wszMessage) / sizeof(wszMessage[0])); + CharToOemW (wszMessage, oemMessage); + fprintf (stderr, oemMessage, finddata.name); } } diff --git a/base/applications/mplay32/mplay32.c b/base/applications/mplay32/mplay32.c index f4220f2feb3..2dbec3ceace 100644 --- a/base/applications/mplay32/mplay32.c +++ b/base/applications/mplay32/mplay32.c @@ -112,7 +112,7 @@ ShowMCIError(HWND hwnd, DWORD dwError) LoadString(hInstance, IDS_DEFAULTMCIERRMSG, szErrorMessage, sizeof(szErrorMessage) / sizeof(TCHAR)); } - _stprintf(szTempMessage, _T("MMSYS%u: %s"), dwError, szErrorMessage); + _stprintf(szTempMessage, _T("MMSYS%lu: %s"), dwError, szErrorMessage); MessageBox(hwnd, szTempMessage, szAppTitle, MB_OK | MB_ICONEXCLAMATION); } diff --git a/base/applications/mscutils/devmgmt/mainwnd.c b/base/applications/mscutils/devmgmt/mainwnd.c index e08341a9a52..2cc2c2d5f71 100644 --- a/base/applications/mscutils/devmgmt/mainwnd.c +++ b/base/applications/mscutils/devmgmt/mainwnd.c @@ -268,7 +268,7 @@ UpdateViewMenu(PMAIN_WND_INFO Info) CheckMenuItem(hMenu, IDC_SHOWHIDDEN, - MF_BYCOMMAND | (Info->bShowHidden) ? MF_CHECKED : MF_UNCHECKED); + MF_BYCOMMAND | (Info->bShowHidden ? MF_CHECKED : MF_UNCHECKED)); } @@ -304,7 +304,7 @@ InitMainWnd(PMAIN_WND_INFO Info) 0); SetMenuDefaultItem(Info->hShortcutMenu, IDC_PROP, FALSE); - /* create seperate thread to emum devices */ + /* create separate thread to emum devices */ DevEnumThread = CreateThread(NULL, 0, DeviceEnumThread, @@ -418,6 +418,23 @@ OnNotify(PMAIN_WND_INFO Info, } break; + case NM_RETURN: + { + HTREEITEM hSelected = TreeView_GetSelection(Info->hTreeView); + if (Info->Display == DevicesByType) + { + OpenPropSheet(Info->hTreeView, hSelected); + } + else if (Info->Display == DevicesByConnection) + { + if (hSelected != TreeView_GetRoot(Info->hTreeView)) + { + OpenPropSheet(Info->hTreeView, hSelected); + } + } + } + break; + case NM_DBLCLK: { HTREEITEM hSelected = TreeView_GetSelection(Info->hTreeView); diff --git a/base/applications/mscutils/eventvwr/eventvwr.c b/base/applications/mscutils/eventvwr/eventvwr.c index 4bf6442a737..8d0a019d950 100644 --- a/base/applications/mscutils/eventvwr/eventvwr.c +++ b/base/applications/mscutils/eventvwr/eventvwr.c @@ -261,18 +261,11 @@ GetEventCategory(IN LPCWSTR KeyName, EVENT_MESSAGE_FILE_BUFFER, NULL) != 0) { - if (lpMsgBuf) - { - /* Trim the string */ - TrimNulls((LPWSTR)lpMsgBuf); + /* Trim the string */ + TrimNulls(lpMsgBuf); - /* Copy the category name */ - wcscpy(CategoryName, (LPCWSTR)lpMsgBuf); - } - else - { - wcscpy(CategoryName, (LPCWSTR)lpMsgBuf); - } + /* Copy the category name */ + wcscpy(CategoryName, lpMsgBuf); } else { @@ -1118,14 +1111,14 @@ DisplayEvent(HWND hDlg) if (iIndex != -1) { - ListView_GetItemText(hwndListView, iIndex, 0, szEventType, sizeof(szEventType) * sizeof(WCHAR)); - ListView_GetItemText(hwndListView, iIndex, 1, szDate, sizeof(szDate) * sizeof(WCHAR)); - ListView_GetItemText(hwndListView, iIndex, 2, szTime, sizeof(szTime) * sizeof(WCHAR)); - ListView_GetItemText(hwndListView, iIndex, 3, szSource, sizeof(szSource) * sizeof(WCHAR)); - ListView_GetItemText(hwndListView, iIndex, 4, szCategory, sizeof(szCategory) * sizeof(WCHAR)); - ListView_GetItemText(hwndListView, iIndex, 5, szEventID, sizeof(szEventID) * sizeof(WCHAR)); - ListView_GetItemText(hwndListView, iIndex, 6, szUser, sizeof(szUser) * sizeof(WCHAR)); - ListView_GetItemText(hwndListView, iIndex, 7, szComputer, sizeof(szComputer) * sizeof(WCHAR)); + ListView_GetItemText(hwndListView, iIndex, 0, szEventType, sizeof(szEventType) / sizeof(WCHAR)); + ListView_GetItemText(hwndListView, iIndex, 1, szDate, sizeof(szDate) / sizeof(WCHAR)); + ListView_GetItemText(hwndListView, iIndex, 2, szTime, sizeof(szTime) / sizeof(WCHAR)); + ListView_GetItemText(hwndListView, iIndex, 3, szSource, sizeof(szSource) / sizeof(WCHAR)); + ListView_GetItemText(hwndListView, iIndex, 4, szCategory, sizeof(szCategory) / sizeof(WCHAR)); + ListView_GetItemText(hwndListView, iIndex, 5, szEventID, sizeof(szEventID) / sizeof(WCHAR)); + ListView_GetItemText(hwndListView, iIndex, 6, szUser, sizeof(szUser) / sizeof(WCHAR)); + ListView_GetItemText(hwndListView, iIndex, 7, szComputer, sizeof(szComputer) / sizeof(WCHAR)); bEventData = !(pevlr->DataLength == 0); diff --git a/base/applications/mspaint/registry.c b/base/applications/mspaint/registry.c index 06bc8403b56..fca10a04bfa 100644 --- a/base/applications/mspaint/registry.c +++ b/base/applications/mspaint/registry.c @@ -31,8 +31,8 @@ SetWallpaper(TCHAR * FileName, DWORD dwStyle, DWORD dwTile) //FIXME: Has to be c RegSetValueEx(hDesktop, _T("Wallpaper"), 0, REG_SZ, (LPBYTE) FileName, _tcslen(FileName) * sizeof(TCHAR)); - _stprintf(szStyle, _T("%i"), dwStyle); - _stprintf(szTile, _T("%i"), dwTile); + _stprintf(szStyle, _T("%lu"), dwStyle); + _stprintf(szTile, _T("%lu"), dwTile); RegSetValueEx(hDesktop, _T("WallpaperStyle"), 0, REG_SZ, (LPBYTE) szStyle, _tcslen(szStyle) * sizeof(TCHAR)); diff --git a/base/applications/mspaint/winproc.c b/base/applications/mspaint/winproc.c index 2826df0152f..76af666a0ad 100644 --- a/base/applications/mspaint/winproc.c +++ b/base/applications/mspaint/winproc.c @@ -595,7 +595,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if (!drawing) { TCHAR coordStr[100]; - _stprintf(coordStr, _T("%d, %d"), xNow, yNow); + _stprintf(coordStr, _T("%ld, %ld"), xNow, yNow); SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) coordStr); } } @@ -634,7 +634,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case TOOL_SHAPE: { TCHAR coordStr[100]; - _stprintf(coordStr, _T("%d, %d"), xNow, yNow); + _stprintf(coordStr, _T("%ld, %ld"), xNow, yNow); SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) coordStr); break; } @@ -648,7 +648,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) TCHAR sizeStr[100]; if ((activeTool >= TOOL_LINE) && (GetAsyncKeyState(VK_SHIFT) < 0)) yRel = xRel; - _stprintf(sizeStr, _T("%d x %d"), xRel, yRel); + _stprintf(sizeStr, _T("%ld x %ld"), xRel, yRel); SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) sizeStr); } } @@ -661,7 +661,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) TCHAR sizeStr[100]; if ((activeTool >= TOOL_LINE) && (GetAsyncKeyState(VK_SHIFT) < 0)) yRel = xRel; - _stprintf(sizeStr, _T("%d x %d"), xRel, yRel); + _stprintf(sizeStr, _T("%ld x %ld"), xRel, yRel); SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) sizeStr); } } diff --git a/base/applications/network/dwnl/dwnl.c b/base/applications/network/dwnl/dwnl.c index 8d30828beeb..345c0e9b61e 100644 --- a/base/applications/network/dwnl/dwnl.c +++ b/base/applications/network/dwnl/dwnl.c @@ -225,7 +225,7 @@ CBindStatusCallback_OnProgress(IBindStatusCallback *iface, if (This->szMimeType[0] != _T('\0')) _tprintf(_T("Length: %I64u [%s]\n"), This->Size, This->szMimeType); else - _tprintf(_T("Length: %ull\n"), This->Size); + _tprintf(_T("Length: %I64u\n"), This->Size); } _tprintf(_T("\n")); diff --git a/base/applications/network/ftp/cmds.c b/base/applications/network/ftp/cmds.c index dd752ec7ab9..5b4898290ad 100644 --- a/base/applications/network/ftp/cmds.c +++ b/base/applications/network/ftp/cmds.c @@ -1303,13 +1303,13 @@ void shell(int argc, const char *argv[]) if (argc > 1) { - strncat(CmdLine, " /C", MAX_PATH); + strncat(CmdLine, " /C", MAX_PATH - strlen(CmdLine) - 1); } for (i=1; iszUrlDownload); } while (dwBytesRead); - + CloseHandle(hOut); - if (dl) IBindStatusCallback_Release(dl); + hOut = INVALID_HANDLE_VALUE; + if (bCancelled) goto end; ShowWindow(Dlg, SW_HIDE); @@ -295,10 +297,12 @@ ThreadFunc(LPVOID Context) ShellExecuteW( NULL, L"open", path, NULL, NULL, SW_SHOWNORMAL ); } end: - CloseHandle(hOut); + if (hOut != INVALID_HANDLE_VALUE) CloseHandle(hOut); InternetCloseHandle(hFile); InternetCloseHandle(hOpen); + if (dl) IBindStatusCallback_Release(dl); + if (bTempfile) { if (bCancelled || (SettingsInfo.bDelInstaller && !bCab)) diff --git a/base/applications/regedit/regproc.c b/base/applications/regedit/regproc.c index 138c2bf0e4a..8d09bb349b7 100644 --- a/base/applications/regedit/regproc.c +++ b/base/applications/regedit/regproc.c @@ -893,7 +893,7 @@ static void REGPROC_print_error(void) status = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, error_code, 0, (LPSTR) &lpMsgBuf, 0, NULL); if (!status) { - fprintf(stderr,"%S: Cannot display message for error %ld, status %ld\n", + fprintf(stderr,"%S: Cannot display message for error %lu, status %lu\n", getAppName(), error_code, GetLastError()); exit(1); } diff --git a/base/applications/winhlp32/hlpfile.c b/base/applications/winhlp32/hlpfile.c index 096904f32ef..50710c0a30e 100644 --- a/base/applications/winhlp32/hlpfile.c +++ b/base/applications/winhlp32/hlpfile.c @@ -1049,7 +1049,7 @@ static BOOL HLPFILE_RtfAddMetaFile(struct RtfData* rd, HLPFILE* file, const ptr = beg + 2; /* for type and pack */ mm = fetch_ushort(&ptr); /* mapping mode */ - sprintf(tmp, "{\\pict\\wmetafile%d\\picw%d\\pich%d", + sprintf(tmp, "{\\pict\\wmetafile%u\\picw%u\\pich%u", mm, GET_USHORT(ptr, 0), GET_USHORT(ptr, 2)); if (!HLPFILE_RtfAddControl(rd, tmp)) return FALSE; ptr += 4; @@ -1465,11 +1465,10 @@ static BOOL HLPFILE_BrowseParagraph(HLPFILE_PAGE* page, struct RtfData* rd, } /* FIXME: missing at least colors, also bold attribute looses information */ - sprintf(tmp, "\\f%d\\cf%d\\fs%d%s%s%s%s", + sprintf(tmp, "\\f%u\\cf%u\\fs%u%s%s%s%s", font, font + 2, fs, page->file->fonts[font].LogFont.lfWeight > 400 ? "\\b" : "\\b0", - page->file->fonts[font].LogFont.lfItalic ? "\\i" : "\\i0", - page->file->fonts[font].LogFont.lfUnderline ? "\\ul" : "\\ul0", + page->file->fonts[font].LogFont.lfItalic ? "\\i" : "\\i0", page->file->fonts[font].LogFont.lfUnderline ? "\\ul" : "\\ul0", page->file->fonts[font].LogFont.lfStrikeOut ? "\\strike" : "\\strike0"); if (!HLPFILE_RtfAddControl(rd, tmp)) goto done; } diff --git a/base/applications/winver/CMakeLists.txt b/base/applications/winver/CMakeLists.txt index 09756ca6f7a..af0286db2c0 100644 --- a/base/applications/winver/CMakeLists.txt +++ b/base/applications/winver/CMakeLists.txt @@ -1,6 +1,5 @@ - -add_executable(winver winver.c) +add_executable(winver winver.c winver.rc) set_module_type(winver win32gui UNICODE) add_importlibs(winver shell32 msvcrt kernel32) add_cd_file(TARGET winver DESTINATION reactos/system32 FOR all) diff --git a/base/applications/winver/winver.c b/base/applications/winver/winver.c index b969d14e560..b56230f9b2c 100644 --- a/base/applications/winver/winver.c +++ b/base/applications/winver/winver.c @@ -1,3 +1,9 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Version Program + * FILE: winver.c + */ + #include #include #include @@ -5,11 +11,10 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) { - static const WCHAR szROS[] = { 'R','e','a','c','t','O','S',0 }; - UNREFERENCED_PARAMETER(lpCmdLine); - UNREFERENCED_PARAMETER(nCmdShow); - UNREFERENCED_PARAMETER(hPrevInstance); - UNREFERENCED_PARAMETER(hInstance); - ShellAboutW(0, szROS, 0, 0); - return 1; + UNREFERENCED_PARAMETER(hInstance); + UNREFERENCED_PARAMETER(hPrevInstance); + UNREFERENCED_PARAMETER(lpCmdLine); + UNREFERENCED_PARAMETER(nCmdShow); + + return ShellAboutW(NULL, L"ReactOS", NULL, NULL); } diff --git a/base/applications/winver/winver.rc b/base/applications/winver/winver.rc new file mode 100644 index 00000000000..bc853f8a4b0 --- /dev/null +++ b/base/applications/winver/winver.rc @@ -0,0 +1,5 @@ + +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Version Program" +#define REACTOS_STR_INTERNAL_NAME "winver" +#define REACTOS_STR_ORIGINAL_FILENAME "winver.exe" +#include diff --git a/base/services/umpnpmgr/umpnpmgr.c b/base/services/umpnpmgr/umpnpmgr.c index c821105c335..f683e9f5b40 100644 --- a/base/services/umpnpmgr/umpnpmgr.c +++ b/base/services/umpnpmgr/umpnpmgr.c @@ -1620,7 +1620,7 @@ DWORD PNP_CreateDevInst( dwInstanceNumber = 0; do { - swprintf(szGeneratedInstance, L"Root\\%ls\\%04d", + swprintf(szGeneratedInstance, L"Root\\%ls\\%04lu", pszDeviceID, dwInstanceNumber); /* Try to create a device instance with this ID */ @@ -2115,7 +2115,7 @@ DWORD PNP_HwProfFlags( else { swprintf(szKeyName, - L"System\\CurrentControlSet\\HardwareProfiles\\%04u\\System\\CurrentControlSet\\Enum", + L"System\\CurrentControlSet\\HardwareProfiles\\%04lu\\System\\CurrentControlSet\\Enum", ulConfig); } diff --git a/base/setup/usetup/mui.c b/base/setup/usetup/mui.c index 174f2f96313..71a6250feb9 100644 --- a/base/setup/usetup/mui.c +++ b/base/setup/usetup/mui.c @@ -461,7 +461,7 @@ AddKbLayoutsToRegistry(IN const MUI_LAYOUTS * MuiLayouts) } else { - swprintf(szLangID, L"d%03u%s", uCount, MuiLayouts[uIndex].LangID); + swprintf(szLangID, L"d%03lu%s", uCount, MuiLayouts[uIndex].LangID); Status = NtSetValueKey(KeyHandle, &ValueName, 0, diff --git a/base/setup/usetup/partlist.c b/base/setup/usetup/partlist.c index a678c94cf7e..c81ce910581 100644 --- a/base/setup/usetup/partlist.c +++ b/base/setup/usetup/partlist.c @@ -33,576 +33,585 @@ /* FUNCTIONS ****************************************************************/ -static VOID -GetDriverName (PDISKENTRY DiskEntry) +static +VOID +GetDriverName( + PDISKENTRY DiskEntry) { - RTL_QUERY_REGISTRY_TABLE QueryTable[2]; - WCHAR KeyName[32]; - NTSTATUS Status; + RTL_QUERY_REGISTRY_TABLE QueryTable[2]; + WCHAR KeyName[32]; + NTSTATUS Status; - RtlInitUnicodeString (&DiskEntry->DriverName, - NULL); + RtlInitUnicodeString(&DiskEntry->DriverName, + NULL); - swprintf (KeyName, - L"\\Scsi\\Scsi Port %lu", - DiskEntry->Port); + swprintf(KeyName, + L"\\Scsi\\Scsi Port %lu", + DiskEntry->Port); - RtlZeroMemory (&QueryTable, - sizeof(QueryTable)); + RtlZeroMemory(&QueryTable, + sizeof(QueryTable)); - QueryTable[0].Name = L"Driver"; - QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; - QueryTable[0].EntryContext = &DiskEntry->DriverName; + QueryTable[0].Name = L"Driver"; + QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; + QueryTable[0].EntryContext = &DiskEntry->DriverName; - Status = RtlQueryRegistryValues (RTL_REGISTRY_DEVICEMAP, - KeyName, - QueryTable, - NULL, - NULL); - if (!NT_SUCCESS (Status)) - { - DPRINT1 ("RtlQueryRegistryValues() failed (Status %lx)\n", Status); - } -} - - -static VOID -AssignDriverLetters (PPARTLIST List) -{ - PDISKENTRY DiskEntry; - PPARTENTRY PartEntry; - PLIST_ENTRY Entry1; - //PLIST_ENTRY Entry2; - CHAR Letter; - UCHAR i; - - Letter = 'C'; - - /* Assign drive letters to primary partitions */ - Entry1 = List->DiskListHead.Flink; - while (Entry1 != &List->DiskListHead) - { - DiskEntry = CONTAINING_RECORD (Entry1, DISKENTRY, ListEntry); - - if (!IsListEmpty (&DiskEntry->PartListHead)) - { - PartEntry = CONTAINING_RECORD (DiskEntry->PartListHead.Flink, - PARTENTRY, - ListEntry); - - for (i=0; i<4; i++) - PartEntry->DriveLetter[i] = 0; - - if (PartEntry->Unpartitioned == FALSE) - { - for (i=0; i<4; i++) - { - if (IsContainerPartition (PartEntry->PartInfo[i].PartitionType)) - continue; - - if (IsRecognizedPartition (PartEntry->PartInfo[i].PartitionType) || - (PartEntry->PartInfo[i].PartitionType == PARTITION_ENTRY_UNUSED && - PartEntry->PartInfo[i].PartitionLength.QuadPart != 0LL)) - { - if (Letter <= 'Z') - { - PartEntry->DriveLetter[i] = Letter; - Letter++; - } - } - } - } - } - - Entry1 = Entry1->Flink; - } - - /* Assign drive letters to logical drives */ -#if 0 - Entry1 = List->DiskListHead.Flink; - while (Entry1 != &List->DiskListHead) - { - DiskEntry = CONTAINING_RECORD (Entry1, DISKENTRY, ListEntry); - - Entry2 = DiskEntry->PartListHead.Flink; - if (Entry2 != &DiskEntry->PartListHead) - { - Entry2 = Entry2->Flink; - while (Entry2 != &DiskEntry->PartListHead) - { - PartEntry = CONTAINING_RECORD (Entry2, - PARTENTRY, - ListEntry); - - PartEntry->DriveLetter = 0; - - if (PartEntry->Unpartitioned == FALSE && - !IsContainerPartition (PartEntry->PartInfo[0].PartitionType)) - { - if (IsRecognizedPartition (PartEntry->PartInfo[0].PartitionType) || - (PartEntry->PartInfo[0].PartitionType == PARTITION_ENTRY_UNUSED && - PartEntry->PartInfo[0].PartitionLength.QuadPart != 0LL)) - { - if (Letter <= 'Z') - { - PartEntry->DriveLetter = Letter; - Letter++; - } - } - } - - Entry2 = Entry2->Flink; - } - } - - Entry1 = Entry1->Flink; - } -#endif -} - - -static VOID -UpdatePartitionNumbers (PDISKENTRY DiskEntry) -{ - PPARTENTRY PartEntry; - PLIST_ENTRY Entry; - ULONG PartNumber; - ULONG i; - - PartNumber = 1; - Entry = DiskEntry->PartListHead.Flink; - while (Entry != &DiskEntry->PartListHead) - { - PartEntry = CONTAINING_RECORD (Entry, - PARTENTRY, - ListEntry); - - if (PartEntry->Unpartitioned == TRUE) - { - for (i = 0; i < 4; i++) - { - PartEntry->PartInfo[i].PartitionNumber = 0; - } - } - else - { - for (i = 0; i < 4; i++) - { - if (IsContainerPartition (PartEntry->PartInfo[i].PartitionType)) - { - PartEntry->PartInfo[i].PartitionNumber = 0; - } - else if (PartEntry->PartInfo[i].PartitionType == PARTITION_ENTRY_UNUSED && - PartEntry->PartInfo[i].PartitionLength.QuadPart == 0ULL) - { - PartEntry->PartInfo[i].PartitionNumber = 0; - } - else - { - PartEntry->PartInfo[i].PartitionNumber = PartNumber; - PartNumber++; - } - } - } - - Entry = Entry->Flink; - } -} - - -static VOID -AddPartitionToList (ULONG DiskNumber, - PDISKENTRY DiskEntry, - DRIVE_LAYOUT_INFORMATION *LayoutBuffer) -{ - PPARTENTRY PartEntry; - ULONG i; - ULONG j; - - for (i = 0; i < LayoutBuffer->PartitionCount; i += 4) - { - for (j = 0; j < 4; j++) - { - if (LayoutBuffer->PartitionEntry[i+j].PartitionType != PARTITION_ENTRY_UNUSED || - LayoutBuffer->PartitionEntry[i+j].PartitionLength.QuadPart != 0ULL) - { - break; - } - } - if (j >= 4) - { - continue; - } - - PartEntry = (PPARTENTRY)RtlAllocateHeap (ProcessHeap, - 0, - sizeof(PARTENTRY)); - if (PartEntry == NULL) - { - return; - } - - RtlZeroMemory (PartEntry, - sizeof(PARTENTRY)); - - PartEntry->Unpartitioned = FALSE; - - for (j = 0; j < 4; j++) - { - RtlCopyMemory (&PartEntry->PartInfo[j], - &LayoutBuffer->PartitionEntry[i+j], - sizeof(PARTITION_INFORMATION)); - } - - if (IsContainerPartition(PartEntry->PartInfo[0].PartitionType)) - { - PartEntry->FormatState = Unformatted; - } - else if ((PartEntry->PartInfo[0].PartitionType == PARTITION_FAT_12) || - (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT_16) || - (PartEntry->PartInfo[0].PartitionType == PARTITION_HUGE) || - (PartEntry->PartInfo[0].PartitionType == PARTITION_XINT13) || - (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32) || - (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32_XINT13)) - { -#if 0 - if (CheckFatFormat()) - { - PartEntry->FormatState = Preformatted; - } - else - { - PartEntry->FormatState = Unformatted; - } -#endif - PartEntry->FormatState = Preformatted; - } - else if (PartEntry->PartInfo[0].PartitionType == PARTITION_EXT2) - { -#if 0 - if (CheckExt2Format()) - { - PartEntry->FormatState = Preformatted; - } - else - { - PartEntry->FormatState = Unformatted; - } -#endif - PartEntry->FormatState = Preformatted; - } - else if (PartEntry->PartInfo[0].PartitionType == PARTITION_IFS) - { -#if 0 - if (CheckNtfsFormat()) - { - PartEntry->FormatState = Preformatted; - } - else if (CheckHpfsFormat()) - { - PartEntry->FormatState = Preformatted; - } - else - { - PartEntry->FormatState = Unformatted; - } -#endif - PartEntry->FormatState = Preformatted; - } - else - { - PartEntry->FormatState = UnknownFormat; - } - - InsertTailList (&DiskEntry->PartListHead, - &PartEntry->ListEntry); - } -} - - -static VOID -ScanForUnpartitionedDiskSpace (PDISKENTRY DiskEntry) -{ - ULONGLONG LastStartingOffset; - ULONGLONG LastPartitionLength; - ULONGLONG LastUnusedPartitionLength; - PPARTENTRY PartEntry; - PPARTENTRY NewPartEntry; - PLIST_ENTRY Entry; - ULONG i; - ULONG j; - - if (IsListEmpty (&DiskEntry->PartListHead)) - { - /* Create a partition table that represents the empty disk */ - PartEntry = (PPARTENTRY)RtlAllocateHeap (ProcessHeap, - 0, - sizeof(PARTENTRY)); - if (PartEntry == NULL) - return; - - RtlZeroMemory (PartEntry, - sizeof(PARTENTRY)); - - PartEntry->Unpartitioned = TRUE; - PartEntry->UnpartitionedOffset = 0ULL; - PartEntry->UnpartitionedLength = DiskEntry->DiskSize; - - PartEntry->FormatState = Unformatted; - - InsertTailList (&DiskEntry->PartListHead, - &PartEntry->ListEntry); - } - else - { - /* Start partition at head 1, cylinder 0 */ - LastStartingOffset = DiskEntry->TrackSize; - LastPartitionLength = 0ULL; - LastUnusedPartitionLength = 0ULL; - - i = 0; - Entry = DiskEntry->PartListHead.Flink; - while (Entry != &DiskEntry->PartListHead) - { - PartEntry = CONTAINING_RECORD (Entry, PARTENTRY, ListEntry); - - for (j = 0; j < 4; j++) - { - if ((!IsContainerPartition (PartEntry->PartInfo[j].PartitionType)) && - (PartEntry->PartInfo[j].PartitionType != PARTITION_ENTRY_UNUSED || - PartEntry->PartInfo[j].PartitionLength.QuadPart != 0LL)) - { - LastUnusedPartitionLength = - PartEntry->PartInfo[j].StartingOffset.QuadPart - - (LastStartingOffset + LastPartitionLength); - - if (PartEntry->PartInfo[j].StartingOffset.QuadPart > (LastStartingOffset + LastPartitionLength) && - LastUnusedPartitionLength >= DiskEntry->CylinderSize) - { - DPRINT ("Unpartitioned disk space %I64u\n", LastUnusedPartitionLength); - - NewPartEntry = (PPARTENTRY)RtlAllocateHeap (ProcessHeap, - 0, - sizeof(PARTENTRY)); - if (NewPartEntry == NULL) - return; - - RtlZeroMemory (NewPartEntry, - sizeof(PARTENTRY)); - - NewPartEntry->Unpartitioned = TRUE; - NewPartEntry->UnpartitionedOffset = LastStartingOffset + LastPartitionLength; - NewPartEntry->UnpartitionedLength = LastUnusedPartitionLength; - if (j == 0) - NewPartEntry->UnpartitionedLength -= DiskEntry->TrackSize; - - NewPartEntry->FormatState = Unformatted; - - /* Insert the table into the list */ - InsertTailList (&PartEntry->ListEntry, - &NewPartEntry->ListEntry); - } - - LastStartingOffset = PartEntry->PartInfo[j].StartingOffset.QuadPart; - LastPartitionLength = PartEntry->PartInfo[j].PartitionLength.QuadPart; - } - } - - i += 4; - Entry = Entry->Flink; - } - - /* Check for trailing unpartitioned disk space */ - if (DiskEntry->DiskSize > (LastStartingOffset + LastPartitionLength)) - { - /* Round-down to cylinder size */ - LastUnusedPartitionLength = - (DiskEntry->DiskSize - (LastStartingOffset + LastPartitionLength)) - & ~(DiskEntry->CylinderSize - 1); - - if (LastUnusedPartitionLength >= DiskEntry->CylinderSize) - { - DPRINT ("Unpartitioned disk space %I64u\n", LastUnusedPartitionLength); - - NewPartEntry = (PPARTENTRY)RtlAllocateHeap (ProcessHeap, - 0, - sizeof(PARTENTRY)); - if (NewPartEntry == NULL) - return; - - RtlZeroMemory (NewPartEntry, - sizeof(PARTENTRY)); - - NewPartEntry->Unpartitioned = TRUE; - NewPartEntry->UnpartitionedOffset = LastStartingOffset + LastPartitionLength; - NewPartEntry->UnpartitionedLength = LastUnusedPartitionLength; - - /* Append the table to the list */ - InsertTailList (&DiskEntry->PartListHead, - &NewPartEntry->ListEntry); - } - } - } -} - -NTSTATUS -NTAPI -DiskIdentifierQueryRoutine(PWSTR ValueName, - ULONG ValueType, - PVOID ValueData, - ULONG ValueLength, - PVOID Context, - PVOID EntryContext) -{ - PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context; - UNICODE_STRING NameU; - - if (ValueType == REG_SZ && - ValueLength == 20 * sizeof(WCHAR)) - { - NameU.Buffer = (PWCHAR)ValueData; - NameU.Length = NameU.MaximumLength = 8 * sizeof(WCHAR); - RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Checksum); - - NameU.Buffer = (PWCHAR)ValueData + 9; - RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Signature); - - return STATUS_SUCCESS; - } - return STATUS_UNSUCCESSFUL; -} - -NTSTATUS -NTAPI -DiskConfigurationDataQueryRoutine(PWSTR ValueName, - ULONG ValueType, - PVOID ValueData, - ULONG ValueLength, - PVOID Context, - PVOID EntryContext) -{ - PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context; - PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor; - PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry; - ULONG i; - - if (ValueType != REG_FULL_RESOURCE_DESCRIPTOR || - ValueLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR)) - return STATUS_UNSUCCESSFUL; - - FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData; - /* Hm. Version and Revision are not set on Microsoft Windows XP... */ - /*if (FullResourceDescriptor->PartialResourceList.Version != 1 || - FullResourceDescriptor->PartialResourceList.Revision != 1) - return STATUS_UNSUCCESSFUL;*/ - - for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++) - { - if (FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].Type != CmResourceTypeDeviceSpecific || - FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize != sizeof(CM_DISK_GEOMETRY_DEVICE_DATA)) - continue; - - DiskGeometry = (PCM_DISK_GEOMETRY_DEVICE_DATA)&FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1]; - BiosDiskEntry->DiskGeometry = *DiskGeometry; - - return STATUS_SUCCESS; - } - return STATUS_UNSUCCESSFUL; -} - -NTSTATUS -NTAPI -SystemConfigurationDataQueryRoutine(PWSTR ValueName, - ULONG ValueType, - PVOID ValueData, - ULONG ValueLength, - PVOID Context, - PVOID EntryContext) -{ - PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor; - PCM_INT13_DRIVE_PARAMETER* Int13Drives = (PCM_INT13_DRIVE_PARAMETER*)Context; - ULONG i; - - if (ValueType != REG_FULL_RESOURCE_DESCRIPTOR || - ValueLength < sizeof (CM_FULL_RESOURCE_DESCRIPTOR)) - return STATUS_UNSUCCESSFUL; - - FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData; - /* Hm. Version and Revision are not set on Microsoft Windows XP... */ - /*if (FullResourceDescriptor->PartialResourceList.Version != 1 || - FullResourceDescriptor->PartialResourceList.Revision != 1) - return STATUS_UNSUCCESSFUL;*/ - - for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++) - { - if (FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].Type != CmResourceTypeDeviceSpecific || - FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize % sizeof(CM_INT13_DRIVE_PARAMETER) != 0) - continue; - - *Int13Drives = (CM_INT13_DRIVE_PARAMETER*) RtlAllocateHeap(ProcessHeap, 0, FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize); - if (*Int13Drives == NULL) - return STATUS_NO_MEMORY; - memcpy(*Int13Drives, - &FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1], - FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize); - return STATUS_SUCCESS; - } - return STATUS_UNSUCCESSFUL; -} -#define ROOT_NAME L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter" - -static VOID -EnumerateBiosDiskEntries(PPARTLIST PartList) -{ - RTL_QUERY_REGISTRY_TABLE QueryTable[3]; - WCHAR Name[120]; - ULONG AdapterCount; - ULONG DiskCount; - NTSTATUS Status; - PCM_INT13_DRIVE_PARAMETER Int13Drives; - PBIOSDISKENTRY BiosDiskEntry; - - memset(QueryTable, 0, sizeof(QueryTable)); - - QueryTable[1].Name = L"Configuration Data"; - QueryTable[1].QueryRoutine = SystemConfigurationDataQueryRoutine; - Int13Drives = NULL; - Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, - L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System", - &QueryTable[1], - (PVOID)&Int13Drives, - NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Unable to query the 'Configuration Data' key in '\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System', status=%lx\n", Status); - return; - } - - AdapterCount = 0; - while (1) - { - swprintf(Name, L"%s\\%lu", ROOT_NAME, AdapterCount); - Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, - Name, - &QueryTable[2], + Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP, + KeyName, + QueryTable, NULL, NULL); if (!NT_SUCCESS(Status)) { - break; + DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status); + } +} + + +static +VOID +AssignDriverLetters( + PPARTLIST List) +{ + PDISKENTRY DiskEntry; + PPARTENTRY PartEntry; + PLIST_ENTRY Entry1; + //PLIST_ENTRY Entry2; + CHAR Letter; + UCHAR i; + + Letter = 'C'; + + /* Assign drive letters to primary partitions */ + Entry1 = List->DiskListHead.Flink; + while (Entry1 != &List->DiskListHead) + { + DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry); + + if (!IsListEmpty(&DiskEntry->PartListHead)) + { + PartEntry = CONTAINING_RECORD(DiskEntry->PartListHead.Flink, + PARTENTRY, + ListEntry); + + for (i = 0; i < 4; i++) + PartEntry->DriveLetter[i] = 0; + + if (PartEntry->Unpartitioned == FALSE) + { + for (i = 0; i < 4; i++) + { + if (IsContainerPartition(PartEntry->PartInfo[i].PartitionType)) + continue; + + if (IsRecognizedPartition(PartEntry->PartInfo[i].PartitionType) || + (PartEntry->PartInfo[i].PartitionType == PARTITION_ENTRY_UNUSED && + PartEntry->PartInfo[i].PartitionLength.QuadPart != 0LL)) + { + if (Letter <= 'Z') + { + PartEntry->DriveLetter[i] = Letter; + Letter++; + } + } + } + } + } + + Entry1 = Entry1->Flink; } - swprintf(Name, L"%s\\%lu\\DiskController", ROOT_NAME, AdapterCount); - Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, - Name, - &QueryTable[2], - NULL, - NULL); - if (NT_SUCCESS(Status)) + /* Assign drive letters to logical drives */ +#if 0 + Entry1 = List->DiskListHead.Flink; + while (Entry1 != &List->DiskListHead) { - while (1) - { - swprintf(Name, L"%s\\%lu\\DiskController\\0", ROOT_NAME, AdapterCount); + DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry); + + Entry2 = DiskEntry->PartListHead.Flink; + if (Entry2 != &DiskEntry->PartListHead) + { + Entry2 = Entry2->Flink; + while (Entry2 != &DiskEntry->PartListHead) + { + PartEntry = CONTAINING_RECORD(Entry2, + PARTENTRY, + ListEntry); + + PartEntry->DriveLetter = 0; + + if (PartEntry->Unpartitioned == FALSE && + !IsContainerPartition(PartEntry->PartInfo[0].PartitionType)) + { + if (IsRecognizedPartition(PartEntry->PartInfo[0].PartitionType) || + (PartEntry->PartInfo[0].PartitionType == PARTITION_ENTRY_UNUSED && + PartEntry->PartInfo[0].PartitionLength.QuadPart != 0LL)) + { + if (Letter <= 'Z') + { + PartEntry->DriveLetter = Letter; + Letter++; + } + } + } + + Entry2 = Entry2->Flink; + } + } + + Entry1 = Entry1->Flink; + } +#endif +} + + +static +VOID +UpdatePartitionNumbers( + PDISKENTRY DiskEntry) +{ + PPARTENTRY PartEntry; + PLIST_ENTRY Entry; + ULONG PartNumber; + ULONG i; + + PartNumber = 1; + Entry = DiskEntry->PartListHead.Flink; + while (Entry != &DiskEntry->PartListHead) + { + PartEntry = CONTAINING_RECORD(Entry, + PARTENTRY, + ListEntry); + + if (PartEntry->Unpartitioned == TRUE) + { + for (i = 0; i < 4; i++) + { + PartEntry->PartInfo[i].PartitionNumber = 0; + } + } + else + { + for (i = 0; i < 4; i++) + { + if (IsContainerPartition(PartEntry->PartInfo[i].PartitionType)) + { + PartEntry->PartInfo[i].PartitionNumber = 0; + } + else if (PartEntry->PartInfo[i].PartitionType == PARTITION_ENTRY_UNUSED && + PartEntry->PartInfo[i].PartitionLength.QuadPart == 0ULL) + { + PartEntry->PartInfo[i].PartitionNumber = 0; + } + else + { + PartEntry->PartInfo[i].PartitionNumber = PartNumber; + PartNumber++; + } + } + } + + Entry = Entry->Flink; + } +} + + +static +VOID +AddPartitionToList( + ULONG DiskNumber, + PDISKENTRY DiskEntry, + DRIVE_LAYOUT_INFORMATION *LayoutBuffer) +{ + PPARTENTRY PartEntry; + ULONG i; + ULONG j; + + for (i = 0; i < LayoutBuffer->PartitionCount; i += 4) + { + for (j = 0; j < 4; j++) + { + if (LayoutBuffer->PartitionEntry[i+j].PartitionType != PARTITION_ENTRY_UNUSED || + LayoutBuffer->PartitionEntry[i+j].PartitionLength.QuadPart != 0ULL) + { + break; + } + } + + if (j >= 4) + { + continue; + } + + PartEntry = (PPARTENTRY)RtlAllocateHeap(ProcessHeap, + 0, + sizeof(PARTENTRY)); + if (PartEntry == NULL) + { + return; + } + + RtlZeroMemory(PartEntry, + sizeof(PARTENTRY)); + + PartEntry->Unpartitioned = FALSE; + + for (j = 0; j < 4; j++) + { + RtlCopyMemory(&PartEntry->PartInfo[j], + &LayoutBuffer->PartitionEntry[i+j], + sizeof(PARTITION_INFORMATION)); + } + + if (IsContainerPartition(PartEntry->PartInfo[0].PartitionType)) + { + PartEntry->FormatState = Unformatted; + } + else if ((PartEntry->PartInfo[0].PartitionType == PARTITION_FAT_12) || + (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT_16) || + (PartEntry->PartInfo[0].PartitionType == PARTITION_HUGE) || + (PartEntry->PartInfo[0].PartitionType == PARTITION_XINT13) || + (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32) || + (PartEntry->PartInfo[0].PartitionType == PARTITION_FAT32_XINT13)) + { +#if 0 + if (CheckFatFormat()) + { + PartEntry->FormatState = Preformatted; + } + else + { + PartEntry->FormatState = Unformatted; + } +#endif + PartEntry->FormatState = Preformatted; + } + else if (PartEntry->PartInfo[0].PartitionType == PARTITION_EXT2) + { +#if 0 + if (CheckExt2Format()) + { + PartEntry->FormatState = Preformatted; + } + else + { + PartEntry->FormatState = Unformatted; + } +#endif + PartEntry->FormatState = Preformatted; + } + else if (PartEntry->PartInfo[0].PartitionType == PARTITION_IFS) + { +#if 0 + if (CheckNtfsFormat()) + { + PartEntry->FormatState = Preformatted; + } + else if (CheckHpfsFormat()) + { + PartEntry->FormatState = Preformatted; + } + else + { + PartEntry->FormatState = Unformatted; + } +#endif + PartEntry->FormatState = Preformatted; + } + else + { + PartEntry->FormatState = UnknownFormat; + } + + InsertTailList(&DiskEntry->PartListHead, + &PartEntry->ListEntry); + } +} + + +static +VOID +ScanForUnpartitionedDiskSpace( + PDISKENTRY DiskEntry) +{ + ULONGLONG LastStartingOffset; + ULONGLONG LastPartitionLength; + ULONGLONG LastUnusedPartitionLength; + PPARTENTRY PartEntry; + PPARTENTRY NewPartEntry; + PLIST_ENTRY Entry; + ULONG i; + ULONG j; + + if (IsListEmpty (&DiskEntry->PartListHead)) + { + /* Create a partition table that represents the empty disk */ + PartEntry = (PPARTENTRY)RtlAllocateHeap(ProcessHeap, + 0, + sizeof(PARTENTRY)); + if (PartEntry == NULL) + return; + + RtlZeroMemory(PartEntry, + sizeof(PARTENTRY)); + + PartEntry->Unpartitioned = TRUE; + PartEntry->UnpartitionedOffset = 0ULL; + PartEntry->UnpartitionedLength = DiskEntry->DiskSize; + + PartEntry->FormatState = Unformatted; + + InsertTailList(&DiskEntry->PartListHead, + &PartEntry->ListEntry); + } + else + { + /* Start partition at head 1, cylinder 0 */ + LastStartingOffset = DiskEntry->TrackSize; + LastPartitionLength = 0ULL; + LastUnusedPartitionLength = 0ULL; + + i = 0; + Entry = DiskEntry->PartListHead.Flink; + while (Entry != &DiskEntry->PartListHead) + { + PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); + + for (j = 0; j < 4; j++) + { + if ((!IsContainerPartition (PartEntry->PartInfo[j].PartitionType)) && + (PartEntry->PartInfo[j].PartitionType != PARTITION_ENTRY_UNUSED || + PartEntry->PartInfo[j].PartitionLength.QuadPart != 0LL)) + { + LastUnusedPartitionLength = + PartEntry->PartInfo[j].StartingOffset.QuadPart - + (LastStartingOffset + LastPartitionLength); + + if (PartEntry->PartInfo[j].StartingOffset.QuadPart > (LastStartingOffset + LastPartitionLength) && + LastUnusedPartitionLength >= DiskEntry->CylinderSize) + { + DPRINT("Unpartitioned disk space %I64u\n", LastUnusedPartitionLength); + + NewPartEntry = (PPARTENTRY)RtlAllocateHeap(ProcessHeap, + 0, + sizeof(PARTENTRY)); + if (NewPartEntry == NULL) + return; + + RtlZeroMemory(NewPartEntry, + sizeof(PARTENTRY)); + + NewPartEntry->Unpartitioned = TRUE; + NewPartEntry->UnpartitionedOffset = LastStartingOffset + LastPartitionLength; + NewPartEntry->UnpartitionedLength = LastUnusedPartitionLength; + if (j == 0) + NewPartEntry->UnpartitionedLength -= DiskEntry->TrackSize; + + NewPartEntry->FormatState = Unformatted; + + /* Insert the table into the list */ + InsertTailList(&PartEntry->ListEntry, + &NewPartEntry->ListEntry); + } + + LastStartingOffset = PartEntry->PartInfo[j].StartingOffset.QuadPart; + LastPartitionLength = PartEntry->PartInfo[j].PartitionLength.QuadPart; + } + } + + i += 4; + Entry = Entry->Flink; + } + + /* Check for trailing unpartitioned disk space */ + if (DiskEntry->DiskSize > (LastStartingOffset + LastPartitionLength)) + { + /* Round-down to cylinder size */ + LastUnusedPartitionLength = + (DiskEntry->DiskSize - (LastStartingOffset + LastPartitionLength)) + & ~(DiskEntry->CylinderSize - 1); + + if (LastUnusedPartitionLength >= DiskEntry->CylinderSize) + { + DPRINT("Unpartitioned disk space %I64u\n", LastUnusedPartitionLength); + + NewPartEntry = (PPARTENTRY)RtlAllocateHeap(ProcessHeap, + 0, + sizeof(PARTENTRY)); + if (NewPartEntry == NULL) + return; + + RtlZeroMemory(NewPartEntry, + sizeof(PARTENTRY)); + + NewPartEntry->Unpartitioned = TRUE; + NewPartEntry->UnpartitionedOffset = LastStartingOffset + LastPartitionLength; + NewPartEntry->UnpartitionedLength = LastUnusedPartitionLength; + + /* Append the table to the list */ + InsertTailList(&DiskEntry->PartListHead, + &NewPartEntry->ListEntry); + } + } + } +} + + +NTSTATUS +NTAPI +DiskIdentifierQueryRoutine( + PWSTR ValueName, + ULONG ValueType, + PVOID ValueData, + ULONG ValueLength, + PVOID Context, + PVOID EntryContext) +{ + PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context; + UNICODE_STRING NameU; + + if (ValueType == REG_SZ && + ValueLength == 20 * sizeof(WCHAR)) + { + NameU.Buffer = (PWCHAR)ValueData; + NameU.Length = NameU.MaximumLength = 8 * sizeof(WCHAR); + RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Checksum); + + NameU.Buffer = (PWCHAR)ValueData + 9; + RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Signature); + + return STATUS_SUCCESS; + } + + return STATUS_UNSUCCESSFUL; +} + + +NTSTATUS +NTAPI +DiskConfigurationDataQueryRoutine( + PWSTR ValueName, + ULONG ValueType, + PVOID ValueData, + ULONG ValueLength, + PVOID Context, + PVOID EntryContext) +{ + PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context; + PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor; + PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry; + ULONG i; + + if (ValueType != REG_FULL_RESOURCE_DESCRIPTOR || + ValueLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR)) + return STATUS_UNSUCCESSFUL; + + FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData; + + /* Hm. Version and Revision are not set on Microsoft Windows XP... */ +#if 0 + if (FullResourceDescriptor->PartialResourceList.Version != 1 || + FullResourceDescriptor->PartialResourceList.Revision != 1) + return STATUS_UNSUCCESSFUL; +#endif + + for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++) + { + if (FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].Type != CmResourceTypeDeviceSpecific || + FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize != sizeof(CM_DISK_GEOMETRY_DEVICE_DATA)) + continue; + + DiskGeometry = (PCM_DISK_GEOMETRY_DEVICE_DATA)&FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1]; + BiosDiskEntry->DiskGeometry = *DiskGeometry; + + return STATUS_SUCCESS; + } + + return STATUS_UNSUCCESSFUL; +} + + +NTSTATUS +NTAPI +SystemConfigurationDataQueryRoutine( + PWSTR ValueName, + ULONG ValueType, + PVOID ValueData, + ULONG ValueLength, + PVOID Context, + PVOID EntryContext) +{ + PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor; + PCM_INT13_DRIVE_PARAMETER* Int13Drives = (PCM_INT13_DRIVE_PARAMETER*)Context; + ULONG i; + + if (ValueType != REG_FULL_RESOURCE_DESCRIPTOR || + ValueLength < sizeof (CM_FULL_RESOURCE_DESCRIPTOR)) + return STATUS_UNSUCCESSFUL; + + FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData; + + /* Hm. Version and Revision are not set on Microsoft Windows XP... */ +#if 0 + if (FullResourceDescriptor->PartialResourceList.Version != 1 || + FullResourceDescriptor->PartialResourceList.Revision != 1) + return STATUS_UNSUCCESSFUL; +#endif + + for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++) + { + if (FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].Type != CmResourceTypeDeviceSpecific || + FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize % sizeof(CM_INT13_DRIVE_PARAMETER) != 0) + continue; + + *Int13Drives = (CM_INT13_DRIVE_PARAMETER*) RtlAllocateHeap(ProcessHeap, 0, FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize); + if (*Int13Drives == NULL) + return STATUS_NO_MEMORY; + + memcpy(*Int13Drives, + &FullResourceDescriptor->PartialResourceList.PartialDescriptors[i + 1], + FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize); + return STATUS_SUCCESS; + } + + return STATUS_UNSUCCESSFUL; +} + + +#define ROOT_NAME L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter" + +static VOID +EnumerateBiosDiskEntries( + PPARTLIST PartList) +{ + RTL_QUERY_REGISTRY_TABLE QueryTable[3]; + WCHAR Name[120]; + ULONG AdapterCount; + ULONG DiskCount; + NTSTATUS Status; + PCM_INT13_DRIVE_PARAMETER Int13Drives; + PBIOSDISKENTRY BiosDiskEntry; + + memset(QueryTable, 0, sizeof(QueryTable)); + + QueryTable[1].Name = L"Configuration Data"; + QueryTable[1].QueryRoutine = SystemConfigurationDataQueryRoutine; + Int13Drives = NULL; + Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, + L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System", + &QueryTable[1], + (PVOID)&Int13Drives, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Unable to query the 'Configuration Data' key in '\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System', status=%lx\n", Status); + return; + } + + AdapterCount = 0; + while (1) + { + swprintf(Name, L"%s\\%lu", ROOT_NAME, AdapterCount); Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, Name, &QueryTable[2], @@ -610,11 +619,10 @@ EnumerateBiosDiskEntries(PPARTLIST PartList) NULL); if (!NT_SUCCESS(Status)) { - RtlFreeHeap(ProcessHeap, 0, Int13Drives); - return; + break; } - swprintf(Name, L"%s\\%lu\\DiskController\\0\\DiskPeripheral", ROOT_NAME, AdapterCount); + swprintf(Name, L"%s\\%lu\\DiskController", ROOT_NAME, AdapterCount); Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, Name, &QueryTable[2], @@ -622,2140 +630,2217 @@ EnumerateBiosDiskEntries(PPARTLIST PartList) NULL); if (NT_SUCCESS(Status)) { - QueryTable[0].Name = L"Identifier"; - QueryTable[0].QueryRoutine = DiskIdentifierQueryRoutine; - QueryTable[1].Name = L"Configuration Data"; - QueryTable[1].QueryRoutine = DiskConfigurationDataQueryRoutine; - DiskCount = 0; - while (1) - { - BiosDiskEntry = (BIOSDISKENTRY*) RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, sizeof(BIOSDISKENTRY)); - if (BiosDiskEntry == NULL) + while (1) { - break; + swprintf(Name, L"%s\\%lu\\DiskController\\0", ROOT_NAME, AdapterCount); + Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, + Name, + &QueryTable[2], + NULL, + NULL); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, Int13Drives); + return; + } + + swprintf(Name, L"%s\\%lu\\DiskController\\0\\DiskPeripheral", ROOT_NAME, AdapterCount); + Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, + Name, + &QueryTable[2], + NULL, + NULL); + if (NT_SUCCESS(Status)) + { + QueryTable[0].Name = L"Identifier"; + QueryTable[0].QueryRoutine = DiskIdentifierQueryRoutine; + QueryTable[1].Name = L"Configuration Data"; + QueryTable[1].QueryRoutine = DiskConfigurationDataQueryRoutine; + + DiskCount = 0; + while (1) + { + BiosDiskEntry = (BIOSDISKENTRY*) RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY, sizeof(BIOSDISKENTRY)); + if (BiosDiskEntry == NULL) + { + break; + } + + swprintf(Name, L"%s\\%lu\\DiskController\\0\\DiskPeripheral\\%lu", ROOT_NAME, AdapterCount, DiskCount); + Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, + Name, + QueryTable, + (PVOID)BiosDiskEntry, + NULL); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry); + break; + } + + BiosDiskEntry->DiskNumber = DiskCount; + BiosDiskEntry->Recognized = FALSE; + + if (DiskCount < Int13Drives[0].NumberDrives) + { + BiosDiskEntry->Int13DiskData = Int13Drives[DiskCount]; + } + else + { + DPRINT1("Didn't find int13 drive datas for disk %u\n", DiskCount); + } + + InsertTailList(&PartList->BiosDiskListHead, &BiosDiskEntry->ListEntry); + + DPRINT("DiskNumber: %lu\n", BiosDiskEntry->DiskNumber); + DPRINT("Signature: %08lx\n", BiosDiskEntry->Signature); + DPRINT("Checksum: %08lx\n", BiosDiskEntry->Checksum); + DPRINT("BytesPerSector: %lu\n", BiosDiskEntry->DiskGeometry.BytesPerSector); + DPRINT("NumberOfCylinders: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfCylinders); + DPRINT("NumberOfHeads: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfHeads); + DPRINT("DriveSelect: %02x\n", BiosDiskEntry->Int13DiskData.DriveSelect); + DPRINT("MaxCylinders: %lu\n", BiosDiskEntry->Int13DiskData.MaxCylinders); + DPRINT("SectorsPerTrack: %d\n", BiosDiskEntry->Int13DiskData.SectorsPerTrack); + DPRINT("MaxHeads: %d\n", BiosDiskEntry->Int13DiskData.MaxHeads); + DPRINT("NumberDrives: %d\n", BiosDiskEntry->Int13DiskData.NumberDrives); + + DiskCount++; + } + } + + RtlFreeHeap(ProcessHeap, 0, Int13Drives); + return; } - swprintf(Name, L"%s\\%lu\\DiskController\\0\\DiskPeripheral\\%lu", ROOT_NAME, AdapterCount, DiskCount); - Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, - Name, - QueryTable, - (PVOID)BiosDiskEntry, - NULL); - if (!NT_SUCCESS(Status)) - { - RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry); - break; - } - BiosDiskEntry->DiskNumber = DiskCount; - BiosDiskEntry->Recognized = FALSE; - - if (DiskCount < Int13Drives[0].NumberDrives) - { - BiosDiskEntry->Int13DiskData = Int13Drives[DiskCount]; - } - else - { - DPRINT1("Didn't find int13 drive datas for disk %u\n", DiskCount); - } - - - InsertTailList(&PartList->BiosDiskListHead, &BiosDiskEntry->ListEntry); - - DPRINT("DiskNumber: %lu\n", BiosDiskEntry->DiskNumber); - DPRINT("Signature: %08lx\n", BiosDiskEntry->Signature); - DPRINT("Checksum: %08lx\n", BiosDiskEntry->Checksum); - DPRINT("BytesPerSector: %lu\n", BiosDiskEntry->DiskGeometry.BytesPerSector); - DPRINT("NumberOfCylinders: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfCylinders); - DPRINT("NumberOfHeads: %lu\n", BiosDiskEntry->DiskGeometry.NumberOfHeads); - DPRINT("DriveSelect: %02x\n", BiosDiskEntry->Int13DiskData.DriveSelect); - DPRINT("MaxCylinders: %lu\n", BiosDiskEntry->Int13DiskData.MaxCylinders); - DPRINT("SectorsPerTrack: %d\n", BiosDiskEntry->Int13DiskData.SectorsPerTrack); - DPRINT("MaxHeads: %d\n", BiosDiskEntry->Int13DiskData.MaxHeads); - DPRINT("NumberDrives: %d\n", BiosDiskEntry->Int13DiskData.NumberDrives); - - DiskCount++; - } } - RtlFreeHeap(ProcessHeap, 0, Int13Drives); - return; - } + + AdapterCount++; } - AdapterCount++; - } - RtlFreeHeap(ProcessHeap, 0, Int13Drives); + + RtlFreeHeap(ProcessHeap, 0, Int13Drives); } -static VOID -AddDiskToList (HANDLE FileHandle, - ULONG DiskNumber, - PPARTLIST List) + +static +VOID +AddDiskToList( + HANDLE FileHandle, + ULONG DiskNumber, + PPARTLIST List) { - DRIVE_LAYOUT_INFORMATION *LayoutBuffer; - DISK_GEOMETRY DiskGeometry; - SCSI_ADDRESS ScsiAddress; - PDISKENTRY DiskEntry; - IO_STATUS_BLOCK Iosb; - NTSTATUS Status; - PPARTITION_SECTOR Mbr; - PULONG Buffer; - LARGE_INTEGER FileOffset; - WCHAR Identifier[20]; - ULONG Checksum; - ULONG Signature; - ULONG i; - PLIST_ENTRY ListEntry; - PBIOSDISKENTRY BiosDiskEntry; - ULONG LayoutBufferSize; + DRIVE_LAYOUT_INFORMATION *LayoutBuffer; + DISK_GEOMETRY DiskGeometry; + SCSI_ADDRESS ScsiAddress; + PDISKENTRY DiskEntry; + IO_STATUS_BLOCK Iosb; + NTSTATUS Status; + PPARTITION_SECTOR Mbr; + PULONG Buffer; + LARGE_INTEGER FileOffset; + WCHAR Identifier[20]; + ULONG Checksum; + ULONG Signature; + ULONG i; + PLIST_ENTRY ListEntry; + PBIOSDISKENTRY BiosDiskEntry; + ULONG LayoutBufferSize; - Status = NtDeviceIoControlFile (FileHandle, - NULL, - NULL, - NULL, - &Iosb, - IOCTL_DISK_GET_DRIVE_GEOMETRY, - NULL, - 0, - &DiskGeometry, - sizeof(DISK_GEOMETRY)); - if (!NT_SUCCESS (Status)) - { - return; - } + Status = NtDeviceIoControlFile(FileHandle, + NULL, + NULL, + NULL, + &Iosb, + IOCTL_DISK_GET_DRIVE_GEOMETRY, + NULL, + 0, + &DiskGeometry, + sizeof(DISK_GEOMETRY)); + if (!NT_SUCCESS(Status)) + { + return; + } - if (DiskGeometry.MediaType != FixedMedia && - DiskGeometry.MediaType != RemovableMedia) - { - return; - } + if (DiskGeometry.MediaType != FixedMedia && + DiskGeometry.MediaType != RemovableMedia) + { + return; + } - Status = NtDeviceIoControlFile (FileHandle, - NULL, - NULL, - NULL, - &Iosb, - IOCTL_SCSI_GET_ADDRESS, - NULL, - 0, - &ScsiAddress, - sizeof(SCSI_ADDRESS)); - if (!NT_SUCCESS(Status)) - { - return; - } + Status = NtDeviceIoControlFile(FileHandle, + NULL, + NULL, + NULL, + &Iosb, + IOCTL_SCSI_GET_ADDRESS, + NULL, + 0, + &ScsiAddress, + sizeof(SCSI_ADDRESS)); + if (!NT_SUCCESS(Status)) + { + return; + } - Mbr = (PARTITION_SECTOR*) RtlAllocateHeap(ProcessHeap, + Mbr = (PARTITION_SECTOR*)RtlAllocateHeap(ProcessHeap, + 0, + DiskGeometry.BytesPerSector); + if (Mbr == NULL) + { + return; + } + + FileOffset.QuadPart = 0; + Status = NtReadFile(FileHandle, + NULL, + NULL, + NULL, + &Iosb, + (PVOID)Mbr, + DiskGeometry.BytesPerSector, + &FileOffset, + NULL); + if (!NT_SUCCESS(Status)) + { + RtlFreeHeap(ProcessHeap, + 0, + Mbr); + DPRINT1("NtReadFile failed, status=%x\n", Status); + return; + } + Signature = Mbr->Signature; + + /* Calculate the MBR checksum */ + Checksum = 0; + Buffer = (PULONG)Mbr; + for (i = 0; i < 128; i++) + { + Checksum += Buffer[i]; + } + Checksum = ~Checksum + 1; + + swprintf(Identifier, L"%08x-%08x-A", Checksum, Signature); + DPRINT("Identifier: %S\n", Identifier); + + DiskEntry = (PDISKENTRY)RtlAllocateHeap(ProcessHeap, 0, - DiskGeometry.BytesPerSector); + sizeof(DISKENTRY)); + if (DiskEntry == NULL) + { + return; + } - if (Mbr == NULL) - { - return; - } + DiskEntry->Checksum = Checksum; + DiskEntry->Signature = Signature; + if (Signature == 0) + { + /* If we have no signature, set the disk to dirty. WritePartitionsToDisk creates a new signature */ + DiskEntry->Modified = TRUE; + } + DiskEntry->BiosFound = FALSE; - FileOffset.QuadPart = 0; - Status = NtReadFile(FileHandle, - NULL, - NULL, - NULL, - &Iosb, - (PVOID)Mbr, - DiskGeometry.BytesPerSector, - &FileOffset, - NULL); - if (!NT_SUCCESS(Status)) - { + /* Check if this disk has a valid MBR */ + if (Mbr->BootCode[0] == 0 && Mbr->BootCode[1] == 0) + DiskEntry->NoMbr = TRUE; + else + DiskEntry->NoMbr = FALSE; + + /* Free Mbr sector buffer */ RtlFreeHeap(ProcessHeap, 0, Mbr); - DPRINT1("NtReadFile failed, status=%x\n", Status); - return; - } - Signature = Mbr->Signature; - /* Calculate the MBR checksum */ - Checksum = 0; - Buffer = (PULONG)Mbr; - for (i = 0; i < 128; i++) - { - Checksum += Buffer[i]; - } - Checksum = ~Checksum + 1; - - swprintf(Identifier, L"%08x-%08x-A", Checksum, Signature); - DPRINT("Identifier: %S\n", Identifier); - - DiskEntry = (PDISKENTRY)RtlAllocateHeap (ProcessHeap, - 0, - sizeof(DISKENTRY)); - if (DiskEntry == NULL) - { - return; - } - - DiskEntry->Checksum = Checksum; - DiskEntry->Signature = Signature; - if (Signature == 0) - { - /* If we have no signature, set the disk to dirty. WritePartitionsToDisk creates a new signature */ - DiskEntry->Modified = TRUE; - } - DiskEntry->BiosFound = FALSE; - - /* Check if this disk has a valid MBR */ - if (Mbr->BootCode[0] == 0 && Mbr->BootCode[1] == 0) - DiskEntry->NoMbr = TRUE; - else - DiskEntry->NoMbr = FALSE; - - /* Free Mbr sector buffer */ - RtlFreeHeap (ProcessHeap, - 0, - Mbr); - - ListEntry = List->BiosDiskListHead.Flink; - while(ListEntry != &List->BiosDiskListHead) - { - BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry); - /* FIXME: - * Compare the size from bios and the reported size from driver. - * If we have more than one disk with a zero or with the same signatur - * we must create new signatures and reboot. After the reboot, - * it is possible to identify the disks. - */ - if (BiosDiskEntry->Signature == Signature && - BiosDiskEntry->Checksum == Checksum && - !BiosDiskEntry->Recognized) + ListEntry = List->BiosDiskListHead.Flink; + while(ListEntry != &List->BiosDiskListHead) { - if (!DiskEntry->BiosFound) - { - DiskEntry->BiosDiskNumber = BiosDiskEntry->DiskNumber; - DiskEntry->BiosFound = TRUE; - BiosDiskEntry->Recognized = TRUE; - } - else - { - } + BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry); + /* FIXME: + * Compare the size from bios and the reported size from driver. + * If we have more than one disk with a zero or with the same signatur + * we must create new signatures and reboot. After the reboot, + * it is possible to identify the disks. + */ + if (BiosDiskEntry->Signature == Signature && + BiosDiskEntry->Checksum == Checksum && + !BiosDiskEntry->Recognized) + { + if (!DiskEntry->BiosFound) + { + DiskEntry->BiosDiskNumber = BiosDiskEntry->DiskNumber; + DiskEntry->BiosFound = TRUE; + BiosDiskEntry->Recognized = TRUE; + } + else + { + } + } + ListEntry = ListEntry->Flink; } - ListEntry = ListEntry->Flink; - } - if (!DiskEntry->BiosFound) - { + if (!DiskEntry->BiosFound) + { #if 0 - RtlFreeHeap(ProcessHeap, 0, DiskEntry); - return; + RtlFreeHeap(ProcessHeap, 0, DiskEntry); + return; #else - DPRINT1("WARNING: Setup could not find a matching BIOS disk entry. Disk %d is not be bootable by the BIOS!\n", DiskNumber); + DPRINT1("WARNING: Setup could not find a matching BIOS disk entry. Disk %d is not be bootable by the BIOS!\n", DiskNumber); #endif - } - - InitializeListHead (&DiskEntry->PartListHead); - - DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart; - DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder; - DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack; - DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector; - - DPRINT ("Cylinders %I64u\n", DiskEntry->Cylinders); - DPRINT ("TracksPerCylinder %I64u\n", DiskEntry->TracksPerCylinder); - DPRINT ("SectorsPerTrack %I64u\n", DiskEntry->SectorsPerTrack); - DPRINT ("BytesPerSector %I64u\n", DiskEntry->BytesPerSector); - - DiskEntry->TrackSize = - (ULONGLONG)DiskGeometry.SectorsPerTrack * - (ULONGLONG)DiskGeometry.BytesPerSector; - DiskEntry->CylinderSize = - (ULONGLONG)DiskGeometry.TracksPerCylinder * - DiskEntry->TrackSize; - DiskEntry->DiskSize = - DiskGeometry.Cylinders.QuadPart * - DiskEntry->CylinderSize; - - DiskEntry->DiskNumber = DiskNumber; - DiskEntry->Port = ScsiAddress.PortNumber; - DiskEntry->Bus = ScsiAddress.PathId; - DiskEntry->Id = ScsiAddress.TargetId; - - GetDriverName (DiskEntry); - - InsertAscendingList(&List->DiskListHead, DiskEntry, DISKENTRY, ListEntry, DiskNumber); - - /* - * Allocate a buffer for 26 logical drives (2 entries each == 52) - * plus the main partiton table (4 entries). Total 56 entries. - */ - LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) + - ((56 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION)); - LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap (ProcessHeap, - 0, - LayoutBufferSize); - if (LayoutBuffer == NULL) - { - return; - } - - Status = NtDeviceIoControlFile (FileHandle, - NULL, - NULL, - NULL, - &Iosb, - IOCTL_DISK_GET_DRIVE_LAYOUT, - NULL, - 0, - LayoutBuffer, - LayoutBufferSize); - if (NT_SUCCESS (Status)) - { - if (LayoutBuffer->PartitionCount == 0) - { - DiskEntry->NewDisk = TRUE; } - AddPartitionToList (DiskNumber, - DiskEntry, - LayoutBuffer); + InitializeListHead(&DiskEntry->PartListHead); - ScanForUnpartitionedDiskSpace (DiskEntry); - } + DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart; + DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder; + DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack; + DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector; - RtlFreeHeap (ProcessHeap, - 0, - LayoutBuffer); + DPRINT ("Cylinders %I64u\n", DiskEntry->Cylinders); + DPRINT ("TracksPerCylinder %I64u\n", DiskEntry->TracksPerCylinder); + DPRINT ("SectorsPerTrack %I64u\n", DiskEntry->SectorsPerTrack); + DPRINT ("BytesPerSector %I64u\n", DiskEntry->BytesPerSector); + + DiskEntry->TrackSize = + (ULONGLONG)DiskGeometry.SectorsPerTrack * + (ULONGLONG)DiskGeometry.BytesPerSector; + DiskEntry->CylinderSize = + (ULONGLONG)DiskGeometry.TracksPerCylinder * + DiskEntry->TrackSize; + DiskEntry->DiskSize = + DiskGeometry.Cylinders.QuadPart * + DiskEntry->CylinderSize; + + DiskEntry->DiskNumber = DiskNumber; + DiskEntry->Port = ScsiAddress.PortNumber; + DiskEntry->Bus = ScsiAddress.PathId; + DiskEntry->Id = ScsiAddress.TargetId; + + GetDriverName(DiskEntry); + + InsertAscendingList(&List->DiskListHead, DiskEntry, DISKENTRY, ListEntry, DiskNumber); + + /* + * Allocate a buffer for 26 logical drives (2 entries each == 52) + * plus the main partiton table (4 entries). Total 56 entries. + */ + LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) + + ((56 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION)); + LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap(ProcessHeap, + 0, + LayoutBufferSize); + if (LayoutBuffer == NULL) + { + return; + } + + Status = NtDeviceIoControlFile(FileHandle, + NULL, + NULL, + NULL, + &Iosb, + IOCTL_DISK_GET_DRIVE_LAYOUT, + NULL, + 0, + LayoutBuffer, + LayoutBufferSize); + if (NT_SUCCESS(Status)) + { + if (LayoutBuffer->PartitionCount == 0) + { + DiskEntry->NewDisk = TRUE; + } + + AddPartitionToList(DiskNumber, + DiskEntry, + LayoutBuffer); + + ScanForUnpartitionedDiskSpace(DiskEntry); + } + + RtlFreeHeap(ProcessHeap, + 0, + LayoutBuffer); } PPARTLIST -CreatePartitionList (SHORT Left, - SHORT Top, - SHORT Right, - SHORT Bottom) +CreatePartitionList( + SHORT Left, + SHORT Top, + SHORT Right, + SHORT Bottom) { - PPARTLIST List; - OBJECT_ATTRIBUTES ObjectAttributes; - SYSTEM_DEVICE_INFORMATION Sdi; - IO_STATUS_BLOCK Iosb; - ULONG ReturnSize; - NTSTATUS Status; - ULONG DiskNumber; - WCHAR Buffer[MAX_PATH]; - UNICODE_STRING Name; - HANDLE FileHandle; + PPARTLIST List; + OBJECT_ATTRIBUTES ObjectAttributes; + SYSTEM_DEVICE_INFORMATION Sdi; + IO_STATUS_BLOCK Iosb; + ULONG ReturnSize; + NTSTATUS Status; + ULONG DiskNumber; + WCHAR Buffer[MAX_PATH]; + UNICODE_STRING Name; + HANDLE FileHandle; - List = (PPARTLIST)RtlAllocateHeap (ProcessHeap, - 0, - sizeof (PARTLIST)); - if (List == NULL) - return NULL; + List = (PPARTLIST)RtlAllocateHeap(ProcessHeap, + 0, + sizeof (PARTLIST)); + if (List == NULL) + return NULL; - List->Left = Left; - List->Top = Top; - List->Right = Right; - List->Bottom = Bottom; + List->Left = Left; + List->Top = Top; + List->Right = Right; + List->Bottom = Bottom; - List->Line = 0; - List->Offset = 0; + List->Line = 0; + List->Offset = 0; - List->TopDisk = (ULONG)-1; - List->TopPartition = (ULONG)-1; + List->TopDisk = (ULONG)-1; + List->TopPartition = (ULONG)-1; - List->CurrentDisk = NULL; - List->CurrentPartition = NULL; - List->CurrentPartitionNumber = 0; - - InitializeListHead (&List->DiskListHead); - InitializeListHead (&List->BiosDiskListHead); - - EnumerateBiosDiskEntries(List); - - Status = NtQuerySystemInformation (SystemDeviceInformation, - &Sdi, - sizeof(SYSTEM_DEVICE_INFORMATION), - &ReturnSize); - if (!NT_SUCCESS (Status)) - { - RtlFreeHeap (ProcessHeap, 0, List); - return NULL; - } - - for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++) - { - swprintf (Buffer, - L"\\Device\\Harddisk%d\\Partition0", - DiskNumber); - RtlInitUnicodeString (&Name, - Buffer); - - InitializeObjectAttributes (&ObjectAttributes, - &Name, - 0, - NULL, - NULL); - - Status = NtOpenFile (&FileHandle, - FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE, - &ObjectAttributes, - &Iosb, - FILE_SHARE_READ, - FILE_SYNCHRONOUS_IO_NONALERT); - if (NT_SUCCESS(Status)) - { - AddDiskToList (FileHandle, - DiskNumber, - List); - - NtClose(FileHandle); - } - } - - AssignDriverLetters (List); - - List->TopDisk = 0; - List->TopPartition = 0; - - /* Search for first usable disk and partition */ - if (IsListEmpty (&List->DiskListHead)) - { List->CurrentDisk = NULL; List->CurrentPartition = NULL; List->CurrentPartitionNumber = 0; - } - else - { - List->CurrentDisk = - CONTAINING_RECORD (List->DiskListHead.Flink, - DISKENTRY, - ListEntry); - if (IsListEmpty (&List->CurrentDisk->PartListHead)) + InitializeListHead(&List->DiskListHead); + InitializeListHead(&List->BiosDiskListHead); + + EnumerateBiosDiskEntries(List); + + Status = NtQuerySystemInformation(SystemDeviceInformation, + &Sdi, + sizeof(SYSTEM_DEVICE_INFORMATION), + &ReturnSize); + if (!NT_SUCCESS(Status)) { - List->CurrentPartition = 0; - List->CurrentPartitionNumber = 0; + RtlFreeHeap(ProcessHeap, 0, List); + return NULL; + } + + for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++) + { + swprintf(Buffer, + L"\\Device\\Harddisk%d\\Partition0", + DiskNumber); + RtlInitUnicodeString(&Name, + Buffer); + + InitializeObjectAttributes(&ObjectAttributes, + &Name, + 0, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE, + &ObjectAttributes, + &Iosb, + FILE_SHARE_READ, + FILE_SYNCHRONOUS_IO_NONALERT); + if (NT_SUCCESS(Status)) + { + AddDiskToList(FileHandle, + DiskNumber, + List); + + NtClose(FileHandle); + } + } + + AssignDriverLetters(List); + + List->TopDisk = 0; + List->TopPartition = 0; + + /* Search for first usable disk and partition */ + if (IsListEmpty(&List->DiskListHead)) + { + List->CurrentDisk = NULL; + List->CurrentPartition = NULL; + List->CurrentPartitionNumber = 0; } else { - List->CurrentPartition = - CONTAINING_RECORD (List->CurrentDisk->PartListHead.Flink, - PARTENTRY, - ListEntry); - List->CurrentPartitionNumber = 0; - } - } + List->CurrentDisk = CONTAINING_RECORD(List->DiskListHead.Flink, + DISKENTRY, + ListEntry); - return List; + if (IsListEmpty(&List->CurrentDisk->PartListHead)) + { + List->CurrentPartition = 0; + List->CurrentPartitionNumber = 0; + } + else + { + List->CurrentPartition = CONTAINING_RECORD(List->CurrentDisk->PartListHead.Flink, + PARTENTRY, + ListEntry); + List->CurrentPartitionNumber = 0; + } + } + + return List; } VOID -DestroyPartitionList (PPARTLIST List) +DestroyPartitionList( + PPARTLIST List) { - PDISKENTRY DiskEntry; - PBIOSDISKENTRY BiosDiskEntry; - PPARTENTRY PartEntry; - PLIST_ENTRY Entry; + PDISKENTRY DiskEntry; + PBIOSDISKENTRY BiosDiskEntry; + PPARTENTRY PartEntry; + PLIST_ENTRY Entry; - /* Release disk and partition info */ - while (!IsListEmpty (&List->DiskListHead)) - { - Entry = RemoveHeadList (&List->DiskListHead); - DiskEntry = CONTAINING_RECORD (Entry, DISKENTRY, ListEntry); - - /* Release driver name */ - RtlFreeUnicodeString(&DiskEntry->DriverName); - - /* Release partition array */ - while (!IsListEmpty (&DiskEntry->PartListHead)) + /* Release disk and partition info */ + while (!IsListEmpty(&List->DiskListHead)) { - Entry = RemoveHeadList (&DiskEntry->PartListHead); - PartEntry = CONTAINING_RECORD (Entry, PARTENTRY, ListEntry); + Entry = RemoveHeadList(&List->DiskListHead); + DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry); - RtlFreeHeap (ProcessHeap, - 0, - PartEntry); + /* Release driver name */ + RtlFreeUnicodeString(&DiskEntry->DriverName); + + /* Release partition array */ + while (!IsListEmpty(&DiskEntry->PartListHead)) + { + Entry = RemoveHeadList(&DiskEntry->PartListHead); + PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); + + RtlFreeHeap(ProcessHeap, + 0, + PartEntry); + } + + /* Release disk entry */ + RtlFreeHeap(ProcessHeap, 0, DiskEntry); } - /* Release disk entry */ - RtlFreeHeap (ProcessHeap, 0, DiskEntry); - } - - /* release the bios disk info */ - while(!IsListEmpty(&List->BiosDiskListHead)) - { - Entry = RemoveHeadList(&List->BiosDiskListHead); - BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry); - - RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry); - } - - /* Release list head */ - RtlFreeHeap (ProcessHeap, 0, List); -} - - -static VOID -PrintEmptyLine (PPARTLIST List) -{ - COORD coPos; - DWORD Written; - USHORT Width; - USHORT Height; - - Width = List->Right - List->Left - 1; - Height = List->Bottom - List->Top - 2; - - - coPos.X = List->Left + 1; - coPos.Y = List->Top + 1 + List->Line; - - if (List->Line >= 0 && List->Line <= Height) - { - FillConsoleOutputAttribute (StdOutput, - FOREGROUND_WHITE | BACKGROUND_BLUE, - Width, - coPos, - &Written); - - FillConsoleOutputCharacterA (StdOutput, - ' ', - Width, - coPos, - &Written); - } - List->Line++; -} - - -static VOID -PrintPartitionData (PPARTLIST List, - PDISKENTRY DiskEntry, - PPARTENTRY PartEntry, - ULONG PartNumber) -{ - CHAR LineBuffer[128]; - COORD coPos; - DWORD Written; - USHORT Width; - USHORT Height; - - LARGE_INTEGER PartSize; - PCHAR Unit; - UCHAR Attribute; - PCHAR PartType; - - Width = List->Right - List->Left - 1; - Height = List->Bottom - List->Top - 2; - - - coPos.X = List->Left + 1; - coPos.Y = List->Top + 1 + List->Line; - - if (PartEntry->Unpartitioned == TRUE) - { -#if 0 - if (PartEntry->UnpartitionledLength >= 0x280000000ULL) /* 10 GB */ + /* release the bios disk info */ + while(!IsListEmpty(&List->BiosDiskListHead)) { - PartSize.QuadPart = (PartEntry->UnpartitionedLength + (1 << 29)) >> 30; - Unit = MUIGetString(STRING_GB); + Entry = RemoveHeadList(&List->BiosDiskListHead); + BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry); + + RtlFreeHeap(ProcessHeap, 0, BiosDiskEntry); + } + + /* Release list head */ + RtlFreeHeap(ProcessHeap, 0, List); +} + + +static +VOID +PrintEmptyLine( + PPARTLIST List) +{ + COORD coPos; + DWORD Written; + USHORT Width; + USHORT Height; + + Width = List->Right - List->Left - 1; + Height = List->Bottom - List->Top - 2; + + coPos.X = List->Left + 1; + coPos.Y = List->Top + 1 + List->Line; + + if (List->Line >= 0 && List->Line <= Height) + { + FillConsoleOutputAttribute(StdOutput, + FOREGROUND_WHITE | BACKGROUND_BLUE, + Width, + coPos, + &Written); + + FillConsoleOutputCharacterA(StdOutput, + ' ', + Width, + coPos, + &Written); + } + + List->Line++; +} + + +static +VOID +PrintPartitionData( + PPARTLIST List, + PDISKENTRY DiskEntry, + PPARTENTRY PartEntry, + ULONG PartNumber) +{ + CHAR LineBuffer[128]; + COORD coPos; + DWORD Written; + USHORT Width; + USHORT Height; + LARGE_INTEGER PartSize; + PCHAR Unit; + UCHAR Attribute; + PCHAR PartType; + + Width = List->Right - List->Left - 1; + Height = List->Bottom - List->Top - 2; + + coPos.X = List->Left + 1; + coPos.Y = List->Top + 1 + List->Line; + + if (PartEntry->Unpartitioned == TRUE) + { +#if 0 + if (PartEntry->UnpartitionledLength >= 0x280000000ULL) /* 10 GB */ + { + PartSize.QuadPart = (PartEntry->UnpartitionedLength + (1 << 29)) >> 30; + Unit = MUIGetString(STRING_GB); + } + else +#endif + if (PartEntry->UnpartitionedLength >= 0xA00000ULL) /* 10 MB */ + { + PartSize.QuadPart = (PartEntry->UnpartitionedLength + (1 << 19)) >> 20; + Unit = MUIGetString(STRING_MB); + } + else + { + PartSize.QuadPart = (PartEntry->UnpartitionedLength + (1 << 9)) >> 10; + Unit = MUIGetString(STRING_KB); + } + + sprintf(LineBuffer, + MUIGetString(STRING_UNPSPACE), + PartSize.u.LowPart, + Unit); + } + else + { + /* Determine partition type */ + PartType = NULL; + if (PartEntry->New == TRUE) + { + PartType = MUIGetString(STRING_UNFORMATTED); + } + else if (PartEntry->Unpartitioned == FALSE) + { + if ((PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT_12) || + (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT_16) || + (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_HUGE) || + (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_XINT13)) + { + PartType = "FAT"; + } + else if ((PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT32) || + (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT32_XINT13)) + { + PartType = "FAT32"; + } + else if (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_EXT2) + { + PartType = "EXT2"; + } + else if (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_IFS) + { + PartType = "NTFS"; /* FIXME: Not quite correct! */ + } + } + +#if 0 + if (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart >= 0x280000000LL) /* 10 GB */ + { + PartSize.QuadPart = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 29)) >> 30; + Unit = MUIGetString(STRING_GB); + } + else +#endif + if (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart >= 0xA00000LL) /* 10 MB */ + { + PartSize.QuadPart = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 19)) >> 20; + Unit = MUIGetString(STRING_MB); + } + else + { + PartSize.QuadPart = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 9)) >> 10; + Unit = MUIGetString(STRING_KB); + } + + if (PartType == NULL) + { + sprintf(LineBuffer, + MUIGetString(STRING_HDDINFOUNK5), + (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : PartEntry->DriveLetter[PartNumber], + (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : ':', + PartEntry->PartInfo[PartNumber].PartitionType, + PartSize.u.LowPart, + Unit); + } + else + { + sprintf(LineBuffer, + "%c%c %-24s %6lu %s", + (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : PartEntry->DriveLetter[PartNumber], + (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : ':', + PartType, + PartSize.u.LowPart, + Unit); + } + } + + Attribute = (List->CurrentDisk == DiskEntry && + List->CurrentPartition == PartEntry && + List->CurrentPartitionNumber == PartNumber) ? + FOREGROUND_BLUE | BACKGROUND_WHITE : + FOREGROUND_WHITE | BACKGROUND_BLUE; + + if (List->Line >= 0 && List->Line <= Height) + { + FillConsoleOutputCharacterA(StdOutput, + ' ', + Width, + coPos, + &Written); + } + coPos.X += 4; + Width -= 8; + if (List->Line >= 0 && List->Line <= Height) + { + FillConsoleOutputAttribute(StdOutput, + Attribute, + Width, + coPos, + &Written); + } + coPos.X++; + Width -= 2; + if (List->Line >= 0 && List->Line <= Height) + { + WriteConsoleOutputCharacterA(StdOutput, + LineBuffer, + min(strlen(LineBuffer), Width), + coPos, + &Written); + } + + List->Line++; +} + + +static +VOID +PrintDiskData( + PPARTLIST List, + PDISKENTRY DiskEntry) +{ + PPARTENTRY PartEntry; + PLIST_ENTRY Entry; + CHAR LineBuffer[128]; + COORD coPos; + DWORD Written; + USHORT Width; + USHORT Height; + ULARGE_INTEGER DiskSize; + PCHAR Unit; + ULONG i; + + Width = List->Right - List->Left - 1; + Height = List->Bottom - List->Top - 2; + + coPos.X = List->Left + 1; + coPos.Y = List->Top + 1 + List->Line; + +#if 0 + if (DiskEntry->DiskSize >= 0x280000000ULL) /* 10 GB */ + { + DiskSize.QuadPart = (DiskEntry->DiskSize + (1 << 29)) >> 30; + Unit = MUIGetString(STRING_GB); } else #endif - if (PartEntry->UnpartitionedLength >= 0xA00000ULL) /* 10 MB */ - { - PartSize.QuadPart = (PartEntry->UnpartitionedLength + (1 << 19)) >> 20; + { + DiskSize.QuadPart = (DiskEntry->DiskSize + (1 << 19)) >> 20; + if (DiskSize.QuadPart == 0) + DiskSize.QuadPart = 1; Unit = MUIGetString(STRING_MB); - } - else - { - PartSize.QuadPart = (PartEntry->UnpartitionedLength + (1 << 9)) >> 10; - Unit = MUIGetString(STRING_KB); - } - - sprintf (LineBuffer, - MUIGetString(STRING_UNPSPACE), - PartSize.u.LowPart, - Unit); - } - else - { - /* Determine partition type */ - PartType = NULL; - if (PartEntry->New == TRUE) - { - PartType = MUIGetString(STRING_UNFORMATTED); - } - else if (PartEntry->Unpartitioned == FALSE) - { - if ((PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT_12) || - (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT_16) || - (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_HUGE) || - (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_XINT13)) - { - PartType = "FAT"; - } - else if ((PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT32) || - (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_FAT32_XINT13)) - { - PartType = "FAT32"; - } - else if (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_EXT2) - { - PartType = "EXT2"; - } - else if (PartEntry->PartInfo[PartNumber].PartitionType == PARTITION_IFS) - { - PartType = "NTFS"; /* FIXME: Not quite correct! */ - } } -#if 0 - if (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart >= 0x280000000LL) /* 10 GB */ + if (DiskEntry->DriverName.Length > 0) { - PartSize.QuadPart = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 29)) >> 30; - Unit = MUIGetString(STRING_GB); - } - else -#endif - if (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart >= 0xA00000LL) /* 10 MB */ - { - PartSize.QuadPart = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 19)) >> 20; - Unit = MUIGetString(STRING_MB); + sprintf(LineBuffer, + MUIGetString(STRING_HDINFOPARTSELECT), + DiskSize.u.LowPart, + Unit, + DiskEntry->DiskNumber, + DiskEntry->Port, + DiskEntry->Bus, + DiskEntry->Id, + DiskEntry->DriverName.Buffer); } else { - PartSize.QuadPart = (PartEntry->PartInfo[PartNumber].PartitionLength.QuadPart + (1 << 9)) >> 10; - Unit = MUIGetString(STRING_KB); + sprintf(LineBuffer, + MUIGetString(STRING_HDDINFOUNK6), + DiskSize.u.LowPart, + Unit, + DiskEntry->DiskNumber, + DiskEntry->Port, + DiskEntry->Bus, + DiskEntry->Id); } - if (PartType == NULL) + if (List->Line >= 0 && List->Line <= Height) { - sprintf (LineBuffer, - MUIGetString(STRING_HDDINFOUNK5), - (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : PartEntry->DriveLetter[PartNumber], - (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : ':', - PartEntry->PartInfo[PartNumber].PartitionType, - PartSize.u.LowPart, - Unit); + FillConsoleOutputAttribute(StdOutput, + FOREGROUND_WHITE | BACKGROUND_BLUE, + Width, + coPos, + &Written); + + FillConsoleOutputCharacterA(StdOutput, + ' ', + Width, + coPos, + &Written); } - else + + coPos.X++; + if (List->Line >= 0 && List->Line <= Height) { - sprintf (LineBuffer, - "%c%c %-24s %6lu %s", - (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : PartEntry->DriveLetter[PartNumber], - (PartEntry->DriveLetter[PartNumber] == 0) ? '-' : ':', - PartType, - PartSize.u.LowPart, - Unit); + WriteConsoleOutputCharacterA(StdOutput, + LineBuffer, + min((USHORT)strlen(LineBuffer), Width - 2), + coPos, + &Written); } - } - Attribute = (List->CurrentDisk == DiskEntry && - List->CurrentPartition == PartEntry && - List->CurrentPartitionNumber == PartNumber) ? - FOREGROUND_BLUE | BACKGROUND_WHITE : - FOREGROUND_WHITE | BACKGROUND_BLUE; + List->Line++; - if (List->Line >= 0 && List->Line <= Height) - { - FillConsoleOutputCharacterA (StdOutput, - ' ', - Width, - coPos, - &Written); - } - coPos.X += 4; - Width -= 8; - if (List->Line >= 0 && List->Line <= Height) - { - FillConsoleOutputAttribute (StdOutput, - Attribute, - Width, - coPos, - &Written); - } - coPos.X++; - Width -= 2; - if (List->Line >= 0 && List->Line <= Height) - { - WriteConsoleOutputCharacterA (StdOutput, - LineBuffer, - min (strlen (LineBuffer), Width), - coPos, - &Written); - } - List->Line++; -} + /* Print separator line */ + PrintEmptyLine(List); - -static VOID -PrintDiskData (PPARTLIST List, - PDISKENTRY DiskEntry) -{ - PPARTENTRY PartEntry; - PLIST_ENTRY Entry; - CHAR LineBuffer[128]; - COORD coPos; - DWORD Written; - USHORT Width; - USHORT Height; - ULARGE_INTEGER DiskSize; - PCHAR Unit; - ULONG i; - - Width = List->Right - List->Left - 1; - Height = List->Bottom - List->Top - 2; - - - coPos.X = List->Left + 1; - coPos.Y = List->Top + 1 + List->Line; - -#if 0 - if (DiskEntry->DiskSize >= 0x280000000ULL) /* 10 GB */ - { - DiskSize.QuadPart = (DiskEntry->DiskSize + (1 << 29)) >> 30; - Unit = MUIGetString(STRING_GB); - } - else -#endif - { - DiskSize.QuadPart = (DiskEntry->DiskSize + (1 << 19)) >> 20; - if (DiskSize.QuadPart == 0) - DiskSize.QuadPart = 1; - Unit = MUIGetString(STRING_MB); - } - - if (DiskEntry->DriverName.Length > 0) - { - sprintf (LineBuffer, - MUIGetString(STRING_HDINFOPARTSELECT), - DiskSize.u.LowPart, - Unit, - DiskEntry->DiskNumber, - DiskEntry->Port, - DiskEntry->Bus, - DiskEntry->Id, - DiskEntry->DriverName.Buffer); - } - else - { - sprintf (LineBuffer, - MUIGetString(STRING_HDDINFOUNK6), - DiskSize.u.LowPart, - Unit, - DiskEntry->DiskNumber, - DiskEntry->Port, - DiskEntry->Bus, - DiskEntry->Id); - } - if (List->Line >= 0 && List->Line <= Height) - { - FillConsoleOutputAttribute (StdOutput, - FOREGROUND_WHITE | BACKGROUND_BLUE, - Width, - coPos, - &Written); - - FillConsoleOutputCharacterA (StdOutput, - ' ', - Width, - coPos, - &Written); - } - - coPos.X++; - if (List->Line >= 0 && List->Line <= Height) - { - WriteConsoleOutputCharacterA (StdOutput, - LineBuffer, - min ((USHORT)strlen (LineBuffer), Width - 2), - coPos, - &Written); - } - List->Line++; - - /* Print separator line */ - PrintEmptyLine (List); - - /* Print partition lines*/ - Entry = DiskEntry->PartListHead.Flink; - while (Entry != &DiskEntry->PartListHead) - { - PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); - - /* Print disk entry */ - for (i=0; i<4; i++) + /* Print partition lines*/ + Entry = DiskEntry->PartListHead.Flink; + while (Entry != &DiskEntry->PartListHead) { - if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED || - PartEntry->PartInfo[i].PartitionLength.QuadPart != 0ULL) - { - PrintPartitionData (List, - DiskEntry, - PartEntry, - i); - } + PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry); + + /* Print disk entry */ + for (i = 0; i < 4; i++) + { + if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED || + PartEntry->PartInfo[i].PartitionLength.QuadPart != 0ULL) + { + PrintPartitionData(List, + DiskEntry, + PartEntry, + i); + } + } + + /* Print unpartitioned entry */ + if (PartEntry->Unpartitioned) + { + PrintPartitionData(List, + DiskEntry, + PartEntry, + 0); + } + + Entry = Entry->Flink; } - /* Print unpartitioned entry */ - if (PartEntry->Unpartitioned) - { - PrintPartitionData (List, - DiskEntry, - PartEntry, - 0); - } - - Entry = Entry->Flink; - } - - /* Print separator line */ - PrintEmptyLine (List); + /* Print separator line */ + PrintEmptyLine(List); } VOID -DrawPartitionList (PPARTLIST List) +DrawPartitionList( + PPARTLIST List) { - PLIST_ENTRY Entry, Entry2; - PDISKENTRY DiskEntry; - PPARTENTRY PartEntry = NULL; - COORD coPos; - DWORD Written; - SHORT i; - SHORT CurrentDiskLine; - SHORT CurrentPartLine; - SHORT LastLine; - BOOL CurrentPartLineFound = FALSE; - BOOL CurrentDiskLineFound = FALSE; + PLIST_ENTRY Entry, Entry2; + PDISKENTRY DiskEntry; + PPARTENTRY PartEntry = NULL; + COORD coPos; + DWORD Written; + SHORT i; + SHORT CurrentDiskLine; + SHORT CurrentPartLine; + SHORT LastLine; + BOOL CurrentPartLineFound = FALSE; + BOOL CurrentDiskLineFound = FALSE; - /* Calculate the line of the current disk and partition */ - CurrentDiskLine = 0; - CurrentPartLine = 0; - LastLine = 0; - Entry = List->DiskListHead.Flink; - while (Entry != &List->DiskListHead) - { - DiskEntry = CONTAINING_RECORD (Entry, DISKENTRY, ListEntry); - LastLine += 2; - if (CurrentPartLineFound == FALSE) + /* Calculate the line of the current disk and partition */ + CurrentDiskLine = 0; + CurrentPartLine = 0; + LastLine = 0; + + Entry = List->DiskListHead.Flink; + while (Entry != &List->DiskListHead) { - CurrentPartLine += 2; + DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry); + + LastLine += 2; + if (CurrentPartLineFound == FALSE) + { + CurrentPartLine += 2; + } + + Entry2 = DiskEntry->PartListHead.Flink; + while (Entry2 != &DiskEntry->PartListHead) + { + PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); + if (PartEntry == List->CurrentPartition) + { + CurrentPartLineFound = TRUE; + } + + Entry2 = Entry2->Flink; + if (CurrentPartLineFound == FALSE) + { + CurrentPartLine++; + } + + LastLine++; + } + + if (DiskEntry == List->CurrentDisk) + { + CurrentDiskLineFound = TRUE; + } + + Entry = Entry->Flink; + if (Entry != &List->DiskListHead) + { + if (CurrentDiskLineFound == FALSE) + { + CurrentPartLine ++; + CurrentDiskLine = CurrentPartLine; + } + + LastLine++; + } + else + { + LastLine--; + } } - Entry2 = DiskEntry->PartListHead.Flink; - while (Entry2 != &DiskEntry->PartListHead) + + /* If it possible, make the disk name visible */ + if (CurrentPartLine < List->Offset) { - PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry); - if (PartEntry == List->CurrentPartition) - { - CurrentPartLineFound = TRUE; - } - Entry2 = Entry2->Flink; - if (CurrentPartLineFound == FALSE) - { - CurrentPartLine++; - } - LastLine++; + List->Offset = CurrentPartLine; } - if (DiskEntry == List->CurrentDisk) + else if (CurrentPartLine - List->Offset > List->Bottom - List->Top - 2) { - CurrentDiskLineFound = TRUE; + List->Offset = CurrentPartLine - (List->Bottom - List->Top - 2); } - Entry = Entry->Flink; - if (Entry != &List->DiskListHead) + + if (CurrentDiskLine < List->Offset && CurrentPartLine - CurrentDiskLine < List->Bottom - List->Top - 2) { - if (CurrentDiskLineFound == FALSE) - { - CurrentPartLine ++; - CurrentDiskLine = CurrentPartLine; - } - LastLine++; + List->Offset = CurrentDiskLine; + } + + /* draw upper left corner */ + coPos.X = List->Left; + coPos.Y = List->Top; + FillConsoleOutputCharacterA(StdOutput, + 0xDA, // '+', + 1, + coPos, + &Written); + + /* draw upper edge */ + coPos.X = List->Left + 1; + coPos.Y = List->Top; + if (List->Offset == 0) + { + FillConsoleOutputCharacterA(StdOutput, + 0xC4, // '-', + List->Right - List->Left - 1, + coPos, + &Written); } else { - LastLine--; + FillConsoleOutputCharacterA(StdOutput, + 0xC4, // '-', + List->Right - List->Left - 5, + coPos, + &Written); + coPos.X = List->Right - 5; + WriteConsoleOutputCharacterA(StdOutput, + "(\x18)", // "(up)" + 3, + coPos, + &Written); + coPos.X = List->Right - 2; + FillConsoleOutputCharacterA(StdOutput, + 0xC4, // '-', + 2, + coPos, + &Written); } - } - - /* If it possible, make the disk name visible */ - if (CurrentPartLine < List->Offset) - { - List->Offset = CurrentPartLine; - } - else if (CurrentPartLine - List->Offset > List->Bottom - List->Top - 2) - { - List->Offset = CurrentPartLine - (List->Bottom - List->Top - 2); - } - if (CurrentDiskLine < List->Offset && CurrentPartLine - CurrentDiskLine < List->Bottom - List->Top - 2) - { - List->Offset = CurrentDiskLine; - } - - - /* draw upper left corner */ - coPos.X = List->Left; - coPos.Y = List->Top; - FillConsoleOutputCharacterA (StdOutput, - 0xDA, // '+', - 1, - coPos, - &Written); - - /* draw upper edge */ - coPos.X = List->Left + 1; - coPos.Y = List->Top; - if (List->Offset == 0) - { - FillConsoleOutputCharacterA (StdOutput, - 0xC4, // '-', - List->Right - List->Left - 1, - coPos, - &Written); - } - else - { - FillConsoleOutputCharacterA (StdOutput, - 0xC4, // '-', - List->Right - List->Left - 5, - coPos, - &Written); - coPos.X = List->Right - 5; - WriteConsoleOutputCharacterA (StdOutput, - "(\x18)", // "(up)" - 3, - coPos, - &Written); - coPos.X = List->Right - 2; - FillConsoleOutputCharacterA (StdOutput, - 0xC4, // '-', - 2, - coPos, - &Written); - } - - /* draw upper right corner */ - coPos.X = List->Right; - coPos.Y = List->Top; - FillConsoleOutputCharacterA (StdOutput, - 0xBF, // '+', - 1, - coPos, - &Written); - - /* draw left and right edge */ - for (i = List->Top + 1; i < List->Bottom; i++) - { - coPos.X = List->Left; - coPos.Y = i; - FillConsoleOutputCharacterA (StdOutput, - 0xB3, // '|', - 1, - coPos, - &Written); + /* draw upper right corner */ coPos.X = List->Right; - FillConsoleOutputCharacterA (StdOutput, - 0xB3, //'|', - 1, - coPos, - &Written); - } + coPos.Y = List->Top; + FillConsoleOutputCharacterA(StdOutput, + 0xBF, // '+', + 1, + coPos, + &Written); - /* draw lower left corner */ - coPos.X = List->Left; - coPos.Y = List->Bottom; - FillConsoleOutputCharacterA (StdOutput, - 0xC0, // '+', - 1, - coPos, - &Written); + /* draw left and right edge */ + for (i = List->Top + 1; i < List->Bottom; i++) + { + coPos.X = List->Left; + coPos.Y = i; + FillConsoleOutputCharacterA(StdOutput, + 0xB3, // '|', + 1, + coPos, + &Written); - /* draw lower edge */ - coPos.X = List->Left + 1; - coPos.Y = List->Bottom; - if (LastLine - List->Offset <= List->Bottom - List->Top - 2) - { - FillConsoleOutputCharacterA (StdOutput, - 0xC4, // '-', - List->Right - List->Left - 1, - coPos, - &Written); - } - else - { - FillConsoleOutputCharacterA (StdOutput, - 0xC4, // '-', - List->Right - List->Left - 5, - coPos, - &Written); - coPos.X = List->Right - 5; - WriteConsoleOutputCharacterA (StdOutput, - "(\x19)", // "(down)" - 3, - coPos, - &Written); - coPos.X = List->Right - 2; - FillConsoleOutputCharacterA (StdOutput, - 0xC4, // '-', - 2, - coPos, - &Written); - } + coPos.X = List->Right; + FillConsoleOutputCharacterA(StdOutput, + 0xB3, //'|', + 1, + coPos, + &Written); + } - /* draw lower right corner */ - coPos.X = List->Right; - coPos.Y = List->Bottom; - FillConsoleOutputCharacterA (StdOutput, - 0xD9, // '+', - 1, - coPos, - &Written); + /* draw lower left corner */ + coPos.X = List->Left; + coPos.Y = List->Bottom; + FillConsoleOutputCharacterA(StdOutput, + 0xC0, // '+', + 1, + coPos, + &Written); - /* print list entries */ - List->Line = - List->Offset; + /* draw lower edge */ + coPos.X = List->Left + 1; + coPos.Y = List->Bottom; + if (LastLine - List->Offset <= List->Bottom - List->Top - 2) + { + FillConsoleOutputCharacterA(StdOutput, + 0xC4, // '-', + List->Right - List->Left - 1, + coPos, + &Written); + } + else + { + FillConsoleOutputCharacterA(StdOutput, + 0xC4, // '-', + List->Right - List->Left - 5, + coPos, + &Written); + coPos.X = List->Right - 5; + WriteConsoleOutputCharacterA(StdOutput, + "(\x19)", // "(down)" + 3, + coPos, + &Written); + coPos.X = List->Right - 2; + FillConsoleOutputCharacterA(StdOutput, + 0xC4, // '-', + 2, + coPos, + &Written); + } - Entry = List->DiskListHead.Flink; - while (Entry != &List->DiskListHead) - { - DiskEntry = CONTAINING_RECORD (Entry, DISKENTRY, ListEntry); + /* draw lower right corner */ + coPos.X = List->Right; + coPos.Y = List->Bottom; + FillConsoleOutputCharacterA(StdOutput, + 0xD9, // '+', + 1, + coPos, + &Written); - /* Print disk entry */ - PrintDiskData (List, - DiskEntry); + /* print list entries */ + List->Line = - List->Offset; - Entry = Entry->Flink; - } + Entry = List->DiskListHead.Flink; + while (Entry != &List->DiskListHead) + { + DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry); + + /* Print disk entry */ + PrintDiskData(List, + DiskEntry); + + Entry = Entry->Flink; + } } DWORD -SelectPartition(PPARTLIST List, ULONG DiskNumber, ULONG PartitionNumber) +SelectPartition( + PPARTLIST List, + ULONG DiskNumber, + ULONG PartitionNumber) { - PDISKENTRY DiskEntry; - PPARTENTRY PartEntry; - PLIST_ENTRY Entry1; - PLIST_ENTRY Entry2; - UCHAR i; + PDISKENTRY DiskEntry; + PPARTENTRY PartEntry; + PLIST_ENTRY Entry1; + PLIST_ENTRY Entry2; + UCHAR i; - /* Check for empty disks */ - if (IsListEmpty (&List->DiskListHead)) - return FALSE; + /* Check for empty disks */ + if (IsListEmpty(&List->DiskListHead)) + return FALSE; - /* Check for first usable entry on next disk */ - Entry1 = List->CurrentDisk->ListEntry.Flink; - while (Entry1 != &List->DiskListHead) - { - DiskEntry = CONTAINING_RECORD (Entry1, DISKENTRY, ListEntry); - - if (DiskEntry->DiskNumber == DiskNumber) - { - Entry2 = DiskEntry->PartListHead.Flink; - while (Entry2 != &DiskEntry->PartListHead) - { - PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry); - - for (i = 0; i < 4; i++) - { - if (PartEntry->PartInfo[i].PartitionNumber == PartitionNumber) - { - List->CurrentDisk = DiskEntry; - List->CurrentPartition = PartEntry; - List->CurrentPartitionNumber = i; - DrawPartitionList (List); - return TRUE; - } - } - Entry2 = Entry2->Flink; - } - return FALSE; - } - Entry1 = Entry1->Flink; - } - return FALSE; -} - - -VOID -ScrollDownPartitionList (PPARTLIST List) -{ - PDISKENTRY DiskEntry; - PPARTENTRY PartEntry; - PLIST_ENTRY Entry1; - PLIST_ENTRY Entry2; - UCHAR i; - - /* Check for empty disks */ - if (IsListEmpty (&List->DiskListHead)) - return; - - /* Check for next usable entry on current disk */ - if (List->CurrentPartition != NULL) - { - Entry2 = &List->CurrentPartition->ListEntry; - PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry); - - /* Check if we can move inside primary partitions */ - for (i = List->CurrentPartitionNumber + 1; i < 4; i++) - { - if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED) - break; - } - - if (i == 4) - { - /* We're out of partitions in the current partition table. - Try to move to the next one if possible. */ - Entry2 = Entry2->Flink; - } - else - { - /* Just advance to the next partition */ - List->CurrentPartitionNumber = i; - DrawPartitionList (List); - return; - } - - while (Entry2 != &List->CurrentDisk->PartListHead) - { - PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry); - -// if (PartEntry->HidePartEntry == FALSE) - { - List->CurrentPartition = PartEntry; - List->CurrentPartitionNumber = 0; - DrawPartitionList (List); - return; - } - Entry2 = Entry2->Flink; - } - } - - /* Check for first usable entry on next disk */ - if (List->CurrentDisk != NULL) - { + /* Check for first usable entry on next disk */ Entry1 = List->CurrentDisk->ListEntry.Flink; while (Entry1 != &List->DiskListHead) { - DiskEntry = CONTAINING_RECORD (Entry1, DISKENTRY, ListEntry); + DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry); - Entry2 = DiskEntry->PartListHead.Flink; - while (Entry2 != &DiskEntry->PartListHead) - { - PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry); - -// if (PartEntry->HidePartEntry == FALSE) + if (DiskEntry->DiskNumber == DiskNumber) { - List->CurrentDisk = DiskEntry; - List->CurrentPartition = PartEntry; - List->CurrentPartitionNumber = 0; - DrawPartitionList (List); - return; + Entry2 = DiskEntry->PartListHead.Flink; + while (Entry2 != &DiskEntry->PartListHead) + { + PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); + + for (i = 0; i < 4; i++) + { + if (PartEntry->PartInfo[i].PartitionNumber == PartitionNumber) + { + List->CurrentDisk = DiskEntry; + List->CurrentPartition = PartEntry; + List->CurrentPartitionNumber = i; + DrawPartitionList(List); + return TRUE; + } + } + + Entry2 = Entry2->Flink; + } + + return FALSE; } - Entry2 = Entry2->Flink; - } - - Entry1 = Entry1->Flink; + Entry1 = Entry1->Flink; } - } + + return FALSE; } VOID -ScrollUpPartitionList (PPARTLIST List) +ScrollDownPartitionList( + PPARTLIST List) { - PDISKENTRY DiskEntry; - PPARTENTRY PartEntry; - PLIST_ENTRY Entry1; - PLIST_ENTRY Entry2; - UCHAR i; + PDISKENTRY DiskEntry; + PPARTENTRY PartEntry; + PLIST_ENTRY Entry1; + PLIST_ENTRY Entry2; + UCHAR i; - /* Check for empty disks */ - if (IsListEmpty (&List->DiskListHead)) - return; + /* Check for empty disks */ + if (IsListEmpty(&List->DiskListHead)) + return; - /* check for previous usable entry on current disk */ - if (List->CurrentPartition != NULL) - { - Entry2 = &List->CurrentPartition->ListEntry; - PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry); - - /* Check if we can move inside primary partitions */ - if (List->CurrentPartitionNumber > 0) + /* Check for next usable entry on current disk */ + if (List->CurrentPartition != NULL) { - /* Find a previous partition */ - for (i = List->CurrentPartitionNumber - 1; i > 0; i--) + Entry2 = &List->CurrentPartition->ListEntry; + PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); + + /* Check if we can move inside primary partitions */ + for (i = List->CurrentPartitionNumber + 1; i < 4; i++) { if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED) break; } - /* Move to it and return */ - List->CurrentPartitionNumber = i; - DrawPartitionList (List); - return; - } - - /* Move to the previous entry */ - Entry2 = Entry2->Blink; - - while (Entry2 != &List->CurrentDisk->PartListHead) - { - PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry); - -// if (PartEntry->HidePartEntry == FALSE) - { - List->CurrentPartition = PartEntry; - - /* Find last existing partition in the table */ - for (i = 3; i > 0; i--) + if (i == 4) { - if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED) - break; + /* We're out of partitions in the current partition table. + Try to move to the next one if possible. */ + Entry2 = Entry2->Flink; + } + else + { + /* Just advance to the next partition */ + List->CurrentPartitionNumber = i; + DrawPartitionList(List); + return; } - /* Move to it */ - List->CurrentPartitionNumber = i; - - /* Draw partition list and return */ - DrawPartitionList (List); - return; - } - Entry2 = Entry2->Blink; - } - } - - - /* check for last usable entry on previous disk */ - if (List->CurrentDisk != NULL) - { - Entry1 = List->CurrentDisk->ListEntry.Blink; - while (Entry1 != &List->DiskListHead) - { - DiskEntry = CONTAINING_RECORD (Entry1, DISKENTRY, ListEntry); - - Entry2 = DiskEntry->PartListHead.Blink; - while (Entry2 != &DiskEntry->PartListHead) - { - PartEntry = CONTAINING_RECORD (Entry2, PARTENTRY, ListEntry); - -// if (PartEntry->HidePartEntry == FALSE) + while (Entry2 != &List->CurrentDisk->PartListHead) { - List->CurrentDisk = DiskEntry; - List->CurrentPartition = PartEntry; + PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); - /* Find last existing partition in the table */ - for (i = 3; i > 0; i--) - { - if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED) - break; - } +// if (PartEntry->HidePartEntry == FALSE) + { + List->CurrentPartition = PartEntry; + List->CurrentPartitionNumber = 0; + DrawPartitionList(List); + return; + } - /* Move to it */ - List->CurrentPartitionNumber = i; + Entry2 = Entry2->Flink; + } + } - /* Draw partition list and return */ - DrawPartitionList (List); - return; + /* Check for first usable entry on next disk */ + if (List->CurrentDisk != NULL) + { + Entry1 = List->CurrentDisk->ListEntry.Flink; + while (Entry1 != &List->DiskListHead) + { + DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry); + + Entry2 = DiskEntry->PartListHead.Flink; + while (Entry2 != &DiskEntry->PartListHead) + { + PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); + +// if (PartEntry->HidePartEntry == FALSE) + { + List->CurrentDisk = DiskEntry; + List->CurrentPartition = PartEntry; + List->CurrentPartitionNumber = 0; + DrawPartitionList(List); + return; + } + + Entry2 = Entry2->Flink; + } + + Entry1 = Entry1->Flink; + } + } +} + + +VOID +ScrollUpPartitionList( + PPARTLIST List) +{ + PDISKENTRY DiskEntry; + PPARTENTRY PartEntry; + PLIST_ENTRY Entry1; + PLIST_ENTRY Entry2; + UCHAR i; + + /* Check for empty disks */ + if (IsListEmpty(&List->DiskListHead)) + return; + + /* check for previous usable entry on current disk */ + if (List->CurrentPartition != NULL) + { + Entry2 = &List->CurrentPartition->ListEntry; + PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); + + /* Check if we can move inside primary partitions */ + if (List->CurrentPartitionNumber > 0) + { + /* Find a previous partition */ + for (i = List->CurrentPartitionNumber - 1; i > 0; i--) + { + if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED) + break; + } + + /* Move to it and return */ + List->CurrentPartitionNumber = i; + DrawPartitionList(List); + return; } + /* Move to the previous entry */ Entry2 = Entry2->Blink; - } - Entry1 = Entry1->Blink; + while (Entry2 != &List->CurrentDisk->PartListHead) + { + PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); + +// if (PartEntry->HidePartEntry == FALSE) + { + List->CurrentPartition = PartEntry; + + /* Find last existing partition in the table */ + for (i = 3; i > 0; i--) + { + if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED) + break; + } + + /* Move to it */ + List->CurrentPartitionNumber = i; + + /* Draw partition list and return */ + DrawPartitionList(List); + return; + } + + Entry2 = Entry2->Blink; + } + } + + + /* check for last usable entry on previous disk */ + if (List->CurrentDisk != NULL) + { + Entry1 = List->CurrentDisk->ListEntry.Blink; + while (Entry1 != &List->DiskListHead) + { + DiskEntry = CONTAINING_RECORD(Entry1, DISKENTRY, ListEntry); + + Entry2 = DiskEntry->PartListHead.Blink; + while (Entry2 != &DiskEntry->PartListHead) + { + PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); + +// if (PartEntry->HidePartEntry == FALSE) + { + List->CurrentDisk = DiskEntry; + List->CurrentPartition = PartEntry; + + /* Find last existing partition in the table */ + for (i = 3; i > 0; i--) + { + if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED) + break; + } + + /* Move to it */ + List->CurrentPartitionNumber = i; + + /* Draw partition list and return */ + DrawPartitionList(List); + return; + } + + Entry2 = Entry2->Blink; + } + + Entry1 = Entry1->Blink; + } } - } } -static PPARTENTRY -GetPrevPartitionedEntry (PDISKENTRY DiskEntry, - PPARTENTRY CurrentEntry) +static +PPARTENTRY +GetPrevPartitionedEntry( + PDISKENTRY DiskEntry, + PPARTENTRY CurrentEntry) { - PPARTENTRY PrevEntry; - PLIST_ENTRY Entry; + PPARTENTRY PrevEntry; + PLIST_ENTRY Entry; + + if (CurrentEntry->ListEntry.Blink == &DiskEntry->PartListHead) + return NULL; + + Entry = CurrentEntry->ListEntry.Blink; + while (Entry != &DiskEntry->PartListHead) + { + PrevEntry = CONTAINING_RECORD(Entry, + PARTENTRY, + ListEntry); + if (PrevEntry->Unpartitioned == FALSE) + return PrevEntry; + + Entry = Entry->Blink; + } - if (CurrentEntry->ListEntry.Blink == &DiskEntry->PartListHead) return NULL; - - Entry = CurrentEntry->ListEntry.Blink; - while (Entry != &DiskEntry->PartListHead) - { - PrevEntry = CONTAINING_RECORD (Entry, - PARTENTRY, - ListEntry); - if (PrevEntry->Unpartitioned == FALSE) - return PrevEntry; - - Entry = Entry->Blink; - } - - return NULL; } -static PPARTENTRY -GetNextPartitionedEntry (PDISKENTRY DiskEntry, - PPARTENTRY CurrentEntry) +static +PPARTENTRY +GetNextPartitionedEntry( + PDISKENTRY DiskEntry, + PPARTENTRY CurrentEntry) { - PPARTENTRY NextEntry; - PLIST_ENTRY Entry; + PPARTENTRY NextEntry; + PLIST_ENTRY Entry; + + if (CurrentEntry->ListEntry.Flink == &DiskEntry->PartListHead) + return NULL; + + Entry = CurrentEntry->ListEntry.Flink; + while (Entry != &DiskEntry->PartListHead) + { + NextEntry = CONTAINING_RECORD(Entry, + PARTENTRY, + ListEntry); + if (NextEntry->Unpartitioned == FALSE) + return NextEntry; + + Entry = Entry->Flink; + } - if (CurrentEntry->ListEntry.Flink == &DiskEntry->PartListHead) return NULL; - - Entry = CurrentEntry->ListEntry.Flink; - while (Entry != &DiskEntry->PartListHead) - { - NextEntry = CONTAINING_RECORD (Entry, - PARTENTRY, - ListEntry); - if (NextEntry->Unpartitioned == FALSE) - return NextEntry; - - Entry = Entry->Flink; - } - - return NULL; } -static PPARTENTRY -GetPrevUnpartitionedEntry (PDISKENTRY DiskEntry, - PPARTENTRY PartEntry) +static +PPARTENTRY +GetPrevUnpartitionedEntry( + PDISKENTRY DiskEntry, + PPARTENTRY PartEntry) { - PPARTENTRY PrevPartEntry; + PPARTENTRY PrevPartEntry; - if (PartEntry->ListEntry.Blink != &DiskEntry->PartListHead) - { - PrevPartEntry = CONTAINING_RECORD (PartEntry->ListEntry.Blink, - PARTENTRY, - ListEntry); - if (PrevPartEntry->Unpartitioned == TRUE) - return PrevPartEntry; - } + if (PartEntry->ListEntry.Blink != &DiskEntry->PartListHead) + { + PrevPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Blink, + PARTENTRY, + ListEntry); + if (PrevPartEntry->Unpartitioned == TRUE) + return PrevPartEntry; + } - return NULL; + return NULL; } -static PPARTENTRY -GetNextUnpartitionedEntry (PDISKENTRY DiskEntry, - PPARTENTRY PartEntry) +static +PPARTENTRY +GetNextUnpartitionedEntry( + PDISKENTRY DiskEntry, + PPARTENTRY PartEntry) { - PPARTENTRY NextPartEntry; + PPARTENTRY NextPartEntry; - if (PartEntry->ListEntry.Flink != &DiskEntry->PartListHead) - { - NextPartEntry = CONTAINING_RECORD (PartEntry->ListEntry.Flink, - PARTENTRY, - ListEntry); - if (NextPartEntry->Unpartitioned == TRUE) - return NextPartEntry; - } + if (PartEntry->ListEntry.Flink != &DiskEntry->PartListHead) + { + NextPartEntry = CONTAINING_RECORD(PartEntry->ListEntry.Flink, + PARTENTRY, + ListEntry); + if (NextPartEntry->Unpartitioned == TRUE) + return NextPartEntry; + } - return NULL; + return NULL; } VOID -CreateNewPartition (PPARTLIST List, - ULONGLONG PartitionSize, - BOOLEAN AutoCreate) +CreateNewPartition( + PPARTLIST List, + ULONGLONG PartitionSize, + BOOLEAN AutoCreate) { - PDISKENTRY DiskEntry; - PPARTENTRY PartEntry; - PPARTENTRY PrevPartEntry; - PPARTENTRY NextPartEntry; - PPARTENTRY NewPartEntry; + PDISKENTRY DiskEntry; + PPARTENTRY PartEntry; + PPARTENTRY PrevPartEntry; + PPARTENTRY NextPartEntry; + PPARTENTRY NewPartEntry; - if (List == NULL || - List->CurrentDisk == NULL || - List->CurrentPartition == NULL || - List->CurrentPartition->Unpartitioned == FALSE) - { - return; - } - - DiskEntry = List->CurrentDisk; - PartEntry = List->CurrentPartition; - - if (AutoCreate == TRUE || - PartitionSize == PartEntry->UnpartitionedLength) - { - /* Convert current entry to 'new (unformatted)' */ - PartEntry->FormatState = Unformatted; - PartEntry->PartInfo[0].StartingOffset.QuadPart = - PartEntry->UnpartitionedOffset + DiskEntry->TrackSize; - PartEntry->PartInfo[0].HiddenSectors = - (ULONG)(PartEntry->PartInfo[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector); - PartEntry->PartInfo[0].PartitionLength.QuadPart = - PartEntry->UnpartitionedLength - DiskEntry->TrackSize; - PartEntry->PartInfo[0].PartitionType = PARTITION_ENTRY_UNUSED; - PartEntry->PartInfo[0].BootIndicator = FALSE; /* FIXME */ - PartEntry->PartInfo[0].RewritePartition = TRUE; - PartEntry->PartInfo[1].RewritePartition = TRUE; - PartEntry->PartInfo[2].RewritePartition = TRUE; - PartEntry->PartInfo[3].RewritePartition = TRUE; - - /* Get previous and next partition entries */ - PrevPartEntry = GetPrevPartitionedEntry (DiskEntry, - PartEntry); - NextPartEntry = GetNextPartitionedEntry (DiskEntry, - PartEntry); - - if (PrevPartEntry != NULL && NextPartEntry != NULL) + if (List == NULL || + List->CurrentDisk == NULL || + List->CurrentPartition == NULL || + List->CurrentPartition->Unpartitioned == FALSE) { - /* Current entry is in the middle of the list */ - - /* Copy previous container partition data to current entry */ - RtlCopyMemory (&PartEntry->PartInfo[1], - &PrevPartEntry->PartInfo[1], - sizeof(PARTITION_INFORMATION)); - PartEntry->PartInfo[1].RewritePartition = TRUE; - - /* Update previous container partition data */ - - PrevPartEntry->PartInfo[1].StartingOffset.QuadPart = - PartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize; - PrevPartEntry->PartInfo[1].HiddenSectors = - (ULONG)(PrevPartEntry->PartInfo[1].StartingOffset.QuadPart / DiskEntry->BytesPerSector); - - if (DiskEntry->PartListHead.Flink == &PrevPartEntry->ListEntry) - { - /* Special case - previous partition is first partition */ - PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = - DiskEntry->DiskSize - PrevPartEntry->PartInfo[1].StartingOffset.QuadPart; - } - else - { - PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = - PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize; - } - - PrevPartEntry->PartInfo[1].RewritePartition = TRUE; - } - else if (PrevPartEntry == NULL && NextPartEntry != NULL) - { - /* Current entry is the first entry */ - return; - } - else if (PrevPartEntry != NULL && NextPartEntry == NULL) - { - /* Current entry is the last entry */ - - PrevPartEntry->PartInfo[1].StartingOffset.QuadPart = - PartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize; - PrevPartEntry->PartInfo[1].HiddenSectors = - (ULONG)(PrevPartEntry->PartInfo[1].StartingOffset.QuadPart / DiskEntry->BytesPerSector); - - if (DiskEntry->PartListHead.Flink == &PrevPartEntry->ListEntry) - { - /* Special case - previous partition is first partition */ - PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = - DiskEntry->DiskSize - PrevPartEntry->PartInfo[1].StartingOffset.QuadPart; - } - else - { - PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = - PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize; - } - - if ((PartEntry->PartInfo[1].StartingOffset.QuadPart + - PartEntry->PartInfo[1].PartitionLength.QuadPart) < - (1024LL * 255LL * 63LL * 512LL)) - { - PrevPartEntry->PartInfo[1].PartitionType = PARTITION_EXTENDED; - } - else - { - PrevPartEntry->PartInfo[1].PartitionType = PARTITION_XINT13_EXTENDED; - } - - PrevPartEntry->PartInfo[1].BootIndicator = FALSE; - PrevPartEntry->PartInfo[1].RewritePartition = TRUE; + return; } - PartEntry->AutoCreate = AutoCreate; - PartEntry->New = TRUE; - PartEntry->Unpartitioned = FALSE; - PartEntry->UnpartitionedOffset = 0ULL; - PartEntry->UnpartitionedLength = 0ULL; - } - else - { - /* Insert an initialize a new partition entry */ - NewPartEntry = (PPARTENTRY)RtlAllocateHeap (ProcessHeap, - 0, - sizeof(PARTENTRY)); - if (NewPartEntry == NULL) - return; + DiskEntry = List->CurrentDisk; + PartEntry = List->CurrentPartition; - RtlZeroMemory (NewPartEntry, - sizeof(PARTENTRY)); - - /* Insert the new entry into the list */ - InsertTailList (&PartEntry->ListEntry, - &NewPartEntry->ListEntry); - - NewPartEntry->New = TRUE; - - NewPartEntry->FormatState = Unformatted; - NewPartEntry->PartInfo[0].StartingOffset.QuadPart = - PartEntry->UnpartitionedOffset + DiskEntry->TrackSize; - NewPartEntry->PartInfo[0].HiddenSectors = - (ULONG)(NewPartEntry->PartInfo[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector); - NewPartEntry->PartInfo[0].PartitionLength.QuadPart = - PartitionSize - DiskEntry->TrackSize; - NewPartEntry->PartInfo[0].PartitionType = PARTITION_ENTRY_UNUSED; - NewPartEntry->PartInfo[0].BootIndicator = FALSE; /* FIXME */ - NewPartEntry->PartInfo[0].RewritePartition = TRUE; - NewPartEntry->PartInfo[1].RewritePartition = TRUE; - NewPartEntry->PartInfo[2].RewritePartition = TRUE; - NewPartEntry->PartInfo[3].RewritePartition = TRUE; - - /* Get previous and next partition entries */ - PrevPartEntry = GetPrevPartitionedEntry (DiskEntry, - NewPartEntry); - NextPartEntry = GetNextPartitionedEntry (DiskEntry, - NewPartEntry); - - if (PrevPartEntry != NULL && NextPartEntry != NULL) + if (AutoCreate == TRUE || + PartitionSize == PartEntry->UnpartitionedLength) { - /* Current entry is in the middle of the list */ + /* Convert current entry to 'new (unformatted)' */ + PartEntry->FormatState = Unformatted; + PartEntry->PartInfo[0].StartingOffset.QuadPart = + PartEntry->UnpartitionedOffset + DiskEntry->TrackSize; + PartEntry->PartInfo[0].HiddenSectors = + (ULONG)(PartEntry->PartInfo[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector); + PartEntry->PartInfo[0].PartitionLength.QuadPart = + PartEntry->UnpartitionedLength - DiskEntry->TrackSize; + PartEntry->PartInfo[0].PartitionType = PARTITION_ENTRY_UNUSED; + PartEntry->PartInfo[0].BootIndicator = FALSE; /* FIXME */ + PartEntry->PartInfo[0].RewritePartition = TRUE; + PartEntry->PartInfo[1].RewritePartition = TRUE; + PartEntry->PartInfo[2].RewritePartition = TRUE; + PartEntry->PartInfo[3].RewritePartition = TRUE; - /* Copy previous container partition data to current entry */ - RtlCopyMemory (&NewPartEntry->PartInfo[1], - &PrevPartEntry->PartInfo[1], - sizeof(PARTITION_INFORMATION)); - NewPartEntry->PartInfo[1].RewritePartition = TRUE; + /* Get previous and next partition entries */ + PrevPartEntry = GetPrevPartitionedEntry(DiskEntry, + PartEntry); + NextPartEntry = GetNextPartitionedEntry(DiskEntry, + PartEntry); - /* Update previous container partition data */ + if (PrevPartEntry != NULL && NextPartEntry != NULL) + { + /* Current entry is in the middle of the list */ - PrevPartEntry->PartInfo[1].StartingOffset.QuadPart = - NewPartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize; - PrevPartEntry->PartInfo[1].HiddenSectors = - (ULONG)(PrevPartEntry->PartInfo[1].StartingOffset.QuadPart / DiskEntry->BytesPerSector); + /* Copy previous container partition data to current entry */ + RtlCopyMemory(&PartEntry->PartInfo[1], + &PrevPartEntry->PartInfo[1], + sizeof(PARTITION_INFORMATION)); + PartEntry->PartInfo[1].RewritePartition = TRUE; - if (DiskEntry->PartListHead.Flink == &PrevPartEntry->ListEntry) - { - /* Special case - previous partition is first partition */ - PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = - DiskEntry->DiskSize - PrevPartEntry->PartInfo[1].StartingOffset.QuadPart; - } - else - { - PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = - NewPartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize; - } + /* Update previous container partition data */ - PrevPartEntry->PartInfo[1].RewritePartition = TRUE; + PrevPartEntry->PartInfo[1].StartingOffset.QuadPart = + PartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize; + PrevPartEntry->PartInfo[1].HiddenSectors = + (ULONG)(PrevPartEntry->PartInfo[1].StartingOffset.QuadPart / DiskEntry->BytesPerSector); + + if (DiskEntry->PartListHead.Flink == &PrevPartEntry->ListEntry) + { + /* Special case - previous partition is first partition */ + PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = + DiskEntry->DiskSize - PrevPartEntry->PartInfo[1].StartingOffset.QuadPart; + } + else + { + PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = + PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize; + } + + PrevPartEntry->PartInfo[1].RewritePartition = TRUE; + } + else if (PrevPartEntry == NULL && NextPartEntry != NULL) + { + /* Current entry is the first entry */ + return; + } + else if (PrevPartEntry != NULL && NextPartEntry == NULL) + { + /* Current entry is the last entry */ + + PrevPartEntry->PartInfo[1].StartingOffset.QuadPart = + PartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize; + PrevPartEntry->PartInfo[1].HiddenSectors = + (ULONG)(PrevPartEntry->PartInfo[1].StartingOffset.QuadPart / DiskEntry->BytesPerSector); + + if (DiskEntry->PartListHead.Flink == &PrevPartEntry->ListEntry) + { + /* Special case - previous partition is first partition */ + PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = + DiskEntry->DiskSize - PrevPartEntry->PartInfo[1].StartingOffset.QuadPart; + } + else + { + PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = + PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize; + } + + if ((PartEntry->PartInfo[1].StartingOffset.QuadPart + + PartEntry->PartInfo[1].PartitionLength.QuadPart) < + (1024LL * 255LL * 63LL * 512LL)) + { + PrevPartEntry->PartInfo[1].PartitionType = PARTITION_EXTENDED; + } + else + { + PrevPartEntry->PartInfo[1].PartitionType = PARTITION_XINT13_EXTENDED; + } + + PrevPartEntry->PartInfo[1].BootIndicator = FALSE; + PrevPartEntry->PartInfo[1].RewritePartition = TRUE; + } + + PartEntry->AutoCreate = AutoCreate; + PartEntry->New = TRUE; + PartEntry->Unpartitioned = FALSE; + PartEntry->UnpartitionedOffset = 0ULL; + PartEntry->UnpartitionedLength = 0ULL; } - else if (PrevPartEntry == NULL && NextPartEntry != NULL) + else { - /* Current entry is the first entry */ - return; - } - else if (PrevPartEntry != NULL && NextPartEntry == NULL) - { - /* Current entry is the last entry */ + /* Insert an initialize a new partition entry */ + NewPartEntry = (PPARTENTRY)RtlAllocateHeap(ProcessHeap, + 0, + sizeof(PARTENTRY)); + if (NewPartEntry == NULL) + return; - PrevPartEntry->PartInfo[1].StartingOffset.QuadPart = - NewPartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize; - PrevPartEntry->PartInfo[1].HiddenSectors = - (ULONG)(PrevPartEntry->PartInfo[1].StartingOffset.QuadPart / DiskEntry->BytesPerSector); + RtlZeroMemory(NewPartEntry, + sizeof(PARTENTRY)); - if (DiskEntry->PartListHead.Flink == &PrevPartEntry->ListEntry) - { - /* Special case - previous partition is first partition */ - PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = - DiskEntry->DiskSize - PrevPartEntry->PartInfo[1].StartingOffset.QuadPart; - } - else - { - PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = - NewPartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize; - } + /* Insert the new entry into the list */ + InsertTailList(&PartEntry->ListEntry, + &NewPartEntry->ListEntry); - if ((PartEntry->PartInfo[1].StartingOffset.QuadPart + - PartEntry->PartInfo[1].PartitionLength.QuadPart) < - (1024LL * 255LL * 63LL * 512LL)) - { - PrevPartEntry->PartInfo[1].PartitionType = PARTITION_EXTENDED; - } - else - { - PrevPartEntry->PartInfo[1].PartitionType = PARTITION_XINT13_EXTENDED; - } + NewPartEntry->New = TRUE; - PrevPartEntry->PartInfo[1].BootIndicator = FALSE; - PrevPartEntry->PartInfo[1].RewritePartition = TRUE; + NewPartEntry->FormatState = Unformatted; + NewPartEntry->PartInfo[0].StartingOffset.QuadPart = + PartEntry->UnpartitionedOffset + DiskEntry->TrackSize; + NewPartEntry->PartInfo[0].HiddenSectors = + (ULONG)(NewPartEntry->PartInfo[0].StartingOffset.QuadPart / DiskEntry->BytesPerSector); + NewPartEntry->PartInfo[0].PartitionLength.QuadPart = + PartitionSize - DiskEntry->TrackSize; + NewPartEntry->PartInfo[0].PartitionType = PARTITION_ENTRY_UNUSED; + NewPartEntry->PartInfo[0].BootIndicator = FALSE; /* FIXME */ + NewPartEntry->PartInfo[0].RewritePartition = TRUE; + NewPartEntry->PartInfo[1].RewritePartition = TRUE; + NewPartEntry->PartInfo[2].RewritePartition = TRUE; + NewPartEntry->PartInfo[3].RewritePartition = TRUE; + + /* Get previous and next partition entries */ + PrevPartEntry = GetPrevPartitionedEntry(DiskEntry, + NewPartEntry); + NextPartEntry = GetNextPartitionedEntry(DiskEntry, + NewPartEntry); + + if (PrevPartEntry != NULL && NextPartEntry != NULL) + { + /* Current entry is in the middle of the list */ + + /* Copy previous container partition data to current entry */ + RtlCopyMemory(&NewPartEntry->PartInfo[1], + &PrevPartEntry->PartInfo[1], + sizeof(PARTITION_INFORMATION)); + NewPartEntry->PartInfo[1].RewritePartition = TRUE; + + /* Update previous container partition data */ + PrevPartEntry->PartInfo[1].StartingOffset.QuadPart = + NewPartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize; + PrevPartEntry->PartInfo[1].HiddenSectors = + (ULONG)(PrevPartEntry->PartInfo[1].StartingOffset.QuadPart / DiskEntry->BytesPerSector); + + if (DiskEntry->PartListHead.Flink == &PrevPartEntry->ListEntry) + { + /* Special case - previous partition is first partition */ + PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = + DiskEntry->DiskSize - PrevPartEntry->PartInfo[1].StartingOffset.QuadPart; + } + else + { + PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = + NewPartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize; + } + + PrevPartEntry->PartInfo[1].RewritePartition = TRUE; + } + else if (PrevPartEntry == NULL && NextPartEntry != NULL) + { + /* Current entry is the first entry */ + return; + } + else if (PrevPartEntry != NULL && NextPartEntry == NULL) + { + /* Current entry is the last entry */ + + PrevPartEntry->PartInfo[1].StartingOffset.QuadPart = + NewPartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize; + PrevPartEntry->PartInfo[1].HiddenSectors = + (ULONG)(PrevPartEntry->PartInfo[1].StartingOffset.QuadPart / DiskEntry->BytesPerSector); + + if (DiskEntry->PartListHead.Flink == &PrevPartEntry->ListEntry) + { + /* Special case - previous partition is first partition */ + PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = + DiskEntry->DiskSize - PrevPartEntry->PartInfo[1].StartingOffset.QuadPart; + } + else + { + PrevPartEntry->PartInfo[1].PartitionLength.QuadPart = + NewPartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize; + } + + if ((PartEntry->PartInfo[1].StartingOffset.QuadPart + + PartEntry->PartInfo[1].PartitionLength.QuadPart) < + (1024LL * 255LL * 63LL * 512LL)) + { + PrevPartEntry->PartInfo[1].PartitionType = PARTITION_EXTENDED; + } + else + { + PrevPartEntry->PartInfo[1].PartitionType = PARTITION_XINT13_EXTENDED; + } + + PrevPartEntry->PartInfo[1].BootIndicator = FALSE; + PrevPartEntry->PartInfo[1].RewritePartition = TRUE; + } + + /* Update offset and size of the remaining unpartitioned disk space */ + PartEntry->UnpartitionedOffset += PartitionSize; + PartEntry->UnpartitionedLength -= PartitionSize; } - /* Update offset and size of the remaining unpartitioned disk space */ - PartEntry->UnpartitionedOffset += PartitionSize; - PartEntry->UnpartitionedLength -= PartitionSize; - } - - DiskEntry->Modified = TRUE; - - UpdatePartitionNumbers (DiskEntry); - - AssignDriverLetters (List); -} - - -VOID -DeleteCurrentPartition (PPARTLIST List) -{ - PDISKENTRY DiskEntry; - PPARTENTRY PartEntry; - PPARTENTRY PrevPartEntry; - PPARTENTRY NextPartEntry; - - if (List == NULL || - List->CurrentDisk == NULL || - List->CurrentPartition == NULL || - List->CurrentPartition->Unpartitioned == TRUE) - { - return; - } - - DiskEntry = List->CurrentDisk; - PartEntry = List->CurrentPartition; - - /* Adjust container partition entries */ - - /* Get previous and next partition entries */ - PrevPartEntry = GetPrevPartitionedEntry (DiskEntry, - PartEntry); - NextPartEntry = GetNextPartitionedEntry (DiskEntry, - PartEntry); - - if (PrevPartEntry != NULL && NextPartEntry != NULL) - { - /* Current entry is in the middle of the list */ - - /* - * The first extended partition can not be deleted - * as long as other extended partitions are present. - */ - if (PrevPartEntry->ListEntry.Blink == &DiskEntry->PartListHead) - return; - - /* Copy previous container partition data to current entry */ - RtlCopyMemory (&PrevPartEntry->PartInfo[1], - &PartEntry->PartInfo[1], - sizeof(PARTITION_INFORMATION)); - PrevPartEntry->PartInfo[1].RewritePartition = TRUE; - } - else if (PrevPartEntry == NULL && NextPartEntry != NULL) - { - /* - * A primary partition can not be deleted as long as - * extended partitions are present. - */ - return; - } - else if (PrevPartEntry != NULL && NextPartEntry == NULL) - { - /* Current entry is the last entry */ - RtlZeroMemory (&PrevPartEntry->PartInfo[1], - sizeof(PARTITION_INFORMATION)); - PrevPartEntry->PartInfo[1].RewritePartition = TRUE; - } - - - /* Adjust unpartitioned disk space entries */ - - /* Get pointer to previous and next unpartitioned entries */ - PrevPartEntry = GetPrevUnpartitionedEntry (DiskEntry, - PartEntry); - - NextPartEntry = GetNextUnpartitionedEntry (DiskEntry, - PartEntry); - - if (PrevPartEntry != NULL && NextPartEntry != NULL) - { - /* Merge previous, current and next unpartitioned entry */ - - /* Adjust the previous entries length */ - PrevPartEntry->UnpartitionedLength += - (PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize + - NextPartEntry->UnpartitionedLength); - - /* Remove the current entry */ - RemoveEntryList (&PartEntry->ListEntry); - RtlFreeHeap (ProcessHeap, - 0, - PartEntry); - - /* Remove the next entry */ - RemoveEntryList (&NextPartEntry->ListEntry); - RtlFreeHeap (ProcessHeap, - 0, - NextPartEntry); - - /* Update current partition */ - List->CurrentPartition = PrevPartEntry; - } - else if (PrevPartEntry != NULL && NextPartEntry == NULL) - { - /* Merge current and previous unpartitioned entry */ - - /* Adjust the previous entries length */ - PrevPartEntry->UnpartitionedLength += - (PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize); - - /* Remove the current entry */ - RemoveEntryList (&PartEntry->ListEntry); - RtlFreeHeap (ProcessHeap, - 0, - PartEntry); - - /* Update current partition */ - List->CurrentPartition = PrevPartEntry; - } - else if (PrevPartEntry == NULL && NextPartEntry != NULL) - { - /* Merge current and next unpartitioned entry */ - - /* Adjust the next entries offset and length */ - NextPartEntry->UnpartitionedOffset = - PartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize; - NextPartEntry->UnpartitionedLength += - (PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize); - - /* Remove the current entry */ - RemoveEntryList (&PartEntry->ListEntry); - RtlFreeHeap (ProcessHeap, - 0, - PartEntry); - - /* Update current partition */ - List->CurrentPartition = NextPartEntry; - } - else - { - /* Nothing to merge but change current entry */ - PartEntry->New = FALSE; - PartEntry->Unpartitioned = TRUE; - PartEntry->UnpartitionedOffset = - PartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize; - PartEntry->UnpartitionedLength = - PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize; - - /* Wipe the partition table */ - RtlZeroMemory (&PartEntry->PartInfo, - sizeof(PartEntry->PartInfo)); - } - - DiskEntry->Modified = TRUE; - - UpdatePartitionNumbers (DiskEntry); - - AssignDriverLetters (List); -} - - -VOID -CheckActiveBootPartition (PPARTLIST List) -{ - PDISKENTRY DiskEntry; - PPARTENTRY PartEntry; - PLIST_ENTRY ListEntry; - UCHAR i; - - /* Check for empty disk list */ - if (IsListEmpty (&List->DiskListHead)) - { - List->ActiveBootDisk = NULL; - List->ActiveBootPartition = NULL; - List->ActiveBootPartitionNumber = 0; - return; - } - -#if 0 - if (List->ActiveBootDisk != NULL && - List->ActiveBootPartition != NULL) - { - /* We already have an active boot partition */ - return; - } -#endif - - /* Choose the currently selected disk */ - DiskEntry = List->CurrentDisk; - - /* Check for empty partition list */ - if (IsListEmpty (&DiskEntry->PartListHead)) - { - List->ActiveBootDisk = NULL; - List->ActiveBootPartition = NULL; - List->ActiveBootPartitionNumber = 0; - return; - } - - PartEntry = CONTAINING_RECORD (DiskEntry->PartListHead.Flink, - PARTENTRY, - ListEntry); - - /* Set active boot partition */ - if ((DiskEntry->NewDisk == TRUE) || - (PartEntry->PartInfo[0].BootIndicator == FALSE && - PartEntry->PartInfo[1].BootIndicator == FALSE && - PartEntry->PartInfo[2].BootIndicator == FALSE && - PartEntry->PartInfo[3].BootIndicator == FALSE)) - { - PartEntry->PartInfo[0].BootIndicator = TRUE; - PartEntry->PartInfo[0].RewritePartition = TRUE; DiskEntry->Modified = TRUE; - /* FIXME: Might be incorrect if partitions were created by Linux FDISK */ - List->ActiveBootDisk = DiskEntry; - List->ActiveBootPartition = PartEntry; - List->ActiveBootPartitionNumber = 0; + UpdatePartitionNumbers(DiskEntry); - return; - } + AssignDriverLetters(List); +} - /* Disk is not new, scan all partitions to find a bootable one */ - List->ActiveBootDisk = NULL; - List->ActiveBootPartition = NULL; - List->ActiveBootPartitionNumber = 0; - ListEntry = DiskEntry->PartListHead.Flink; - while (ListEntry != &DiskEntry->PartListHead) - { - PartEntry = CONTAINING_RECORD(ListEntry, +VOID +DeleteCurrentPartition( + PPARTLIST List) +{ + PDISKENTRY DiskEntry; + PPARTENTRY PartEntry; + PPARTENTRY PrevPartEntry; + PPARTENTRY NextPartEntry; + + if (List == NULL || + List->CurrentDisk == NULL || + List->CurrentPartition == NULL || + List->CurrentPartition->Unpartitioned == TRUE) + { + return; + } + + DiskEntry = List->CurrentDisk; + PartEntry = List->CurrentPartition; + + /* Adjust container partition entries */ + + /* Get previous and next partition entries */ + PrevPartEntry = GetPrevPartitionedEntry(DiskEntry, + PartEntry); + NextPartEntry = GetNextPartitionedEntry(DiskEntry, + PartEntry); + + if (PrevPartEntry != NULL && NextPartEntry != NULL) + { + /* Current entry is in the middle of the list */ + + /* + * The first extended partition can not be deleted + * as long as other extended partitions are present. + */ + if (PrevPartEntry->ListEntry.Blink == &DiskEntry->PartListHead) + return; + + /* Copy previous container partition data to current entry */ + RtlCopyMemory(&PrevPartEntry->PartInfo[1], + &PartEntry->PartInfo[1], + sizeof(PARTITION_INFORMATION)); + PrevPartEntry->PartInfo[1].RewritePartition = TRUE; + } + else if (PrevPartEntry == NULL && NextPartEntry != NULL) + { + /* + * A primary partition can not be deleted as long as + * extended partitions are present. + */ + return; + } + else if (PrevPartEntry != NULL && NextPartEntry == NULL) + { + /* Current entry is the last entry */ + RtlZeroMemory(&PrevPartEntry->PartInfo[1], + sizeof(PARTITION_INFORMATION)); + PrevPartEntry->PartInfo[1].RewritePartition = TRUE; + } + + + /* Adjust unpartitioned disk space entries */ + + /* Get pointer to previous and next unpartitioned entries */ + PrevPartEntry = GetPrevUnpartitionedEntry(DiskEntry, + PartEntry); + + NextPartEntry = GetNextUnpartitionedEntry(DiskEntry, + PartEntry); + + if (PrevPartEntry != NULL && NextPartEntry != NULL) + { + /* Merge previous, current and next unpartitioned entry */ + + /* Adjust the previous entries length */ + PrevPartEntry->UnpartitionedLength += + (PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize + + NextPartEntry->UnpartitionedLength); + + /* Remove the current entry */ + RemoveEntryList(&PartEntry->ListEntry); + RtlFreeHeap(ProcessHeap, + 0, + PartEntry); + + /* Remove the next entry */ + RemoveEntryList (&NextPartEntry->ListEntry); + RtlFreeHeap(ProcessHeap, + 0, + NextPartEntry); + + /* Update current partition */ + List->CurrentPartition = PrevPartEntry; + } + else if (PrevPartEntry != NULL && NextPartEntry == NULL) + { + /* Merge current and previous unpartitioned entry */ + + /* Adjust the previous entries length */ + PrevPartEntry->UnpartitionedLength += + (PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize); + + /* Remove the current entry */ + RemoveEntryList(&PartEntry->ListEntry); + RtlFreeHeap(ProcessHeap, + 0, + PartEntry); + + /* Update current partition */ + List->CurrentPartition = PrevPartEntry; + } + else if (PrevPartEntry == NULL && NextPartEntry != NULL) + { + /* Merge current and next unpartitioned entry */ + + /* Adjust the next entries offset and length */ + NextPartEntry->UnpartitionedOffset = + PartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize; + NextPartEntry->UnpartitionedLength += + (PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize); + + /* Remove the current entry */ + RemoveEntryList(&PartEntry->ListEntry); + RtlFreeHeap(ProcessHeap, + 0, + PartEntry); + + /* Update current partition */ + List->CurrentPartition = NextPartEntry; + } + else + { + /* Nothing to merge but change current entry */ + PartEntry->New = FALSE; + PartEntry->Unpartitioned = TRUE; + PartEntry->UnpartitionedOffset = + PartEntry->PartInfo[0].StartingOffset.QuadPart - DiskEntry->TrackSize; + PartEntry->UnpartitionedLength = + PartEntry->PartInfo[0].PartitionLength.QuadPart + DiskEntry->TrackSize; + + /* Wipe the partition table */ + RtlZeroMemory(&PartEntry->PartInfo, + sizeof(PartEntry->PartInfo)); + } + + DiskEntry->Modified = TRUE; + + UpdatePartitionNumbers(DiskEntry); + + AssignDriverLetters(List); +} + + +VOID +CheckActiveBootPartition( + PPARTLIST List) +{ + PDISKENTRY DiskEntry; + PPARTENTRY PartEntry; + PLIST_ENTRY ListEntry; + UCHAR i; + + /* Check for empty disk list */ + if (IsListEmpty (&List->DiskListHead)) + { + List->ActiveBootDisk = NULL; + List->ActiveBootPartition = NULL; + List->ActiveBootPartitionNumber = 0; + return; + } + +#if 0 + if (List->ActiveBootDisk != NULL && + List->ActiveBootPartition != NULL) + { + /* We already have an active boot partition */ + return; + } +#endif + + /* Choose the currently selected disk */ + DiskEntry = List->CurrentDisk; + + /* Check for empty partition list */ + if (IsListEmpty (&DiskEntry->PartListHead)) + { + List->ActiveBootDisk = NULL; + List->ActiveBootPartition = NULL; + List->ActiveBootPartitionNumber = 0; + return; + } + + PartEntry = CONTAINING_RECORD(DiskEntry->PartListHead.Flink, PARTENTRY, ListEntry); - /* Check if it's partitioned */ - if (!PartEntry->Unpartitioned) + /* Set active boot partition */ + if ((DiskEntry->NewDisk == TRUE) || + (PartEntry->PartInfo[0].BootIndicator == FALSE && + PartEntry->PartInfo[1].BootIndicator == FALSE && + PartEntry->PartInfo[2].BootIndicator == FALSE && + PartEntry->PartInfo[3].BootIndicator == FALSE)) { - /* Go through all of its 4 partitions */ - for (i=0; i<4; i++) - { - if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED && - PartEntry->PartInfo[i].BootIndicator) - { - /* Yes, we found it */ - List->ActiveBootDisk = DiskEntry; - List->ActiveBootPartition = PartEntry; - List->ActiveBootPartitionNumber = i; + PartEntry->PartInfo[0].BootIndicator = TRUE; + PartEntry->PartInfo[0].RewritePartition = TRUE; + DiskEntry->Modified = TRUE; - DPRINT("Found bootable partition disk %d, drive letter %c\n", - DiskEntry->DiskNumber, PartEntry->DriveLetter[i]); + /* FIXME: Might be incorrect if partitions were created by Linux FDISK */ + List->ActiveBootDisk = DiskEntry; + List->ActiveBootPartition = PartEntry; + List->ActiveBootPartitionNumber = 0; - break; - } - } - } - /* Go to the next one */ - ListEntry = ListEntry->Flink; - } -} - - -BOOLEAN -CheckForLinuxFdiskPartitions (PPARTLIST List) -{ - PDISKENTRY DiskEntry; - PPARTENTRY PartEntry; - PLIST_ENTRY Entry1; - PLIST_ENTRY Entry2; - ULONG PartitionCount; - ULONG i; - - Entry1 = List->DiskListHead.Flink; - while (Entry1 != &List->DiskListHead) - { - DiskEntry = CONTAINING_RECORD (Entry1, - DISKENTRY, - ListEntry); - - Entry2 = DiskEntry->PartListHead.Flink; - while (Entry2 != &DiskEntry->PartListHead) - { - PartEntry = CONTAINING_RECORD (Entry2, - PARTENTRY, - ListEntry); - - if (PartEntry->Unpartitioned == FALSE) - { - PartitionCount = 0; - - for (i = 0; i < 4; i++) - { - if (!IsContainerPartition (PartEntry->PartInfo[i].PartitionType) && - PartEntry->PartInfo[i].PartitionLength.QuadPart != 0ULL) - { - PartitionCount++; - } - } - - if (PartitionCount > 1) - { - return TRUE; - } - } - - Entry2 = Entry2->Flink; + return; } - Entry1 = Entry1->Flink; - } + /* Disk is not new, scan all partitions to find a bootable one */ + List->ActiveBootDisk = NULL; + List->ActiveBootPartition = NULL; + List->ActiveBootPartitionNumber = 0; - return FALSE; -} - - -BOOLEAN -WritePartitionsToDisk (PPARTLIST List) -{ - PDRIVE_LAYOUT_INFORMATION DriveLayout; - OBJECT_ATTRIBUTES ObjectAttributes; - IO_STATUS_BLOCK Iosb; - WCHAR DstPath[MAX_PATH]; - UNICODE_STRING Name; - HANDLE FileHandle; - PDISKENTRY DiskEntry1; - PDISKENTRY DiskEntry2; - PPARTENTRY PartEntry; - PLIST_ENTRY Entry1; - PLIST_ENTRY Entry2; - ULONG PartitionCount; - ULONG DriveLayoutSize; - ULONG Index; - NTSTATUS Status; - - if (List == NULL) - { - return TRUE; - } - - Entry1 = List->DiskListHead.Flink; - while (Entry1 != &List->DiskListHead) - { - DiskEntry1 = CONTAINING_RECORD (Entry1, - DISKENTRY, - ListEntry); - - if (DiskEntry1->Modified == TRUE) + ListEntry = DiskEntry->PartListHead.Flink; + while (ListEntry != &DiskEntry->PartListHead) { - /* Count partitioned entries */ - PartitionCount = 0; - Entry2 = DiskEntry1->PartListHead.Flink; - while (Entry2 != &DiskEntry1->PartListHead) - { - PartEntry = CONTAINING_RECORD (Entry2, - PARTENTRY, - ListEntry); - if (PartEntry->Unpartitioned == FALSE) + PartEntry = CONTAINING_RECORD(ListEntry, + PARTENTRY, + ListEntry); + + /* Check if it's partitioned */ + if (!PartEntry->Unpartitioned) { - PartitionCount += 4; - } - - Entry2 = Entry2->Flink; - } - if (PartitionCount == 0) - { - DriveLayoutSize = sizeof (DRIVE_LAYOUT_INFORMATION) + - ((4 - 1) * sizeof (PARTITION_INFORMATION)); - } - else - { - DriveLayoutSize = sizeof (DRIVE_LAYOUT_INFORMATION) + - ((PartitionCount - 1) * sizeof (PARTITION_INFORMATION)); - } - DriveLayout = (PDRIVE_LAYOUT_INFORMATION)RtlAllocateHeap (ProcessHeap, - 0, - DriveLayoutSize); - if (DriveLayout == NULL) - { - DPRINT1 ("RtlAllocateHeap() failed\n"); - return FALSE; - } - - RtlZeroMemory (DriveLayout, - DriveLayoutSize); - - if (PartitionCount == 0) - { - /* delete all partitions in the mbr */ - DriveLayout->PartitionCount = 4; - for (Index = 0; Index < 4; Index++) - { - DriveLayout->PartitionEntry[Index].RewritePartition = TRUE; - } - } - else - { - DriveLayout->PartitionCount = PartitionCount; - - Index = 0; - Entry2 = DiskEntry1->PartListHead.Flink; - while (Entry2 != &DiskEntry1->PartListHead) - { - PartEntry = CONTAINING_RECORD (Entry2, - PARTENTRY, - ListEntry); - if (PartEntry->Unpartitioned == FALSE) - { - RtlCopyMemory (&DriveLayout->PartitionEntry[Index], - &PartEntry->PartInfo[0], - 4 * sizeof (PARTITION_INFORMATION)); - Index += 4; - } - - Entry2 = Entry2->Flink; - } - } - if (DiskEntry1->Signature == 0) - { - LARGE_INTEGER SystemTime; - TIME_FIELDS TimeFields; - PUCHAR Buffer; - Buffer = (PUCHAR)&DiskEntry1->Signature; - - while (1) - { - NtQuerySystemTime (&SystemTime); - RtlTimeToTimeFields (&SystemTime, &TimeFields); - - Buffer[0] = (UCHAR)(TimeFields.Year & 0xFF) + (UCHAR)(TimeFields.Hour & 0xFF); - Buffer[1] = (UCHAR)(TimeFields.Year >> 8) + (UCHAR)(TimeFields.Minute & 0xFF); - Buffer[2] = (UCHAR)(TimeFields.Month & 0xFF) + (UCHAR)(TimeFields.Second & 0xFF); - Buffer[3] = (UCHAR)(TimeFields.Day & 0xFF) + (UCHAR)(TimeFields.Milliseconds & 0xFF); - - if (DiskEntry1->Signature == 0) - { - continue; - } - - /* check if the signature already exist */ - /* FIXME: - * Check also signatures from disks, which are - * not visible (bootable) by the bios. - */ - Entry2 = List->DiskListHead.Flink; - while (Entry2 != &List->DiskListHead) - { - DiskEntry2 = CONTAINING_RECORD(Entry2, DISKENTRY, ListEntry); - if (DiskEntry1 != DiskEntry2 && - DiskEntry1->Signature == DiskEntry2->Signature) + /* Go through all of its 4 partitions */ + for (i = 0; i < 4; i++) { - break; + if (PartEntry->PartInfo[i].PartitionType != PARTITION_ENTRY_UNUSED && + PartEntry->PartInfo[i].BootIndicator) + { + /* Yes, we found it */ + List->ActiveBootDisk = DiskEntry; + List->ActiveBootPartition = PartEntry; + List->ActiveBootPartitionNumber = i; + + DPRINT("Found bootable partition disk %d, drive letter %c\n", + DiskEntry->DiskNumber, PartEntry->DriveLetter[i]); + + break; + } } + } + + /* Go to the next one */ + ListEntry = ListEntry->Flink; + } +} + + +BOOLEAN +CheckForLinuxFdiskPartitions( + PPARTLIST List) +{ + PDISKENTRY DiskEntry; + PPARTENTRY PartEntry; + PLIST_ENTRY Entry1; + PLIST_ENTRY Entry2; + ULONG PartitionCount; + ULONG i; + + Entry1 = List->DiskListHead.Flink; + while (Entry1 != &List->DiskListHead) + { + DiskEntry = CONTAINING_RECORD(Entry1, + DISKENTRY, + ListEntry); + + Entry2 = DiskEntry->PartListHead.Flink; + while (Entry2 != &DiskEntry->PartListHead) + { + PartEntry = CONTAINING_RECORD(Entry2, + PARTENTRY, + ListEntry); + + if (PartEntry->Unpartitioned == FALSE) + { + PartitionCount = 0; + + for (i = 0; i < 4; i++) + { + if (!IsContainerPartition(PartEntry->PartInfo[i].PartitionType) && + PartEntry->PartInfo[i].PartitionLength.QuadPart != 0ULL) + { + PartitionCount++; + } + } + + if (PartitionCount > 1) + { + return TRUE; + } + } + Entry2 = Entry2->Flink; - } - if (Entry2 == &List->DiskListHead) - { - break; - } } - /* set one partition entry to dirty, this will update the signature */ - DriveLayout->PartitionEntry[0].RewritePartition = TRUE; - - } - - DriveLayout->Signature = DiskEntry1->Signature; - - - swprintf (DstPath, - L"\\Device\\Harddisk%d\\Partition0", - DiskEntry1->DiskNumber); - RtlInitUnicodeString (&Name, - DstPath); - InitializeObjectAttributes (&ObjectAttributes, - &Name, - 0, - NULL, - NULL); - - Status = NtOpenFile (&FileHandle, - FILE_ALL_ACCESS, - &ObjectAttributes, - &Iosb, - 0, - FILE_SYNCHRONOUS_IO_NONALERT); - - if (!NT_SUCCESS (Status)) - { - DPRINT1 ("NtOpenFile() failed (Status %lx)\n", Status); - return FALSE; - } - - Status = NtDeviceIoControlFile (FileHandle, - NULL, - NULL, - NULL, - &Iosb, - IOCTL_DISK_SET_DRIVE_LAYOUT, - DriveLayout, - DriveLayoutSize, - NULL, - 0); - if (!NT_SUCCESS (Status)) - { - DPRINT1 ("NtDeviceIoControlFile() failed (Status %lx)\n", Status); - NtClose (FileHandle); - return FALSE; - } - - RtlFreeHeap (ProcessHeap, - 0, - DriveLayout); - - NtClose (FileHandle); + Entry1 = Entry1->Flink; } - Entry1 = Entry1->Flink; - } - - return TRUE; -} - -BOOL SetMountedDeviceValues(PPARTLIST List) -{ - PLIST_ENTRY Entry1, Entry2; - PDISKENTRY DiskEntry; - PPARTENTRY PartEntry; - UCHAR i; - - if (List == NULL) - { return FALSE; - } - - Entry1 = List->DiskListHead.Flink; - while (Entry1 != &List->DiskListHead) - { - DiskEntry = CONTAINING_RECORD (Entry1, - DISKENTRY, - ListEntry); - - Entry2 = DiskEntry->PartListHead.Flink; - while (Entry2 != &DiskEntry->PartListHead) - { - PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); - if (!PartEntry->Unpartitioned) - { - for (i=0; i<4; i++) - { - if (PartEntry->DriveLetter[i]) - { - if (!SetMountedDeviceValue(PartEntry->DriveLetter[i], DiskEntry->Signature, PartEntry->PartInfo[i].StartingOffset)) - { - return FALSE; - } - } - } - } - Entry2 = Entry2->Flink; - } - Entry1 = Entry1->Flink; - } - return TRUE; } +BOOLEAN +WritePartitionsToDisk( + PPARTLIST List) +{ + PDRIVE_LAYOUT_INFORMATION DriveLayout; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK Iosb; + WCHAR DstPath[MAX_PATH]; + UNICODE_STRING Name; + HANDLE FileHandle; + PDISKENTRY DiskEntry1; + PDISKENTRY DiskEntry2; + PPARTENTRY PartEntry; + PLIST_ENTRY Entry1; + PLIST_ENTRY Entry2; + ULONG PartitionCount; + ULONG DriveLayoutSize; + ULONG Index; + NTSTATUS Status; + + if (List == NULL) + { + return TRUE; + } + + Entry1 = List->DiskListHead.Flink; + while (Entry1 != &List->DiskListHead) + { + DiskEntry1 = CONTAINING_RECORD(Entry1, + DISKENTRY, + ListEntry); + + if (DiskEntry1->Modified == TRUE) + { + /* Count partitioned entries */ + PartitionCount = 0; + + Entry2 = DiskEntry1->PartListHead.Flink; + while (Entry2 != &DiskEntry1->PartListHead) + { + PartEntry = CONTAINING_RECORD(Entry2, + PARTENTRY, + ListEntry); + if (PartEntry->Unpartitioned == FALSE) + { + PartitionCount += 4; + } + + Entry2 = Entry2->Flink; + } + + if (PartitionCount == 0) + { + DriveLayoutSize = sizeof (DRIVE_LAYOUT_INFORMATION) + + ((4 - 1) * sizeof (PARTITION_INFORMATION)); + } + else + { + DriveLayoutSize = sizeof (DRIVE_LAYOUT_INFORMATION) + + ((PartitionCount - 1) * sizeof (PARTITION_INFORMATION)); + } + + DriveLayout = (PDRIVE_LAYOUT_INFORMATION)RtlAllocateHeap(ProcessHeap, + 0, + DriveLayoutSize); + if (DriveLayout == NULL) + { + DPRINT1("RtlAllocateHeap() failed\n"); + return FALSE; + } + + RtlZeroMemory(DriveLayout, + DriveLayoutSize); + + if (PartitionCount == 0) + { + /* delete all partitions in the mbr */ + DriveLayout->PartitionCount = 4; + for (Index = 0; Index < 4; Index++) + { + DriveLayout->PartitionEntry[Index].RewritePartition = TRUE; + } + } + else + { + DriveLayout->PartitionCount = PartitionCount; + Index = 0; + + Entry2 = DiskEntry1->PartListHead.Flink; + while (Entry2 != &DiskEntry1->PartListHead) + { + PartEntry = CONTAINING_RECORD(Entry2, + PARTENTRY, + ListEntry); + if (PartEntry->Unpartitioned == FALSE) + { + RtlCopyMemory(&DriveLayout->PartitionEntry[Index], + &PartEntry->PartInfo[0], + 4 * sizeof (PARTITION_INFORMATION)); + Index += 4; + } + + Entry2 = Entry2->Flink; + } + } + + if (DiskEntry1->Signature == 0) + { + LARGE_INTEGER SystemTime; + TIME_FIELDS TimeFields; + PUCHAR Buffer; + Buffer = (PUCHAR)&DiskEntry1->Signature; + + while (1) + { + NtQuerySystemTime(&SystemTime); + RtlTimeToTimeFields(&SystemTime, &TimeFields); + + Buffer[0] = (UCHAR)(TimeFields.Year & 0xFF) + (UCHAR)(TimeFields.Hour & 0xFF); + Buffer[1] = (UCHAR)(TimeFields.Year >> 8) + (UCHAR)(TimeFields.Minute & 0xFF); + Buffer[2] = (UCHAR)(TimeFields.Month & 0xFF) + (UCHAR)(TimeFields.Second & 0xFF); + Buffer[3] = (UCHAR)(TimeFields.Day & 0xFF) + (UCHAR)(TimeFields.Milliseconds & 0xFF); + + if (DiskEntry1->Signature == 0) + { + continue; + } + + /* check if the signature already exist */ + /* FIXME: + * Check also signatures from disks, which are + * not visible (bootable) by the bios. + */ + Entry2 = List->DiskListHead.Flink; + while (Entry2 != &List->DiskListHead) + { + DiskEntry2 = CONTAINING_RECORD(Entry2, DISKENTRY, ListEntry); + if (DiskEntry1 != DiskEntry2 && + DiskEntry1->Signature == DiskEntry2->Signature) + { + break; + } + + Entry2 = Entry2->Flink; + } + + if (Entry2 == &List->DiskListHead) + { + break; + } + } + + /* set one partition entry to dirty, this will update the signature */ + DriveLayout->PartitionEntry[0].RewritePartition = TRUE; + } + + DriveLayout->Signature = DiskEntry1->Signature; + + swprintf(DstPath, + L"\\Device\\Harddisk%d\\Partition0", + DiskEntry1->DiskNumber); + RtlInitUnicodeString(&Name, + DstPath); + InitializeObjectAttributes(&ObjectAttributes, + &Name, + 0, + NULL, + NULL); + + Status = NtOpenFile(&FileHandle, + FILE_ALL_ACCESS, + &ObjectAttributes, + &Iosb, + 0, + FILE_SYNCHRONOUS_IO_NONALERT); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtOpenFile() failed (Status %lx)\n", Status); + return FALSE; + } + + Status = NtDeviceIoControlFile(FileHandle, + NULL, + NULL, + NULL, + &Iosb, + IOCTL_DISK_SET_DRIVE_LAYOUT, + DriveLayout, + DriveLayoutSize, + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtDeviceIoControlFile() failed (Status %lx)\n", Status); + NtClose(FileHandle); + return FALSE; + } + + RtlFreeHeap(ProcessHeap, + 0, + DriveLayout); + + NtClose(FileHandle); + } + + Entry1 = Entry1->Flink; + } + + return TRUE; +} + + +BOOL +SetMountedDeviceValues( + PPARTLIST List) +{ + PLIST_ENTRY Entry1, Entry2; + PDISKENTRY DiskEntry; + PPARTENTRY PartEntry; + UCHAR i; + + if (List == NULL) + { + return FALSE; + } + + Entry1 = List->DiskListHead.Flink; + while (Entry1 != &List->DiskListHead) + { + DiskEntry = CONTAINING_RECORD(Entry1, + DISKENTRY, + ListEntry); + + Entry2 = DiskEntry->PartListHead.Flink; + while (Entry2 != &DiskEntry->PartListHead) + { + PartEntry = CONTAINING_RECORD(Entry2, PARTENTRY, ListEntry); + if (!PartEntry->Unpartitioned) + { + for (i = 0; i < 4; i++) + { + if (PartEntry->DriveLetter[i]) + { + if (!SetMountedDeviceValue(PartEntry->DriveLetter[i], + DiskEntry->Signature, + PartEntry->PartInfo[i].StartingOffset)) + { + return FALSE; + } + } + } + } + + Entry2 = Entry2->Flink; + } + + Entry1 = Entry1->Flink; + } + + return TRUE; +} /* EOF */ diff --git a/base/setup/usetup/partlist.h b/base/setup/usetup/partlist.h index ef3f4d2cbe0..81282f022fc 100644 --- a/base/setup/usetup/partlist.h +++ b/base/setup/usetup/partlist.h @@ -30,116 +30,116 @@ typedef enum _FORMATSTATE { - Unformatted, - UnformattedOrDamaged, - UnknownFormat, - Preformatted, - Formatted + Unformatted, + UnformattedOrDamaged, + UnknownFormat, + Preformatted, + Formatted } FORMATSTATE, *PFORMATSTATE; typedef struct _PARTENTRY { - LIST_ENTRY ListEntry; + LIST_ENTRY ListEntry; - CHAR DriveLetter[4]; - CHAR VolumeLabel[17]; - CHAR FileSystemName[9]; + CHAR DriveLetter[4]; + CHAR VolumeLabel[17]; + CHAR FileSystemName[9]; - /* Partition is unused disk space */ - BOOLEAN Unpartitioned; + /* Partition is unused disk space */ + BOOLEAN Unpartitioned; - /* Partition is new. Table does not exist on disk yet */ - BOOLEAN New; + /* Partition is new. Table does not exist on disk yet */ + BOOLEAN New; - /* Partition was created automatically. */ - BOOLEAN AutoCreate; + /* Partition was created automatically. */ + BOOLEAN AutoCreate; - FORMATSTATE FormatState; + FORMATSTATE FormatState; - /* - * Raw offset and length of the unpartitioned disk space. - * Includes the leading, not yet existing, partition table. - */ - ULONGLONG UnpartitionedOffset; - ULONGLONG UnpartitionedLength; + /* + * Raw offset and length of the unpartitioned disk space. + * Includes the leading, not yet existing, partition table. + */ + ULONGLONG UnpartitionedOffset; + ULONGLONG UnpartitionedLength; - PARTITION_INFORMATION PartInfo[4]; + PARTITION_INFORMATION PartInfo[4]; } PARTENTRY, *PPARTENTRY; typedef struct _BIOSDISKENTRY { - LIST_ENTRY ListEntry; - ULONG DiskNumber; - ULONG Signature; - ULONG Checksum; - BOOLEAN Recognized; - CM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry; - CM_INT13_DRIVE_PARAMETER Int13DiskData; + LIST_ENTRY ListEntry; + ULONG DiskNumber; + ULONG Signature; + ULONG Checksum; + BOOLEAN Recognized; + CM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry; + CM_INT13_DRIVE_PARAMETER Int13DiskData; } BIOSDISKENTRY, *PBIOSDISKENTRY; typedef struct _DISKENTRY { - LIST_ENTRY ListEntry; + LIST_ENTRY ListEntry; - ULONGLONG Cylinders; - ULONGLONG TracksPerCylinder; - ULONGLONG SectorsPerTrack; - ULONGLONG BytesPerSector; + ULONGLONG Cylinders; + ULONGLONG TracksPerCylinder; + ULONGLONG SectorsPerTrack; + ULONGLONG BytesPerSector; - ULONGLONG DiskSize; - ULONGLONG CylinderSize; - ULONGLONG TrackSize; + ULONGLONG DiskSize; + ULONGLONG CylinderSize; + ULONGLONG TrackSize; - BOOLEAN BiosFound; - ULONG BiosDiskNumber; - ULONG Signature; - ULONG Checksum; + BOOLEAN BiosFound; + ULONG BiosDiskNumber; + ULONG Signature; + ULONG Checksum; - ULONG DiskNumber; - USHORT Port; - USHORT Bus; - USHORT Id; + ULONG DiskNumber; + USHORT Port; + USHORT Bus; + USHORT Id; - /* Has the partition list been modified? */ - BOOLEAN Modified; + /* Has the partition list been modified? */ + BOOLEAN Modified; - BOOLEAN NewDisk; - BOOLEAN NoMbr; /* MBR is absent */ + BOOLEAN NewDisk; + BOOLEAN NoMbr; /* MBR is absent */ - UNICODE_STRING DriverName; + UNICODE_STRING DriverName; - LIST_ENTRY PartListHead; + LIST_ENTRY PartListHead; } DISKENTRY, *PDISKENTRY; typedef struct _PARTLIST { - SHORT Left; - SHORT Top; - SHORT Right; - SHORT Bottom; + SHORT Left; + SHORT Top; + SHORT Right; + SHORT Bottom; - SHORT Line; - SHORT Offset; + SHORT Line; + SHORT Offset; - ULONG TopDisk; - ULONG TopPartition; + ULONG TopDisk; + ULONG TopPartition; - PDISKENTRY CurrentDisk; - PPARTENTRY CurrentPartition; - UCHAR CurrentPartitionNumber; + PDISKENTRY CurrentDisk; + PPARTENTRY CurrentPartition; + UCHAR CurrentPartitionNumber; - PDISKENTRY ActiveBootDisk; - PPARTENTRY ActiveBootPartition; - UCHAR ActiveBootPartitionNumber; + PDISKENTRY ActiveBootDisk; + PPARTENTRY ActiveBootPartition; + UCHAR ActiveBootPartitionNumber; - LIST_ENTRY DiskListHead; - LIST_ENTRY BiosDiskListHead; + LIST_ENTRY DiskListHead; + LIST_ENTRY BiosDiskListHead; } PARTLIST, *PPARTLIST; @@ -149,76 +149,90 @@ typedef struct _PARTLIST typedef struct _PARTITION { - unsigned char BootFlags; /* bootable? 0=no, 128=yes */ - unsigned char StartingHead; /* beginning head number */ - unsigned char StartingSector; /* beginning sector number */ - unsigned char StartingCylinder; /* 10 bit nmbr, with high 2 bits put in begsect */ - unsigned char PartitionType; /* Operating System type indicator code */ - unsigned char EndingHead; /* ending head number */ - unsigned char EndingSector; /* ending sector number */ - unsigned char EndingCylinder; /* also a 10 bit nmbr, with same high 2 bit trick */ - unsigned int StartingBlock; /* first sector relative to start of disk */ - unsigned int SectorCount; /* number of sectors in partition */ + unsigned char BootFlags; /* bootable? 0=no, 128=yes */ + unsigned char StartingHead; /* beginning head number */ + unsigned char StartingSector; /* beginning sector number */ + unsigned char StartingCylinder; /* 10 bit nmbr, with high 2 bits put in begsect */ + unsigned char PartitionType; /* Operating System type indicator code */ + unsigned char EndingHead; /* ending head number */ + unsigned char EndingSector; /* ending sector number */ + unsigned char EndingCylinder; /* also a 10 bit nmbr, with same high 2 bit trick */ + unsigned int StartingBlock; /* first sector relative to start of disk */ + unsigned int SectorCount; /* number of sectors in partition */ } PARTITION, *PPARTITION; typedef struct _PARTITION_SECTOR { - UCHAR BootCode[440]; /* 0x000 */ - ULONG Signature; /* 0x1B8 */ - UCHAR Reserved[2]; /* 0x1BC */ - PARTITION Partition[PARTITION_TBL_SIZE]; /* 0x1BE */ - USHORT Magic; /* 0x1FE */ + UCHAR BootCode[440]; /* 0x000 */ + ULONG Signature; /* 0x1B8 */ + UCHAR Reserved[2]; /* 0x1BC */ + PARTITION Partition[PARTITION_TBL_SIZE]; /* 0x1BE */ + USHORT Magic; /* 0x1FE */ } PARTITION_SECTOR, *PPARTITION_SECTOR; #include typedef struct { - LIST_ENTRY ListEntry; - ULONG DiskNumber; - ULONG Idendifier; - ULONG Signature; + LIST_ENTRY ListEntry; + ULONG DiskNumber; + ULONG Idendifier; + ULONG Signature; } BIOS_DISK, *PBIOS_DISK; PPARTLIST -CreatePartitionList (SHORT Left, - SHORT Top, - SHORT Right, - SHORT Bottom); +CreatePartitionList( + SHORT Left, + SHORT Top, + SHORT Right, + SHORT Bottom); VOID -DestroyPartitionList (PPARTLIST List); +DestroyPartitionList( + PPARTLIST List); VOID -DrawPartitionList (PPARTLIST List); +DrawPartitionList( + PPARTLIST List); DWORD -SelectPartition(PPARTLIST List, ULONG DiskNumber, ULONG PartitionNumber); +SelectPartition( + PPARTLIST List, + ULONG DiskNumber, + ULONG PartitionNumber); BOOL -SetMountedDeviceValues(PPARTLIST List); +SetMountedDeviceValues( + PPARTLIST List); VOID -ScrollDownPartitionList (PPARTLIST List); +ScrollDownPartitionList( + PPARTLIST List); VOID -ScrollUpPartitionList (PPARTLIST List); +ScrollUpPartitionList( + PPARTLIST List); VOID -CreateNewPartition (PPARTLIST List, - ULONGLONG PartitionSize, - BOOLEAN AutoCreate); +CreateNewPartition( + PPARTLIST List, + ULONGLONG PartitionSize, + BOOLEAN AutoCreate); VOID -DeleteCurrentPartition (PPARTLIST List); +DeleteCurrentPartition( + PPARTLIST List); VOID -CheckActiveBootPartition (PPARTLIST List); +CheckActiveBootPartition( + PPARTLIST List); BOOLEAN -CheckForLinuxFdiskPartitions (PPARTLIST List); +CheckForLinuxFdiskPartitions( + PPARTLIST List); BOOLEAN -WritePartitionsToDisk (PPARTLIST List); +WritePartitionsToDisk( + PPARTLIST List); /* EOF */ diff --git a/base/shell/cmd/alias.c b/base/shell/cmd/alias.c index 4c71d378bec..ac5129aef9b 100644 --- a/base/shell/cmd/alias.c +++ b/base/shell/cmd/alias.c @@ -58,7 +58,7 @@ PrintAlias (VOID) DWORD len; len = GetConsoleAliasesLength(_T("cmd.exe")); - if (len <= 0) + if (len == 0) return; /* allocate memory for an extra \0 char to make parsing easier */ diff --git a/base/shell/cmd/cmd.c b/base/shell/cmd/cmd.c index 2a56ed93c55..40cddc364a9 100644 --- a/base/shell/cmd/cmd.c +++ b/base/shell/cmd/cmd.c @@ -397,13 +397,13 @@ Execute(LPTSTR Full, LPTSTR First, LPTSTR Rest, PARSED_COMMAND *Cmd) /* build command line for CreateProcess(): FullName + " " + rest */ BOOL quoted = !!_tcschr(First, ' '); _tcscpy(szFullCmdLine, quoted ? _T("\"") : _T("")); - _tcsncat(szFullCmdLine, First, CMDLINE_LENGTH - _tcslen(szFullCmdLine)); - _tcsncat(szFullCmdLine, quoted ? _T("\"") : _T(""), CMDLINE_LENGTH - _tcslen(szFullCmdLine)); + _tcsncat(szFullCmdLine, First, CMDLINE_LENGTH - _tcslen(szFullCmdLine) - 1); + _tcsncat(szFullCmdLine, quoted ? _T("\"") : _T(""), CMDLINE_LENGTH - _tcslen(szFullCmdLine) - 1); if (*rest) { - _tcsncat(szFullCmdLine, _T(" "), CMDLINE_LENGTH - _tcslen(szFullCmdLine)); - _tcsncat(szFullCmdLine, rest, CMDLINE_LENGTH - _tcslen(szFullCmdLine)); + _tcsncat(szFullCmdLine, _T(" "), CMDLINE_LENGTH - _tcslen(szFullCmdLine) - 1); + _tcsncat(szFullCmdLine, rest, CMDLINE_LENGTH - _tcslen(szFullCmdLine) - 1); } TRACE ("[EXEC: %s]\n", debugstr_aw(szFullCmdLine)); diff --git a/base/shell/explorer/services/startup.c b/base/shell/explorer/services/startup.c index b0dbf43c8ec..875166ebf92 100644 --- a/base/shell/explorer/services/startup.c +++ b/base/shell/explorer/services/startup.c @@ -93,7 +93,7 @@ static BOOL pendingRename() } else { - printf("Couldn't open key, error %ld\n", res); + printf("Couldn't open key, error %lu\n", res); res=FALSE; } @@ -113,7 +113,7 @@ static BOOL pendingRename() if (res!=ERROR_SUCCESS) { - printf("Couldn't query value's length (%ld)\n", res); + printf("Couldn't query value's length (%lu)\n", res); res=FALSE; goto end; } @@ -369,7 +369,7 @@ static BOOL ProcessRunKeys(HKEY hkRoot, LPCWSTR szKeyName, BOOL bDelete, if ((res=RegEnumValueW(hkRun, i, szValue, &nValLength, 0, &type, (LPBYTE)szCmdLine, &nDataLength))!=ERROR_SUCCESS) { - printf("Couldn't read in value %ld - %ld\n", i, res); + printf("Couldn't read in value %lu - %ld\n", i, res); continue; } @@ -379,22 +379,22 @@ static BOOL ProcessRunKeys(HKEY hkRoot, LPCWSTR szKeyName, BOOL bDelete, if (bDelete && (res=RegDeleteValueW(hkRun, szValue))!=ERROR_SUCCESS) { - printf("Couldn't delete value - %ld, %ld. Running command anyways.\n", i, res); + printf("Couldn't delete value - %lu, %ld. Running command anyways.\n", i, res); } if (type!=REG_SZ) { - printf("Incorrect type of value #%ld (%ld)\n", i, type); + printf("Incorrect type of value #%lu (%lu)\n", i, type); continue; } if ((res=runCmd(szCmdLine, NULL, bSynchronous, FALSE))==INVALID_RUNCMD_RETURN) { - printf("Error running cmd #%ld (%ld)\n", i, GetLastError()); + printf("Error running cmd #%lu (%ld)\n", i, GetLastError()); } - printf("Done processing cmd #%ld\n", i); + printf("Done processing cmd #%lu\n", i); } free(szValue); diff --git a/base/system/msiexec/service.c b/base/system/msiexec/service.c index 47a28591d23..831a68049b7 100644 --- a/base/system/msiexec/service.c +++ b/base/system/msiexec/service.c @@ -73,7 +73,7 @@ static BOOL UpdateSCMStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, static void WINAPI ServiceCtrlHandler(DWORD code) { - WINE_TRACE("%d\n", code); + WINE_TRACE("%u\n", code); switch (code) { @@ -83,7 +83,7 @@ static void WINAPI ServiceCtrlHandler(DWORD code) KillService(); return; default: - fprintf(stderr, "Unhandled service control code: %d\n", code); + fprintf(stderr, "Unhandled service control code: %u\n", code); break; } diff --git a/base/system/services/database.c b/base/system/services/database.c index aea3f8950bb..39563d82db9 100644 --- a/base/system/services/database.c +++ b/base/system/services/database.c @@ -99,7 +99,7 @@ ScmCreateNewControlPipe(PSERVICE_IMAGE pServiceImage) } /* Create '\\.\pipe\net\NtControlPipeXXX' instance */ - swprintf(szControlPipeName, L"\\\\.\\pipe\\net\\NtControlPipe%u", ServiceCurrent); + swprintf(szControlPipeName, L"\\\\.\\pipe\\net\\NtControlPipe%lu", ServiceCurrent); DPRINT("PipeName: %S\n", szControlPipeName); diff --git a/boot/armllb/os/loader.c b/boot/armllb/os/loader.c index 05689d93c77..addf9dc1ab5 100644 --- a/boot/armllb/os/loader.c +++ b/boot/armllb/os/loader.c @@ -115,7 +115,7 @@ LlbHwLoadOsLoaderFromRam(VOID) /* Set parameters for the OS loader */ snprintf(CommandLine, sizeof(CommandLine), - "rdbase=0x%x rdsize=0x%x rdoffset=%s", + "rdbase=0x%lx rdsize=0x%lx rdoffset=%s", RootFs, Size, Offset); LlbSetCommandLine(CommandLine); diff --git a/boot/bootdata/hivedef.inf b/boot/bootdata/hivedef.inf index 8868895778e..5902c686257 100644 --- a/boot/bootdata/hivedef.inf +++ b/boot/bootdata/hivedef.inf @@ -1636,7 +1636,8 @@ HKCU,"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons",,0x00 HKCU,"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\ClassicStartMenu",,0x00000012 HKCU,"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\ClassicStartMenu","{208D2C60-3AEA-1069-A2D7-08002B30309D}",0x00010001,0x00000000 HKCU,"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}",,0x00000012 -HKCU,"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced","ListviewShadow",0x00010001,0x1 +HKCU,"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced","ListviewShadow",0x00010001,0x00000001 +HKCU,"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced","HideFileExt",0x00010001,0x00000000 ; default shell HKCU,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon",,0x00000012 diff --git a/boot/bootdata/hivesft.inf b/boot/bootdata/hivesft.inf index d862f46d738..ee01f6838f9 100644 --- a/boot/bootdata/hivesft.inf +++ b/boot/bootdata/hivesft.inf @@ -1342,7 +1342,7 @@ HKLM,"SOFTWARE\Microsoft\Ole","EnableRemoteConnect",0x00000000,"N" ; SvcHost services HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SvcHost",,0x00000012 -HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SvcHost", "netsvcs",0x00010000,"DHCP" +HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\SvcHost", "netsvcs",0x00010000,"DHCP","BITS" ; Win32 config HKLM,"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows",,0x00000012 diff --git a/boot/bootdata/hivesys.inf b/boot/bootdata/hivesys.inf index 7d8858cb8c4..8433438a741 100644 --- a/boot/bootdata/hivesys.inf +++ b/boot/bootdata/hivesys.inf @@ -1304,6 +1304,16 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Beep","ImagePath",0x00020000,"system32\d HKLM,"SYSTEM\CurrentControlSet\Services\Beep","Start",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\Beep","Type",0x00010001,0x00000001 +; Background Intelligent Transfer Service (BITS) +HKLM,"SYSTEM\CurrentControlSet\Services\BITS","DisplayName",0x00000000,"BITS" +HKLM,"SYSTEM\CurrentControlSet\Services\BITS","Description",0x00000000,"Background Intelligent Transfer Service (BITS)" +HKLM,"SYSTEM\CurrentControlSet\Services\BITS","ErrorControl",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\BITS","ImagePath",0x00020000,"%SystemRoot%\system32\svchost.exe -k netsvcs" +HKLM,"SYSTEM\CurrentControlSet\Services\BITS","ObjectName",0x00000000,"LocalSystem" +HKLM,"SYSTEM\CurrentControlSet\Services\BITS","Start",0x00010001,0x00000003 +HKLM,"SYSTEM\CurrentControlSet\Services\BITS","Type",0x00010001,0x00000020 +HKLM,"SYSTEM\CurrentControlSet\Services\BITS\Parameters","ServiceDll",0x00020000,"%SystemRoot%\system32\qmgr.dll" + ; BlueScreen device driver HKLM,"SYSTEM\CurrentControlSet\Services\Blue","ErrorControl",0x00010001,0x00000000 HKLM,"SYSTEM\CurrentControlSet\Services\Blue","Group",0x00000000,"Video Init" @@ -1393,13 +1403,6 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Fs_Rec","ImagePath",0x00020000,"system32 HKLM,"SYSTEM\CurrentControlSet\Services\Fs_Rec","Start",0x00010001,0x00000001 HKLM,"SYSTEM\CurrentControlSet\Services\Fs_Rec","Type",0x00010001,0x00000008 -; Kernel-Mode Tests -;HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","ErrorControl",0x00010001,0x00000000 -;HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","Group",0x00000000,"Base" -;HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","ImagePath",0x00020000,"system32\drivers\kmtest.sys" -;HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","Start",0x00010001,0x00000001 -;HKLM,"SYSTEM\CurrentControlSet\Services\Kmtest","Type",0x00010001,0x00000001 - ; Keyboard class driver HKLM,"SYSTEM\CurrentControlSet\Services\kbdclass","ErrorControl",0x00010001,0x00000000 HKLM,"SYSTEM\CurrentControlSet\Services\kbdclass","Group",0x00000000,"Keyboard Class" diff --git a/boot/bootdata/packages/reactos.dff.in b/boot/bootdata/packages/reactos.dff.in index 2b8ff15e791..0986c54c8bb 100644 --- a/boot/bootdata/packages/reactos.dff.in +++ b/boot/bootdata/packages/reactos.dff.in @@ -61,5 +61,5 @@ Signature = "$ReactOS$" "modules/optional/vmx_mode.dll" 1 optional "modules/optional/vmx_svga.inf" 6 optional "modules/optional/vmx_svga.sys" 2 optional -"modules/optional/wine_gecko-2.21-x86.msi" 4 optional +"modules/optional/wine_gecko-2.24-x86.msi" 4 optional "boot/bootdata/bootcdregtest/AHKAppTests.cmd" 7 optional diff --git a/boot/freeldr/freeldr/include/mm.h b/boot/freeldr/freeldr/include/mm.h index 3f75508aa77..2b2a71fc296 100644 --- a/boot/freeldr/freeldr/include/mm.h +++ b/boot/freeldr/freeldr/include/mm.h @@ -170,16 +170,16 @@ FrLdrHeapFree(PVOID MemoryPointer, ULONG Tag) FrLdrHeapFreeEx(FrLdrDefaultHeap, MemoryPointer, Tag); } -PVOID FORCEINLINE +PVOID FrLdrTempAlloc( ULONG Size, ULONG Tag) { return FrLdrHeapAllocateEx(FrLdrTempHeap, Size, Tag); } -VOID FORCEINLINE +VOID FrLdrTempFree( PVOID Allocation, ULONG Tag) { diff --git a/cmake/gcc.cmake b/cmake/gcc.cmake index c6da9b8c19e..9b534c5a516 100644 --- a/cmake/gcc.cmake +++ b/cmake/gcc.cmake @@ -36,6 +36,9 @@ if(CMAKE_C_COMPILER_ID STREQUAL "Clang") add_compile_flags("-Wno-microsoft") endif() +if(DBG) + add_compile_flags_language("-Wold-style-declaration -Wdeclaration-after-statement" "C") +endif() add_compile_flags_language("-fno-rtti -fno-exceptions" "CXX") #bug diff --git a/configure.sh b/configure.sh index 6ba64a44cd5..be49ba464e3 100755 --- a/configure.sh +++ b/configure.sh @@ -59,6 +59,6 @@ echo Preparing reactos... cd ../reactos rm -f CMakeCache.txt -cmake -G "$CMAKE_GENERATOR" -DENABLE_CCACHE:BOOL=1 -DCMAKE_TOOLCHAIN_FILE:FILEPATH=toolchain-gcc.cmake -DARCH:STRING=$ARCH -DREACTOS_BUILD_TOOLS_DIR:PATH="$REACTOS_BUILD_TOOLS_DIR" $ROS_CMAKEOPTS "$REACTOS_SOURCE_DIR" +cmake -G "$CMAKE_GENERATOR" -DENABLE_CCACHE:BOOL=0 -DCMAKE_TOOLCHAIN_FILE:FILEPATH=toolchain-gcc.cmake -DARCH:STRING=$ARCH -DREACTOS_BUILD_TOOLS_DIR:PATH="$REACTOS_BUILD_TOOLS_DIR" $ROS_CMAKEOPTS "$REACTOS_SOURCE_DIR" echo Configure script complete! Enter directories and execute appropriate build commands \(ex: ninja, make, makex, etc...\). diff --git a/dll/cpl/appwiz/addons.c b/dll/cpl/appwiz/addons.c index eca42a51e97..12b847298ea 100644 --- a/dll/cpl/appwiz/addons.c +++ b/dll/cpl/appwiz/addons.c @@ -26,11 +26,11 @@ #include -#define GECKO_VERSION "2.21" +#define GECKO_VERSION "2.24" #ifdef __i386__ #define ARCH_STRING "x86" -#define GECKO_SHA "a514fc4d53783a586c7880a676c415695fe934a3" +#define GECKO_SHA "b4923c0565e6cbd20075a0d4119ce3b48424f962" #else #define ARCH_STRING "" #define GECKO_SHA "???" @@ -60,7 +60,7 @@ static const addon_info_t *addon; static HWND install_dialog = NULL; -static WCHAR GeckoUrl[] = L"http://dl.dropboxusercontent.com/u/743491/ReactOS/wine_gecko-2.21-x86.msi"; +static WCHAR GeckoUrl[] = L"http://dl.dropboxusercontent.com/u/743491/ReactOS/wine_gecko-2.24-x86.msi"; /* SHA definitions are copied from advapi32. They aren't available in headers. */ diff --git a/dll/ntdll/ldr/ldrapi.c b/dll/ntdll/ldr/ldrapi.c index a6af75f230e..3e094630916 100644 --- a/dll/ntdll/ldr/ldrapi.c +++ b/dll/ntdll/ldr/ldrapi.c @@ -82,8 +82,8 @@ LdrAlternateResourcesEnabled(VOID) return FALSE; } -ULONG_PTR FORCEINLINE +ULONG_PTR LdrpMakeCookie(VOID) { /* Generate a cookie */ diff --git a/dll/ntdll/ldr/ldrutils.c b/dll/ntdll/ldr/ldrutils.c index 8c192c08742..3cc7608417e 100644 --- a/dll/ntdll/ldr/ldrutils.c +++ b/dll/ntdll/ldr/ldrutils.c @@ -2054,8 +2054,8 @@ lookinhash: if (ShowSnaps) { - DPRINT1("LDR: LdrpCheckForLoadedDll - Unable To Locate %ws: 0x%08x\n", - DllName->Buffer, Length); + DPRINT1("LDR: LdrpCheckForLoadedDll - Unable To Locate %wZ: 0x%08x\n", + &DllName, Length); } /* Return failure */ @@ -2333,7 +2333,8 @@ LdrpGetProcedureAddress(IN PVOID BaseAddress, if (!ExportDir) { - DPRINT1("Image %wZ has no exports, but were trying to get procedure %s. BaseAddress asked %p, got entry BA %p\n", &LdrEntry->BaseDllName, Name ? Name->Buffer : NULL, BaseAddress, LdrEntry->DllBase); + DPRINT1("Image %wZ has no exports, but were trying to get procedure %Z. BaseAddress asked 0x%p, got entry BA 0x%p\n", + &LdrEntry->BaseDllName, &Name, BaseAddress, LdrEntry->DllBase); Status = STATUS_PROCEDURE_NOT_FOUND; _SEH2_YIELD(goto Quickie;) } diff --git a/dll/win32/atl/CMakeLists.txt b/dll/win32/atl/CMakeLists.txt index 04bb786a745..1d7d6bbc536 100644 --- a/dll/win32/atl/CMakeLists.txt +++ b/dll/win32/atl/CMakeLists.txt @@ -11,13 +11,18 @@ include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine) spec2def(atl.dll atl.spec ADD_IMPORTLIB) list(APPEND SOURCE - atl_main.c + atl.c + atl30.c + atl_ax.c + registrar.c + precomp.h ${CMAKE_CURRENT_BINARY_DIR}/atl_stubs.c ${CMAKE_CURRENT_BINARY_DIR}/atl.def) add_library(atl SHARED ${SOURCE} rsrc.rc) set_module_type(atl win32dll) target_link_libraries(atl uuid wine) -add_importlibs(atl atl100 atl80 oleaut32 ole32 user32 msvcrt kernel32 ntdll) +add_importlibs(atl oleaut32 ole32 user32 gdi32 advapi32 msvcrt kernel32 ntdll) add_dependencies(atl atl_atliface_header) +add_pch(atl precomp.h SOURCE) add_cd_file(TARGET atl DESTINATION reactos/system32 FOR all) diff --git a/dll/win32/atl100/atl.c b/dll/win32/atl/atl.c similarity index 92% rename from dll/win32/atl100/atl.c rename to dll/win32/atl/atl.c index 1dbda7f423f..8cc8eda1983 100644 --- a/dll/win32/atl100/atl.c +++ b/dll/win32/atl/atl.c @@ -17,11 +17,13 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include #include -WINE_DEFAULT_DEBUG_CHANNEL(atl100); +#define ATLVer1Size FIELD_OFFSET(_ATL_MODULEW, dwAtlBuildVer) + +HINSTANCE atl_instance; typedef unsigned char cpp_bool; @@ -296,18 +298,22 @@ HRESULT WINAPI AtlModuleAddTermFunc(_ATL_MODULE *pM, _ATL_TERMFUNC *pFunc, DWORD { _ATL_TERMFUNC_ELEM *termfunc_elem; - TRACE("(%p %p %ld)\n", pM, pFunc, dw); + TRACE("version %04x (%p %p %ld)\n", _ATL_VER, pM, pFunc, dw); - termfunc_elem = HeapAlloc(GetProcessHeap(), 0, sizeof(_ATL_TERMFUNC_ELEM)); - termfunc_elem->pFunc = pFunc; - termfunc_elem->dw = dw; - termfunc_elem->pNext = pM->m_pTermFuncs; + if (_ATL_VER > _ATL_VER_30 || pM->cbSize > ATLVer1Size) { + termfunc_elem = HeapAlloc(GetProcessHeap(), 0, sizeof(_ATL_TERMFUNC_ELEM)); + termfunc_elem->pFunc = pFunc; + termfunc_elem->dw = dw; + termfunc_elem->pNext = pM->m_pTermFuncs; - pM->m_pTermFuncs = termfunc_elem; + pM->m_pTermFuncs = termfunc_elem; + } return S_OK; } +#if _ATL_VER > _ATL_VER_30 + /*********************************************************************** * AtlCallTermFunc [atl100.@] */ @@ -327,6 +333,8 @@ void WINAPI AtlCallTermFunc(_ATL_MODULE *pM) pM->m_pTermFuncs = NULL; } +#endif + /*********************************************************************** * AtlLoadTypeLib [atl100.56] */ @@ -383,12 +391,39 @@ HRESULT WINAPI AtlLoadTypeLib(HINSTANCE inst, LPCOLESTR lpszIndex, return S_OK; } +#if _ATL_VER <= _ATL_VER_80 + +/*********************************************************************** + * AtlRegisterTypeLib [atl80.19] + */ +HRESULT WINAPI AtlRegisterTypeLib(HINSTANCE inst, const WCHAR *index) +{ + ITypeLib *typelib; + BSTR path; + HRESULT hres; + + TRACE("(%p %s)\n", inst, debugstr_w(index)); + + hres = AtlLoadTypeLib(inst, index, &path, &typelib); + if(FAILED(hres)) + return hres; + + hres = RegisterTypeLib(typelib, path, NULL); /* FIXME: pass help directory */ + ITypeLib_Release(typelib); + SysFreeString(path); + return hres; +} + +#endif + +#if _ATL_VER > _ATL_VER_30 + /*********************************************************************** * AtlWinModuleInit [atl100.65] */ HRESULT WINAPI AtlWinModuleInit(_ATL_WIN_MODULE *winmod) { - TRACE("(%p\n", winmod); + TRACE("(%p)\n", winmod); if(winmod->cbSize != sizeof(*winmod)) return E_INVALIDARG; @@ -499,7 +534,28 @@ HRESULT WINAPI AtlComModuleRegisterClassObjects(_ATL_COM_MODULE *module, DWORD c } return S_OK; +} +/*********************************************************************** + * AtlComModuleRevokeClassObjects [atl100.20] + */ +HRESULT WINAPI AtlComModuleRevokeClassObjects(_ATL_COM_MODULE *module) +{ + _ATL_OBJMAP_ENTRY **iter; + HRESULT hres; + + TRACE("(%p)\n", module); + + if(!module) + return E_INVALIDARG; + + for(iter = module->m_ppAutoObjMapFirst; iter < module->m_ppAutoObjMapLast; iter++) { + hres = CoRevokeClassObject((*iter)->dwRegister); + if(FAILED(hres)) + return hres; + } + + return S_OK; } /*********************************************************************** @@ -554,6 +610,8 @@ HRESULT WINAPI AtlComModuleUnregisterServer(_ATL_COM_MODULE *mod, BOOL bRegTypeL return S_OK; } +#endif + /*********************************************************************** * AtlRegisterClassCategoriesHelper [atl100.49] */ @@ -757,6 +815,8 @@ HRESULT WINAPI AtlGetObjectSourceInterface(IUnknown *unk, GUID *libid, IID *iid, return hres; } +#if _ATL_VER >= _ATL_VER90 + /*********************************************************************** * AtlSetPerUserRegistration [atl100.67] */ @@ -776,12 +836,15 @@ HRESULT WINAPI AtlGetPerUserRegistration(cpp_bool *pbEnabled) return S_OK; } +#endif + /*********************************************************************** * AtlGetVersion [atl100.@] */ DWORD WINAPI AtlGetVersion(void *pReserved) { - return _ATL_VER; + TRACE("version %04x (%p)\n", _ATL_VER, pReserved); + return _ATL_VER; } BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) @@ -790,6 +853,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) switch(fdwReason) { case DLL_PROCESS_ATTACH: + atl_instance = hinstDLL; DisableThreadLibraryCalls(hinstDLL); break; case DLL_PROCESS_DETACH: diff --git a/dll/win32/atl/atl.spec b/dll/win32/atl/atl.spec index a4b6d07979a..437a555f68c 100644 --- a/dll/win32/atl/atl.spec +++ b/dll/win32/atl/atl.spec @@ -2,11 +2,11 @@ @ stdcall -private DllGetClassObject(ptr ptr ptr) @ stdcall -private DllRegisterServer() @ stdcall -private DllUnregisterServer() -10 stdcall AtlAdvise(ptr ptr ptr ptr) atl100.AtlAdvise -11 stdcall AtlUnadvise(ptr ptr long) atl100.AtlUnadvise -12 stdcall AtlFreeMarshalStream(ptr) atl100.AtlFreeMarshalStream -13 stdcall AtlMarshalPtrInProc(ptr ptr ptr) atl100.AtlMarshalPtrInProc -14 stdcall AtlUnmarshalPtr(ptr ptr ptr) atl100.AtlUnmarshalPtr +10 stdcall AtlAdvise(ptr ptr ptr ptr) +11 stdcall AtlUnadvise(ptr ptr long) +12 stdcall AtlFreeMarshalStream(ptr) +13 stdcall AtlMarshalPtrInProc(ptr ptr ptr) +14 stdcall AtlUnmarshalPtr(ptr ptr ptr) 15 stdcall AtlModuleGetClassObject(ptr ptr ptr ptr) 16 stdcall AtlModuleInit(ptr long long) 17 stdcall AtlModuleRegisterClassObjects(ptr long long) @@ -16,36 +16,36 @@ 21 stdcall AtlModuleTerm(ptr) 22 stdcall AtlModuleUnregisterServer(ptr ptr) 23 stdcall AtlModuleUpdateRegistryFromResourceD(ptr wstr long ptr ptr) -24 stdcall AtlWaitWithMessageLoop(long) atl100.AtlWaitWithMessageLoop +24 stdcall AtlWaitWithMessageLoop(long) 25 stub AtlSetErrorInfo -26 stdcall AtlCreateTargetDC(long ptr) atl100.AtlCreateTargetDC -27 stdcall AtlHiMetricToPixel(ptr ptr) atl100.AtlHiMetricToPixel -28 stdcall AtlPixelToHiMetric(ptr ptr) atl100.AtlPixelToHiMetric +26 stdcall AtlCreateTargetDC(long ptr) +27 stdcall AtlHiMetricToPixel(ptr ptr) +28 stdcall AtlPixelToHiMetric(ptr ptr) 29 stub AtlDevModeW2A -30 stdcall AtlComPtrAssign(ptr ptr) atl100.AtlComPtrAssign -31 stdcall AtlComQIPtrAssign(ptr ptr ptr) atl100.AtlComQIPtrAssign -32 stdcall AtlInternalQueryInterface(ptr ptr ptr ptr) atl100.AtlInternalQueryInterface +30 stdcall AtlComPtrAssign(ptr ptr) +31 stdcall AtlComQIPtrAssign(ptr ptr ptr) +32 stdcall AtlInternalQueryInterface(ptr ptr ptr ptr) 34 stdcall AtlGetVersion(ptr) -35 stdcall AtlAxDialogBoxW(long wstr long ptr long) atl100.AtlAxDialogBoxW -36 stdcall AtlAxDialogBoxA(long str long ptr long) atl100.AtlAxDialogBoxA -37 stdcall AtlAxCreateDialogW(long wstr long ptr long) atl100.AtlAxCreateDialogW -38 stdcall AtlAxCreateDialogA(long str long ptr long) atl100.AtlAxCreateDialogA -39 stdcall AtlAxCreateControl(ptr ptr ptr ptr) atl100.AtlAxCreateControl -40 stdcall AtlAxCreateControlEx(ptr ptr ptr ptr ptr ptr ptr) atl100.AtlAxCreateControlEx -41 stdcall AtlAxAttachControl(ptr ptr ptr) atl100.AtlAxAttachControl +35 stdcall AtlAxDialogBoxW(long wstr long ptr long) +36 stdcall AtlAxDialogBoxA(long str long ptr long) +37 stdcall AtlAxCreateDialogW(long wstr long ptr long) +38 stdcall AtlAxCreateDialogA(long str long ptr long) +39 stdcall AtlAxCreateControl(ptr ptr ptr ptr) +40 stdcall AtlAxCreateControlEx(ptr ptr ptr ptr ptr ptr ptr) +41 stdcall AtlAxAttachControl(ptr ptr ptr) 42 stdcall AtlAxWinInit() 43 stdcall AtlModuleAddCreateWndData(ptr ptr ptr) 44 stdcall AtlModuleExtractCreateWndData(ptr) 45 stdcall AtlModuleRegisterWndClassInfoW(ptr ptr ptr) 46 stdcall AtlModuleRegisterWndClassInfoA(ptr ptr ptr) -47 stdcall AtlAxGetControl(long ptr) atl100.AtlAxGetControl -48 stdcall AtlAxGetHost(long ptr) atl100.AtlAxGetHost -49 stdcall AtlRegisterClassCategoriesHelper(ptr ptr long) atl100.AtlRegisterClassCategoriesHelper -50 stdcall AtlIPersistStreamInit_Load(ptr ptr ptr ptr) atl100.AtlIPersistStreamInit_Load -51 stdcall AtlIPersistStreamInit_Save(ptr long ptr ptr ptr) atl100.AtlIPersistStreamInit_Save -52 stdcall AtlIPersistPropertyBag_Load(ptr ptr ptr ptr ptr) atl100.AtlIPersistPropertyBag_Load +47 stdcall AtlAxGetControl(long ptr) +48 stdcall AtlAxGetHost(long ptr) +49 stdcall AtlRegisterClassCategoriesHelper(ptr ptr long) +50 stdcall AtlIPersistStreamInit_Load(ptr ptr ptr ptr) +51 stdcall AtlIPersistStreamInit_Save(ptr long ptr ptr ptr) +52 stdcall AtlIPersistPropertyBag_Load(ptr ptr ptr ptr ptr) 53 stub AtlIPersistPropertyBag_Save -54 stdcall AtlGetObjectSourceInterface(ptr ptr ptr ptr ptr) atl100.AtlGetObjectSourceInterface +54 stdcall AtlGetObjectSourceInterface(ptr ptr ptr ptr ptr) 55 stub AtlModuleUnRegisterTypeLib 56 stdcall AtlModuleLoadTypeLib(ptr wstr ptr ptr) 57 stdcall AtlModuleUnregisterServerEx(ptr long ptr) diff --git a/dll/win32/atl/atl_main.c b/dll/win32/atl/atl30.c similarity index 86% rename from dll/win32/atl/atl_main.c rename to dll/win32/atl/atl30.c index 6abb826b49b..536f2b07afa 100644 --- a/dll/win32/atl/atl_main.c +++ b/dll/win32/atl/atl30.c @@ -19,40 +19,12 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#define WIN32_NO_STATUS -#define _INC_WINDOWS -#define COM_NO_WINDOWS_H +#include #include +#include -#define COBJMACROS - -#include -#include -#include -#include - -//#include "objidl.h" -#include -#include - -#include -#include - -WINE_DEFAULT_DEBUG_CHANNEL(atl); - -static HINSTANCE hInst; - -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - TRACE("(0x%p, %d, %p)\n",hinstDLL,fdwReason,lpvReserved); - - if (fdwReason == DLL_PROCESS_ATTACH) { - DisableThreadLibraryCalls(hinstDLL); - hInst = hinstDLL; - } - return TRUE; -} +extern HINSTANCE atl_instance; #define ATLVer1Size FIELD_OFFSET(_ATL_MODULEW, dwAtlBuildVer) @@ -150,25 +122,6 @@ HRESULT WINAPI AtlModuleTerm(_ATL_MODULE *pM) return S_OK; } -HRESULT WINAPI AtlModuleAddTermFunc(_ATL_MODULEW *pM, _ATL_TERMFUNC *pFunc, DWORD_PTR dw) -{ - _ATL_TERMFUNC_ELEM *termfunc_elem; - - TRACE("(%p %p %ld)\n", pM, pFunc, dw); - - if (pM->cbSize > ATLVer1Size) - { - termfunc_elem = HeapAlloc(GetProcessHeap(), 0, sizeof(_ATL_TERMFUNC_ELEM)); - termfunc_elem->pFunc = pFunc; - termfunc_elem->dw = dw; - termfunc_elem->pNext = pM->m_pTermFuncs; - - pM->m_pTermFuncs = termfunc_elem; - } - - return S_OK; -} - HRESULT WINAPI AtlModuleRegisterClassObjects(_ATL_MODULEW *pM, DWORD dwClsContext, DWORD dwFlags) { @@ -602,6 +555,7 @@ static HRESULT do_register_server(BOOL do_register) return do_register_dll_server(NULL, atl_dllW, MAKEINTRESOURCEW(101), do_register, reg_map); } + /************************************************************** * DllGetClassObject (ATL.2) */ @@ -640,59 +594,3 @@ HRESULT WINAPI DllCanUnloadNow(void) { return S_FALSE; } - -/*********************************************************************** - * AtlGetVersion [ATL.@] - */ -DWORD WINAPI AtlGetVersion(void *pReserved) -{ - return _ATL_VER; -} - -/********************************************************************** - * AtlAxWin class window procedure - */ -static LRESULT CALLBACK AtlAxWin_wndproc( HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam ) -{ - if ( wMsg == WM_CREATE ) - { - DWORD len = GetWindowTextLengthW( hWnd ) + 1; - WCHAR *ptr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) ); - if (!ptr) - return 1; - GetWindowTextW( hWnd, ptr, len ); - AtlAxCreateControlEx( ptr, hWnd, NULL, NULL, NULL, NULL, NULL ); - HeapFree( GetProcessHeap(), 0, ptr ); - return 0; - } - return DefWindowProcW( hWnd, wMsg, wParam, lParam ); -} - -BOOL WINAPI AtlAxWinInit(void) -{ - WNDCLASSEXW wcex; - const WCHAR AtlAxWin[] = {'A','t','l','A','x','W','i','n',0}; - - FIXME("semi-stub\n"); - - if ( FAILED( OleInitialize(NULL) ) ) - return FALSE; - - wcex.cbSize = sizeof(wcex); - wcex.style = CS_GLOBALCLASS; - wcex.cbClsExtra = 0; - wcex.cbWndExtra = 0; - wcex.hInstance = GetModuleHandleW( NULL ); - wcex.hIcon = NULL; - wcex.hCursor = NULL; - wcex.hbrBackground = NULL; - wcex.lpszMenuName = NULL; - wcex.hIconSm = 0; - - wcex.lpfnWndProc = AtlAxWin_wndproc; - wcex.lpszClassName = AtlAxWin; - if ( !RegisterClassExW( &wcex ) ) - return FALSE; - - return TRUE; -} diff --git a/dll/win32/atl100/atl_ax.c b/dll/win32/atl/atl_ax.c similarity index 97% rename from dll/win32/atl100/atl_ax.c rename to dll/win32/atl/atl_ax.c index 91b16cd2661..6743885b8e2 100644 --- a/dll/win32/atl100/atl_ax.c +++ b/dll/win32/atl/atl_ax.c @@ -18,13 +18,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" +#include #include #include -#include - -WINE_DEFAULT_DEBUG_CHANNEL(atl); +#include typedef struct IOCS { IOleClientSite IOleClientSite_iface; @@ -72,16 +70,30 @@ static LRESULT CALLBACK AtlAxWin_wndproc( HWND hWnd, UINT wMsg, WPARAM wParam, L BOOL WINAPI AtlAxWinInit(void) { WNDCLASSEXW wcex; - const WCHAR AtlAxWin100[] = {'A','t','l','A','x','W','i','n','1','0','0',0}; - const WCHAR AtlAxWinLic100[] = {'A','t','l','A','x','W','i','n','L','i','c','1','0','0',0}; - FIXME("semi-stub\n"); +#if _ATL_VER <= _ATL_VER_30 +#define ATL_NAME_SUFFIX 0 +#elif _ATL_VER == _ATL_VER_80 +#define ATL_NAME_SUFFIX '8','0',0 +#elif _ATL_VER == _ATL_VER_90 +#define ATL_NAME_SUFFIX '9','0',0 +#elif _ATL_VER == _ATL_VER_100 +#define ATL_NAME_SUFFIX '1','0','0',0 +#elif _ATL_VER == _ATL_VER_110 +#define ATL_NAME_SUFFIX '1','1','0',0 +#else +#error Unsupported version +#endif + + const WCHAR AtlAxWinW[] = {'A','t','l','A','x','W','i','n',ATL_NAME_SUFFIX}; + + FIXME("version %04x semi-stub\n", _ATL_VER); if ( FAILED( OleInitialize(NULL) ) ) return FALSE; wcex.cbSize = sizeof(wcex); - wcex.style = CS_GLOBALCLASS | CS_DBLCLKS; + wcex.style = CS_GLOBALCLASS | (_ATL_VER > _ATL_VER_30 ? CS_DBLCLKS : 0); wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = GetModuleHandleW( NULL ); @@ -92,13 +104,17 @@ BOOL WINAPI AtlAxWinInit(void) wcex.hIconSm = 0; wcex.lpfnWndProc = AtlAxWin_wndproc; - wcex.lpszClassName = AtlAxWin100; + wcex.lpszClassName = AtlAxWinW; if ( !RegisterClassExW( &wcex ) ) return FALSE; - wcex.lpszClassName = AtlAxWinLic100; - if ( !RegisterClassExW( &wcex ) ) - return FALSE; + if(_ATL_VER > _ATL_VER_30) { + const WCHAR AtlAxWinLicW[] = {'A','t','l','A','x','W','i','n','L','i','c',ATL_NAME_SUFFIX}; + + wcex.lpszClassName = AtlAxWinLicW; + if ( !RegisterClassExW( &wcex ) ) + return FALSE; + } return TRUE; } diff --git a/dll/win32/atl/atl_classes.idl b/dll/win32/atl/atl_classes.idl index 90605b41a40..aea795cd089 100644 --- a/dll/win32/atl/atl_classes.idl +++ b/dll/win32/atl/atl_classes.idl @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma makedep register + [ helpstring("Registrar Class"), progid("ATL.Registrar"), diff --git a/dll/win32/atl/precomp.h b/dll/win32/atl/precomp.h new file mode 100644 index 00000000000..def51b04e8f --- /dev/null +++ b/dll/win32/atl/precomp.h @@ -0,0 +1,25 @@ +#ifndef _ATL_PCH_ +#define _ATL_PCH_ + +#include + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#define COBJMACROS + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +WINE_DEFAULT_DEBUG_CHANNEL(atl); + +#endif /* _ATL_PCH_ */ diff --git a/dll/win32/atl100/registrar.c b/dll/win32/atl/registrar.c similarity index 98% rename from dll/win32/atl100/registrar.c rename to dll/win32/atl/registrar.c index 9da293f44a8..1c2207d56d7 100644 --- a/dll/win32/atl100/registrar.c +++ b/dll/win32/atl/registrar.c @@ -16,9 +16,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include "precomp.h" - -WINE_DEFAULT_DEBUG_CHANNEL(atl); +#include /************************************************************** * ATLRegistrar implementation @@ -490,15 +488,13 @@ static HRESULT file_register(Registrar *This, LPCOLESTR fileName, BOOL do_regist DWORD filelen, len; LPWSTR regstrw; LPSTR regstra; - LRESULT lres; HRESULT hres; - file = CreateFileW(fileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL); + file = CreateFileW(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if(file != INVALID_HANDLE_VALUE) { filelen = GetFileSize(file, NULL); regstra = HeapAlloc(GetProcessHeap(), 0, filelen); - lres = ReadFile(file, regstra, filelen, NULL, NULL); - if(lres == ERROR_SUCCESS) { + if(ReadFile(file, regstra, filelen, NULL, NULL)) { len = MultiByteToWideChar(CP_ACP, 0, regstra, filelen, NULL, 0)+1; regstrw = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len*sizeof(WCHAR)); MultiByteToWideChar(CP_ACP, 0, regstra, filelen, regstrw, len); @@ -508,13 +504,13 @@ static HRESULT file_register(Registrar *This, LPCOLESTR fileName, BOOL do_regist HeapFree(GetProcessHeap(), 0, regstrw); }else { - WARN("Failed to read faile\n"); - hres = HRESULT_FROM_WIN32(lres); + WARN("Failed to read file %s\n", debugstr_w(fileName)); + hres = HRESULT_FROM_WIN32(GetLastError()); } HeapFree(GetProcessHeap(), 0, regstra); CloseHandle(file); }else { - WARN("Could not open file\n"); + WARN("Could not open file %s\n", debugstr_w(fileName)); hres = HRESULT_FROM_WIN32(GetLastError()); } diff --git a/dll/win32/atl100/CMakeLists.txt b/dll/win32/atl100/CMakeLists.txt index 7efa34415d2..710e11786fb 100644 --- a/dll/win32/atl100/CMakeLists.txt +++ b/dll/win32/atl100/CMakeLists.txt @@ -11,9 +11,9 @@ include_directories(${REACTOS_SOURCE_DIR}/include/reactos/wine) spec2def(atl100.dll atl100.spec ADD_IMPORTLIB) list(APPEND SOURCE - atl.c - atl_ax.c - registrar.c + ${REACTOS_SOURCE_DIR}/dll/win32/atl/atl.c + ${REACTOS_SOURCE_DIR}/dll/win32/atl/atl_ax.c + ${REACTOS_SOURCE_DIR}/dll/win32/atl/registrar.c precomp.h ${CMAKE_CURRENT_BINARY_DIR}/atl100_stubs.c) diff --git a/dll/win32/atl100/atl100.spec b/dll/win32/atl100/atl100.spec index 1295f8c1587..0d41c1efd60 100644 --- a/dll/win32/atl100/atl100.spec +++ b/dll/win32/atl100/atl100.spec @@ -5,7 +5,7 @@ 14 stdcall AtlUnmarshalPtr(ptr ptr ptr) 15 stdcall AtlComModuleGetClassObject(ptr ptr ptr ptr) 17 stdcall AtlComModuleRegisterClassObjects(ptr long long) -20 stub AtlComModuleRevokeClassObjects +20 stdcall AtlComModuleRevokeClassObjects(ptr) 22 stdcall AtlComModuleUnregisterServer(ptr long ptr) 23 stdcall AtlUpdateRegistryFromResourceD(long wstr long ptr ptr) 24 stdcall AtlWaitWithMessageLoop(long) diff --git a/dll/win32/atl100/precomp.h b/dll/win32/atl100/precomp.h index 458366efba3..324229015ec 100644 --- a/dll/win32/atl100/precomp.h +++ b/dll/win32/atl100/precomp.h @@ -19,4 +19,6 @@ #include #include +WINE_DEFAULT_DEBUG_CHANNEL(atl); + #endif /* _ATL100_PCH_ */ diff --git a/dll/win32/atl80/CMakeLists.txt b/dll/win32/atl80/CMakeLists.txt index 71590491295..c27604e573b 100644 --- a/dll/win32/atl80/CMakeLists.txt +++ b/dll/win32/atl80/CMakeLists.txt @@ -3,15 +3,23 @@ add_definitions( -D__WINESRC__ -D_ATL_VER=_ATL_VER_80) +remove_definitions(-D_WIN32_WINNT=0x502) +add_definitions(-D_WIN32_WINNT=0x600) + spec2def(atl80.dll atl80.spec ADD_IMPORTLIB) list(APPEND SOURCE + ${REACTOS_SOURCE_DIR}/dll/win32/atl/atl.c atl80.c + ${REACTOS_SOURCE_DIR}/dll/win32/atl/atl_ax.c + ${REACTOS_SOURCE_DIR}/dll/win32/atl/registrar.c + precomp.h ${CMAKE_CURRENT_BINARY_DIR}/atl80_stubs.c ${CMAKE_CURRENT_BINARY_DIR}/atl80.def) add_library(atl80 SHARED ${SOURCE}) set_module_type(atl80 win32dll) -target_link_libraries(atl80 wine) -add_importlibs(atl80 atl100 oleaut32 user32 ole32 msvcrt kernel32 ntdll) +target_link_libraries(atl80 uuid wine) +add_importlibs(atl80 oleaut32 user32 ole32 gdi32 advapi32 msvcrt kernel32 ntdll) +add_pch(atl80 precomp.h SOURCE) add_cd_file(TARGET atl80 DESTINATION reactos/system32 FOR all) diff --git a/dll/win32/atl80/atl80.c b/dll/win32/atl80/atl80.c index bad49b23d15..1a9019b1501 100644 --- a/dll/win32/atl80/atl80.c +++ b/dll/win32/atl80/atl80.c @@ -16,21 +16,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include +#include + #include - -#define COBJMACROS - -#include -#include #include #include -#include - -#include -#include - -WINE_DEFAULT_DEBUG_CHANNEL(atl); /*********************************************************************** * AtlRegisterTypeLib [atl80.18] @@ -68,85 +58,3 @@ HRESULT WINAPI AtlComModuleRegisterServer(_ATL_COM_MODULE *mod, BOOL bRegTypeLib return S_OK; } - -/*********************************************************************** - * AtlRegisterTypeLib [atl80.19] - */ -HRESULT WINAPI AtlRegisterTypeLib(HINSTANCE inst, const WCHAR *index) -{ - ITypeLib *typelib; - BSTR path; - HRESULT hres; - - TRACE("(%p %s)\n", inst, debugstr_w(index)); - - hres = AtlLoadTypeLib(inst, index, &path, &typelib); - if(FAILED(hres)) - return hres; - - hres = RegisterTypeLib(typelib, path, NULL); /* FIXME: pass help directory */ - ITypeLib_Release(typelib); - SysFreeString(path); - return hres; -} - -/*********************************************************************** - * AtlGetVersion [atl80.@] - */ -DWORD WINAPI AtlGetVersion(void *pReserved) -{ - return _ATL_VER; -} - -/********************************************************************** - * AtlAxWin class window procedure - */ -static LRESULT CALLBACK AtlAxWin_wndproc( HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam ) -{ - if ( wMsg == WM_CREATE ) - { - DWORD len = GetWindowTextLengthW( hWnd ) + 1; - WCHAR *ptr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) ); - if (!ptr) - return 1; - GetWindowTextW( hWnd, ptr, len ); - AtlAxCreateControlEx( ptr, hWnd, NULL, NULL, NULL, NULL, NULL ); - HeapFree( GetProcessHeap(), 0, ptr ); - return 0; - } - return DefWindowProcW( hWnd, wMsg, wParam, lParam ); -} - -BOOL WINAPI AtlAxWinInit(void) -{ - WNDCLASSEXW wcex; - const WCHAR AtlAxWin80[] = {'A','t','l','A','x','W','i','n','8','0',0}; - const WCHAR AtlAxWinLic80[] = {'A','t','l','A','x','W','i','n','L','i','c','8','0',0}; - - FIXME("semi-stub\n"); - - if ( FAILED( OleInitialize(NULL) ) ) - return FALSE; - - wcex.cbSize = sizeof(wcex); - wcex.style = CS_GLOBALCLASS | CS_DBLCLKS; - wcex.cbClsExtra = 0; - wcex.cbWndExtra = 0; - wcex.hInstance = GetModuleHandleW( NULL ); - wcex.hIcon = NULL; - wcex.hCursor = NULL; - wcex.hbrBackground = NULL; - wcex.lpszMenuName = NULL; - wcex.hIconSm = 0; - - wcex.lpfnWndProc = AtlAxWin_wndproc; - wcex.lpszClassName = AtlAxWin80; - if ( !RegisterClassExW( &wcex ) ) - return FALSE; - - wcex.lpszClassName = AtlAxWinLic80; - if ( !RegisterClassExW( &wcex ) ) - return FALSE; - - return TRUE; -} diff --git a/dll/win32/atl80/atl80.manifest b/dll/win32/atl80/atl80.manifest new file mode 100644 index 00000000000..039a3d6aeb4 --- /dev/null +++ b/dll/win32/atl80/atl80.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/dll/win32/atl80/atl80.rc b/dll/win32/atl80/atl80.rc new file mode 100644 index 00000000000..b6ea3d4a86e --- /dev/null +++ b/dll/win32/atl80/atl80.rc @@ -0,0 +1,22 @@ +/* + * Resource file for atl80 + * + * Copyright 2011 Alexandre Julliard + * + * 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 + */ + +/* @makedep: atl80.manifest */ +WINE_MANIFEST 24 atl80.manifest diff --git a/dll/win32/atl80/atl80.spec b/dll/win32/atl80/atl80.spec index 5a77629eea1..fb5fae8b210 100644 --- a/dll/win32/atl80/atl80.spec +++ b/dll/win32/atl80/atl80.spec @@ -1,53 +1,53 @@ -10 stdcall AtlAdvise(ptr ptr ptr ptr) atl100.AtlAdvise -11 stdcall AtlUnadvise(ptr ptr long) atl100.AtlUnadvise -12 stdcall AtlFreeMarshalStream(ptr) atl100.AtlFreeMarshalStream -13 stdcall AtlMarshalPtrInProc(ptr ptr ptr) atl100.AtlMarshalPtrInProc -14 stdcall AtlUnmarshalPtr(ptr ptr ptr) atl100.AtlUnmarshalPtr -15 stdcall AtlComModuleGetClassObject(ptr ptr ptr ptr) atl100.AtlComModuleGetClassObject -17 stdcall AtlComModuleRegisterClassObjects(ptr long long) atl100.AtlComModuleRegisterClassObjects +10 stdcall AtlAdvise(ptr ptr ptr ptr) +11 stdcall AtlUnadvise(ptr ptr long) +12 stdcall AtlFreeMarshalStream(ptr) +13 stdcall AtlMarshalPtrInProc(ptr ptr ptr) +14 stdcall AtlUnmarshalPtr(ptr ptr ptr) +15 stdcall AtlComModuleGetClassObject(ptr ptr ptr ptr) +17 stdcall AtlComModuleRegisterClassObjects(ptr long long) 18 stdcall AtlComModuleRegisterServer(ptr long ptr) 19 stdcall AtlRegisterTypeLib(ptr wstr) -20 stub AtlComModuleRevokeClassObjects -22 stdcall AtlComModuleUnregisterServer(ptr long ptr) atl100.AtlComModuleUnregisterServer -23 stdcall AtlUpdateRegistryFromResourceD(long wstr long ptr ptr) atl100.AtlUpdateRegistryFromResourceD -24 stdcall AtlWaitWithMessageLoop(long) atl100.AtlWaitWithMessageLoop +20 stdcall AtlComModuleRevokeClassObjects(ptr) +22 stdcall AtlComModuleUnregisterServer(ptr long ptr) +23 stdcall AtlUpdateRegistryFromResourceD(long wstr long ptr ptr) +24 stdcall AtlWaitWithMessageLoop(long) 25 stub AtlSetErrorInfo -26 stdcall AtlCreateTargetDC(long ptr) atl100.AtlCreateTargetDC -27 stdcall AtlHiMetricToPixel(ptr ptr) atl100.AtlHiMetricToPixel -28 stdcall AtlPixelToHiMetric(ptr ptr) atl100.AtlPixelToHiMetric +26 stdcall AtlCreateTargetDC(long ptr) +27 stdcall AtlHiMetricToPixel(ptr ptr) +28 stdcall AtlPixelToHiMetric(ptr ptr) 29 stub AtlDevModeW2A -30 stdcall AtlComPtrAssign(ptr ptr) atl100.AtlComPtrAssign -31 stdcall AtlComQIPtrAssign(ptr ptr ptr) atl100.AtlComQIPtrAssign -32 stdcall AtlInternalQueryInterface(ptr ptr ptr ptr) atl100.AtlInternalQueryInterface +30 stdcall AtlComPtrAssign(ptr ptr) +31 stdcall AtlComQIPtrAssign(ptr ptr ptr) +32 stdcall AtlInternalQueryInterface(ptr ptr ptr ptr) 34 stdcall AtlGetVersion(ptr) -35 stdcall AtlAxDialogBoxW(long wstr long ptr long) atl100.AtlAxDialogBoxW -36 stdcall AtlAxDialogBoxA(long str long ptr long) atl100.AtlAxDialogBoxA -37 stdcall AtlAxCreateDialogW(long wstr long ptr long) atl100.AtlAxCreateDialogW -38 stdcall AtlAxCreateDialogA(long str long ptr long) atl100.AtlAxCreateDialogA -39 stdcall AtlAxCreateControl(ptr ptr ptr ptr) atl100.AtlAxCreateControl -40 stdcall AtlAxCreateControlEx(ptr ptr ptr ptr ptr ptr ptr) atl100.AtlAxCreateControlEx -41 stdcall AtlAxAttachControl(ptr ptr ptr) atl100.AtlAxAttachControl +35 stdcall AtlAxDialogBoxW(long wstr long ptr long) +36 stdcall AtlAxDialogBoxA(long str long ptr long) +37 stdcall AtlAxCreateDialogW(long wstr long ptr long) +38 stdcall AtlAxCreateDialogA(long str long ptr long) +39 stdcall AtlAxCreateControl(ptr ptr ptr ptr) +40 stdcall AtlAxCreateControlEx(ptr ptr ptr ptr ptr ptr ptr) +41 stdcall AtlAxAttachControl(ptr ptr ptr) 42 stdcall AtlAxWinInit() -43 stdcall AtlWinModuleAddCreateWndData(ptr ptr ptr) atl100.AtlWinModuleAddCreateWndData -44 stdcall AtlWinModuleExtractCreateWndData(ptr) atl100.AtlWinModuleExtractCreateWndData +43 stdcall AtlWinModuleAddCreateWndData(ptr ptr ptr) +44 stdcall AtlWinModuleExtractCreateWndData(ptr) 45 stub AtlWinModuleRegisterWndClassInfoW 46 stub AtlWinModuleRegisterWndClassInfoA -47 stdcall AtlAxGetControl(long ptr) atl100.AtlAxGetControl -48 stdcall AtlAxGetHost(long ptr) atl100.AtlAxGetHost -49 stdcall AtlRegisterClassCategoriesHelper(ptr ptr long) atl100.AtlRegisterClassCategoriesHelper -50 stdcall AtlIPersistStreamInit_Load(ptr ptr ptr ptr) atl100.AtlIPersistStreamInit_Load -51 stdcall AtlIPersistStreamInit_Save(ptr long ptr ptr ptr) atl100.AtlIPersistStreamInit_Save -52 stdcall AtlIPersistPropertyBag_Load(ptr ptr ptr ptr ptr) atl100.AtlIPersistPropertyBag_Load +47 stdcall AtlAxGetControl(long ptr) +48 stdcall AtlAxGetHost(long ptr) +49 stdcall AtlRegisterClassCategoriesHelper(ptr ptr long) +50 stdcall AtlIPersistStreamInit_Load(ptr ptr ptr ptr) +51 stdcall AtlIPersistStreamInit_Save(ptr long ptr ptr ptr) +52 stdcall AtlIPersistPropertyBag_Load(ptr ptr ptr ptr ptr) 53 stub AtlIPersistPropertyBag_Save -54 stdcall AtlGetObjectSourceInterface(ptr ptr ptr ptr ptr) atl100.AtlGetObjectSourceInterface +54 stdcall AtlGetObjectSourceInterface(ptr ptr ptr ptr ptr) 55 stub AtlUnRegisterTypeLib -56 stdcall AtlLoadTypeLib(long wstr ptr ptr) atl100.AtlLoadTypeLib -58 stdcall AtlModuleAddTermFunc(ptr ptr long) atl100.AtlModuleAddTermFunc +56 stdcall AtlLoadTypeLib(long wstr ptr ptr) +58 stdcall AtlModuleAddTermFunc(ptr ptr long) 59 stub AtlAxCreateControlLic 60 stub AtlAxCreateControlLicEx -61 stdcall AtlCreateRegistrar(ptr) atl100.AtlCreateRegistrar +61 stdcall AtlCreateRegistrar(ptr) 62 stub AtlWinModuleRegisterClassExW 63 stub AtlWinModuleRegisterClassExA -64 stdcall AtlCallTermFunc(ptr) atl100.AtlCallTermFunc -65 stdcall AtlWinModuleInit(ptr) atl100.AtlWinModuleInit +64 stdcall AtlCallTermFunc(ptr) +65 stdcall AtlWinModuleInit(ptr) 66 stub AtlWinModuleTerm diff --git a/dll/win32/atl80/precomp.h b/dll/win32/atl80/precomp.h new file mode 100644 index 00000000000..75f1e4159ea --- /dev/null +++ b/dll/win32/atl80/precomp.h @@ -0,0 +1,24 @@ +#ifndef _ATL80_PCH_ +#define _ATL80_PCH_ + +#include + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#define COBJMACROS + +#include +#include +#include +#include +#include + +#include +#include +#include + +WINE_DEFAULT_DEBUG_CHANNEL(atl); + +#endif /* _ATL80_PCH_ */ diff --git a/dll/win32/beepmidi/beepmidi.c b/dll/win32/beepmidi/beepmidi.c index ef74fa588ae..5fdf62d7bce 100644 --- a/dll/win32/beepmidi/beepmidi.c +++ b/dll/win32/beepmidi/beepmidi.c @@ -221,7 +221,7 @@ GetDeviceCapabilities( caps->vDriverVersion = 0x0100; memset(caps->szPname, 0, sizeof(caps->szPname)); - memcpy(caps->szPname, L"PC speaker\0", strlen("PC speaker\0") * 2); + wcscpy(caps->szPname, L"PC speaker"); caps->wTechnology = MOD_SQSYNTH; diff --git a/dll/win32/dbghelp/cpu_arm.c b/dll/win32/dbghelp/cpu_arm.c index 1b561c68bca..31b1926877c 100644 --- a/dll/win32/dbghelp/cpu_arm.c +++ b/dll/win32/dbghelp/cpu_arm.c @@ -23,8 +23,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp); -static unsigned arm_get_addr(HANDLE hThread, const CONTEXT* ctx, - enum cpu_addr ca, ADDRESS64* addr) +static BOOL arm_get_addr(HANDLE hThread, const CONTEXT* ctx, + enum cpu_addr ca, ADDRESS64* addr) { addr->Mode = AddrModeFlat; addr->Segment = 0; /* don't need segment */ diff --git a/dll/win32/dbghelp/cpu_arm64.c b/dll/win32/dbghelp/cpu_arm64.c index 87864afc06b..8a8511a35dc 100644 --- a/dll/win32/dbghelp/cpu_arm64.c +++ b/dll/win32/dbghelp/cpu_arm64.c @@ -2,7 +2,7 @@ * File cpu_arm64.c * * Copyright (C) 2009 Eric Pouech - * Copyright (C) 2010-2013 Andrأ© Hentschel + * Copyright (C) 2010-2013 André Hentschel * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,8 +23,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp); -static unsigned arm64_get_addr(HANDLE hThread, const CONTEXT* ctx, - enum cpu_addr ca, ADDRESS64* addr) +static BOOL arm64_get_addr(HANDLE hThread, const CONTEXT* ctx, + enum cpu_addr ca, ADDRESS64* addr) { addr->Mode = AddrModeFlat; addr->Segment = 0; /* don't need segment */ diff --git a/dll/win32/dbghelp/cpu_i386.c b/dll/win32/dbghelp/cpu_i386.c index 88642e0dbde..5916d217224 100644 --- a/dll/win32/dbghelp/cpu_i386.c +++ b/dll/win32/dbghelp/cpu_i386.c @@ -45,8 +45,8 @@ static ADDRESS_MODE get_selector_type(HANDLE hThread, const CONTEXT* ctx, WORD s return -1; } -static unsigned i386_build_addr(HANDLE hThread, const CONTEXT* ctx, ADDRESS64* addr, - unsigned seg, unsigned long offset) +static BOOL i386_build_addr(HANDLE hThread, const CONTEXT* ctx, ADDRESS64* addr, + unsigned seg, unsigned long offset) { addr->Mode = AddrModeFlat; addr->Segment = seg; @@ -71,8 +71,8 @@ static unsigned i386_build_addr(HANDLE hThread, const CONTEXT* ctx, ADDRESS64* a #endif #ifndef DBGHELP_STATIC_LIB -static unsigned i386_get_addr(HANDLE hThread, const CONTEXT* ctx, - enum cpu_addr ca, ADDRESS64* addr) +static BOOL i386_get_addr(HANDLE hThread, const CONTEXT* ctx, + enum cpu_addr ca, ADDRESS64* addr) { #ifdef __i386__ switch (ca) diff --git a/dll/win32/dbghelp/cpu_ppc.c b/dll/win32/dbghelp/cpu_ppc.c index 7543ef689ab..70908475a76 100644 --- a/dll/win32/dbghelp/cpu_ppc.c +++ b/dll/win32/dbghelp/cpu_ppc.c @@ -22,8 +22,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp); -static unsigned ppc_get_addr(HANDLE hThread, const CONTEXT* ctx, - enum cpu_addr ca, ADDRESS64* addr) +static BOOL ppc_get_addr(HANDLE hThread, const CONTEXT* ctx, + enum cpu_addr ca, ADDRESS64* addr) { switch (ca) { diff --git a/dll/win32/dbghelp/cpu_x86_64.c b/dll/win32/dbghelp/cpu_x86_64.c index d3e27205c02..09adbe3c465 100644 --- a/dll/win32/dbghelp/cpu_x86_64.c +++ b/dll/win32/dbghelp/cpu_x86_64.c @@ -83,8 +83,8 @@ typedef struct _UNWIND_INFO #define GetExceptionDataPtr(info) \ ((PVOID)((PULONG)GetLanguageSpecificData(info) + 1) -static unsigned x86_64_get_addr(HANDLE hThread, const CONTEXT* ctx, - enum cpu_addr ca, ADDRESS64* addr) +static BOOL x86_64_get_addr(HANDLE hThread, const CONTEXT* ctx, + enum cpu_addr ca, ADDRESS64* addr) { addr->Mode = AddrModeFlat; switch (ca) diff --git a/dll/win32/dbghelp/dbghelp.c b/dll/win32/dbghelp/dbghelp.c index ae4ea13b7ba..f9e64d37f47 100644 --- a/dll/win32/dbghelp/dbghelp.c +++ b/dll/win32/dbghelp/dbghelp.c @@ -60,25 +60,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp); */ unsigned dbghelp_options = SYMOPT_UNDNAME; -HANDLE hMsvcrt = NULL; - -/*********************************************************************** - * DllMain (DEBUGHLP.@) - */ -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - switch (fdwReason) - { - case DLL_PROCESS_ATTACH: break; - case DLL_PROCESS_DETACH: - if (hMsvcrt) FreeLibrary(hMsvcrt); - break; - case DLL_THREAD_ATTACH: break; - case DLL_THREAD_DETACH: break; - default: break; - } - return TRUE; -} static struct process* process_first /* = NULL */; diff --git a/dll/win32/dbghelp/dbghelp_private.h b/dll/win32/dbghelp/dbghelp_private.h index a8712931651..8c10539cb2e 100644 --- a/dll/win32/dbghelp/dbghelp_private.h +++ b/dll/win32/dbghelp/dbghelp_private.h @@ -569,7 +569,7 @@ struct cpu DWORD frame_regno; /* address manipulation */ - unsigned (*get_addr)(HANDLE hThread, const CONTEXT* ctx, + BOOL (*get_addr)(HANDLE hThread, const CONTEXT* ctx, enum cpu_addr, ADDRESS64* addr); /* stack manipulation */ @@ -594,7 +594,6 @@ extern struct cpu* dbghelp_current_cpu DECLSPEC_HIDDEN; /* dbghelp.c */ extern struct process* process_find_by_handle(HANDLE hProcess) DECLSPEC_HIDDEN; -extern HANDLE hMsvcrt DECLSPEC_HIDDEN; extern BOOL validate_addr64(DWORD64 addr) DECLSPEC_HIDDEN; extern BOOL pcs_callback(const struct process* pcs, ULONG action, void* data) DECLSPEC_HIDDEN; extern void* fetch_buffer(struct process* pcs, unsigned size) DECLSPEC_HIDDEN; diff --git a/dll/win32/dbghelp/dwarf.c b/dll/win32/dbghelp/dwarf.c index cca040ea77a..2e007826f0c 100644 --- a/dll/win32/dbghelp/dwarf.c +++ b/dll/win32/dbghelp/dwarf.c @@ -513,7 +513,7 @@ static void dwarf2_fill_attr(const dwarf2_parse_context_t* ctx, break; case DW_FORM_ref8: - FIXME("Unhandled 64 bit support\n"); + FIXME("Unhandled 64-bit support\n"); break; case DW_FORM_sdata: @@ -1408,6 +1408,9 @@ static struct symt* dwarf2_parse_udt_type(dwarf2_parse_context_t* ctx, switch (child->abbrev->tag) { + case DW_TAG_array_type: + dwarf2_parse_array_type(ctx, di); + break; case DW_TAG_member: /* FIXME: should I follow the sibling stuff ?? */ dwarf2_parse_udt_member(ctx, child, (struct symt_udt*)di->symt); @@ -1678,7 +1681,10 @@ static void dwarf2_parse_subprogram_label(dwarf2_subprogram_t* subpgm, static void dwarf2_parse_subprogram_block(dwarf2_subprogram_t* subpgm, struct symt_block* parent_block, - dwarf2_debug_info_t* di); + dwarf2_debug_info_t* di); + +static struct symt* dwarf2_parse_subroutine_type(dwarf2_parse_context_t* ctx, + dwarf2_debug_info_t* di); static void dwarf2_parse_inlined_subroutine(dwarf2_subprogram_t* subpgm, struct symt_block* parent_block, @@ -1769,6 +1775,12 @@ static void dwarf2_parse_subprogram_block(dwarf2_subprogram_t* subpgm, case DW_TAG_variable: dwarf2_parse_variable(subpgm, block, child); break; + case DW_TAG_pointer_type: + dwarf2_parse_pointer_type(subpgm->ctx, di); + break; + case DW_TAG_subroutine_type: + dwarf2_parse_subroutine_type(subpgm->ctx, di); + break; case DW_TAG_lexical_block: dwarf2_parse_subprogram_block(subpgm, block, child); break; @@ -1900,6 +1912,9 @@ static struct symt* dwarf2_parse_subprogram(dwarf2_parse_context_t* ctx, case DW_TAG_inlined_subroutine: dwarf2_parse_inlined_subroutine(&subpgm, NULL, child); break; + case DW_TAG_pointer_type: + dwarf2_parse_pointer_type(subpgm.ctx, di); + break; case DW_TAG_subprogram: /* FIXME: likely a declaration (to be checked) * skip it for now diff --git a/dll/win32/dbghelp/elf_module.c b/dll/win32/dbghelp/elf_module.c index 469b3409d12..b0c1c52a5bf 100644 --- a/dll/win32/dbghelp/elf_module.c +++ b/dll/win32/dbghelp/elf_module.c @@ -43,6 +43,32 @@ #define NT_GNU_BUILD_ID 3 #endif +#ifndef HAVE_STRUCT_R_DEBUG +struct r_debug +{ + int r_version; + struct link_map *r_map; + ElfW(Addr) r_brk; + enum + { + RT_CONSISTENT, + RT_ADD, + RT_DELETE + } r_state; + ElfW(Addr) r_ldbase; +}; +#endif /* HAVE_STRUCT_R_DEBUG */ + +#ifndef HAVE_STRUCT_LINK_MAP +struct link_map +{ + ElfW(Addr) l_addr; + char *l_name; + ElfW(Dyn) *l_ld; + struct link_map *l_next, *l_prev; +}; +#endif /* HAVE_STRUCT_LINK_MAP */ + WINE_DEFAULT_DEBUG_CHANNEL(dbghelp); struct elf_info @@ -1427,7 +1453,7 @@ static BOOL elf_search_and_load_file(struct process* pcs, const WCHAR* filename, { BOOL ret = FALSE; struct module* module; - static WCHAR S_libstdcPPW[] = {'l','i','b','s','t','d','c','+','+','\0'}; + static const WCHAR S_libstdcPPW[] = {'l','i','b','s','t','d','c','+','+','\0'}; if (filename == NULL || *filename == '\0') return FALSE; if ((module = module_is_already_loaded(pcs, filename))) @@ -1682,8 +1708,8 @@ struct module* elf_load_module(struct process* pcs, const WCHAR* name, unsigned /****************************************************************** * elf_synchronize_module_list * - * this functions rescans the debuggee module's list and synchronizes it with - * the one from 'pcs', ie: + * this function rescans the debuggee module's list and synchronizes it with + * the one from 'pcs', i.e.: * - if a module is in debuggee and not in pcs, it's loaded into pcs * - if a module is in pcs and not in debuggee, it's unloaded from pcs */ diff --git a/dll/win32/dbghelp/macho_module.c b/dll/win32/dbghelp/macho_module.c index 6013867cef5..67ee681d92a 100644 --- a/dll/win32/dbghelp/macho_module.c +++ b/dll/win32/dbghelp/macho_module.c @@ -420,17 +420,32 @@ static BOOL macho_map_file(const WCHAR* filenameW, struct macho_file_map* fmap) RtlInitializeBitMap(&fmap->sect_is_code, fmap->sect_is_code_buff, MAX_SECT + 1); len = WideCharToMultiByte(CP_UNIXCP, 0, filenameW, -1, NULL, 0, NULL, NULL); - if (!(filename = HeapAlloc(GetProcessHeap(), 0, len))) return FALSE; + if (!(filename = HeapAlloc(GetProcessHeap(), 0, len))) + { + WARN("failed to allocate filename buffer\n"); + return FALSE; + } WideCharToMultiByte(CP_UNIXCP, 0, filenameW, -1, filename, len, NULL, NULL); /* check that the file exists */ - if (stat(filename, &statbuf) == -1 || S_ISDIR(statbuf.st_mode)) goto done; + if (stat(filename, &statbuf) == -1 || S_ISDIR(statbuf.st_mode)) + { + TRACE("stat() failed or %s is directory: %s\n", debugstr_a(filename), strerror(errno)); + goto done; + } /* Now open the file, so that we can mmap() it. */ - if ((fmap->fd = open(filename, O_RDONLY)) == -1) goto done; + if ((fmap->fd = open(filename, O_RDONLY)) == -1) + { + TRACE("failed to open file %s: %d\n", debugstr_a(filename), errno); + goto done; + } if (read(fmap->fd, &fat_header, sizeof(fat_header)) != sizeof(fat_header)) + { + TRACE("failed to read fat header: %d\n", errno); goto done; + } TRACE("... got possible fat header\n"); /* Fat header is always in big-endian order. */ @@ -936,23 +951,52 @@ static BOOL macho_load_file(struct process* pcs, const WCHAR* filename, */ if (macho_info->flags & MACHO_INFO_DEBUG_HEADER) { - static void* dyld_all_image_infos_addr; + PROCESS_BASIC_INFORMATION pbi; + NTSTATUS status; - /* This symbol should be in the same place in all processes. */ - if (!dyld_all_image_infos_addr) + ret = FALSE; + + /* Get address of PEB */ + status = NtQueryInformationProcess(pcs->handle, ProcessBasicInformation, + &pbi, sizeof(pbi), NULL); + if (status == STATUS_SUCCESS) { - struct nlist nl[2]; - memset(nl, 0, sizeof(nl)); - nl[0].n_un.n_name = (char*)"_dyld_all_image_infos"; - if (!nlist("/usr/lib/dyld", nl)) - dyld_all_image_infos_addr = (void*)nl[0].n_value; + ULONG dyld_image_info; + + /* Read dyld image info address from PEB */ + if (ReadProcessMemory(pcs->handle, &pbi.PebBaseAddress->Reserved, + &dyld_image_info, sizeof(dyld_image_info), NULL)) + { + TRACE("got dyld_image_info 0x%08x from PEB %p MacDyldImageInfo %p\n", + dyld_image_info, pbi.PebBaseAddress, &pbi.PebBaseAddress->Reserved); + macho_info->dbg_hdr_addr = dyld_image_info; + ret = TRUE; + } } - if (dyld_all_image_infos_addr) - macho_info->dbg_hdr_addr = (unsigned long)dyld_all_image_infos_addr; - else - ret = FALSE; - TRACE("dbg_hdr_addr = 0x%08lx\n", macho_info->dbg_hdr_addr); + if (!ret) + { + static void* dyld_all_image_infos_addr; + + /* Our next best guess is that dyld was loaded at its base address + and we can find the dyld image infos address by looking up its symbol. */ + if (!dyld_all_image_infos_addr) + { + struct nlist nl[2]; + memset(nl, 0, sizeof(nl)); + nl[0].n_un.n_name = (char*)"_dyld_all_image_infos"; + if (!nlist("/usr/lib/dyld", nl)) + dyld_all_image_infos_addr = (void*)nl[0].n_value; + } + + if (dyld_all_image_infos_addr) + { + TRACE("got dyld_image_info %p from /usr/lib/dyld symbol table\n", + dyld_all_image_infos_addr); + macho_info->dbg_hdr_addr = (unsigned long)dyld_all_image_infos_addr; + ret = TRUE; + } + } } if (macho_info->flags & MACHO_INFO_MODULE) @@ -1011,7 +1055,7 @@ leave: * macho_load_file_from_path * Tries to load a Mach-O file from a set of paths (separated by ':') */ -static BOOL macho_load_file_from_path(HANDLE hProcess, +static BOOL macho_load_file_from_path(struct process* pcs, const WCHAR* filename, unsigned long load_addr, const char* path, @@ -1022,7 +1066,7 @@ static BOOL macho_load_file_from_path(HANDLE hProcess, WCHAR* pathW = NULL; unsigned len; - TRACE("(%p, %s, 0x%08lx, %s, %p)\n", hProcess, debugstr_w(filename), load_addr, + TRACE("(%p/%p, %s, 0x%08lx, %s, %p)\n", pcs, pcs->handle, debugstr_w(filename), load_addr, debugstr_a(path), macho_info); if (!path) return FALSE; @@ -1041,7 +1085,7 @@ static BOOL macho_load_file_from_path(HANDLE hProcess, strcpyW(fn, s); strcatW(fn, S_SlashW); strcatW(fn, filename); - ret = macho_load_file(hProcess, fn, load_addr, macho_info); + ret = macho_load_file(pcs, fn, load_addr, macho_info); HeapFree(GetProcessHeap(), 0, fn); if (ret) break; s = (t) ? (t+1) : NULL; @@ -1057,7 +1101,7 @@ static BOOL macho_load_file_from_path(HANDLE hProcess, * * Tries to load a Mach-O file from the dll path */ -static BOOL macho_load_file_from_dll_path(HANDLE hProcess, +static BOOL macho_load_file_from_dll_path(struct process* pcs, const WCHAR* filename, unsigned long load_addr, struct macho_info* macho_info) @@ -1066,7 +1110,7 @@ static BOOL macho_load_file_from_dll_path(HANDLE hProcess, unsigned int index = 0; const char *path; - TRACE("(%p, %s, 0x%08lx, %p)\n", hProcess, debugstr_w(filename), load_addr, + TRACE("(%p/%p, %s, 0x%08lx, %p)\n", pcs, pcs->handle, debugstr_w(filename), load_addr, macho_info); while (!ret && (path = wine_dll_enum_load_path( index++ ))) @@ -1083,7 +1127,7 @@ static BOOL macho_load_file_from_dll_path(HANDLE hProcess, MultiByteToWideChar(CP_UNIXCP, 0, path, -1, name, len); strcatW( name, S_SlashW ); strcatW( name, filename ); - ret = macho_load_file(hProcess, name, load_addr, macho_info); + ret = macho_load_file(pcs, name, load_addr, macho_info); HeapFree( GetProcessHeap(), 0, name ); } TRACE(" => %d\n", ret); @@ -1101,7 +1145,7 @@ static BOOL macho_search_and_load_file(struct process* pcs, const WCHAR* filenam { BOOL ret = FALSE; struct module* module; - static WCHAR S_libstdcPPW[] = {'l','i','b','s','t','d','c','+','+','\0'}; + static const WCHAR S_libstdcPPW[] = {'l','i','b','s','t','d','c','+','+','\0'}; const WCHAR* p; TRACE("(%p/%p, %s, 0x%08lx, %p)\n", pcs, pcs->handle, debugstr_w(filename), load_addr, diff --git a/dll/win32/dbghelp/module.c b/dll/win32/dbghelp/module.c index 1886dfaf7dc..dc6bc177980 100644 --- a/dll/win32/dbghelp/module.c +++ b/dll/win32/dbghelp/module.c @@ -23,6 +23,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp); +#define DLLPREFIX "" + 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'}; @@ -47,7 +49,7 @@ static int match_ext(const WCHAR* ptr, size_t len) for (e = ext; *e; e++) { l = strlenW(*e); - if (l >= len) return FALSE; + if (l >= len) return 0; if (strncmpiW(&ptr[len - l], *e, l)) continue; return l; } @@ -96,7 +98,7 @@ void module_set_module(struct module* module, const WCHAR* name) const WCHAR *get_wine_loader_name(void) { - static const int is_win64 = sizeof(void *) > sizeof(int); /* FIXME: should depend on target process */ + static const BOOL is_win64 = sizeof(void *) > sizeof(int); /* FIXME: should depend on target process */ static const WCHAR wineW[] = {'w','i','n','e',0}; static const WCHAR suffixW[] = {'6','4',0}; static const WCHAR *loader; @@ -420,6 +422,16 @@ static BOOL module_is_container_loaded(const struct process* pcs, size_t len; struct module* module; PCWSTR filename, modname; + static WCHAR* dll_prefix; + static int dll_prefix_len; + + if (!dll_prefix) + { + dll_prefix_len = MultiByteToWideChar( CP_UNIXCP, 0, DLLPREFIX, -1, NULL, 0 ); + dll_prefix = HeapAlloc( GetProcessHeap(), 0, dll_prefix_len * sizeof(WCHAR) ); + MultiByteToWideChar( CP_UNIXCP, 0, DLLPREFIX, -1, dll_prefix, dll_prefix_len ); + dll_prefix_len--; + } if (!base) return FALSE; filename = get_filename(ImageName, NULL); @@ -432,6 +444,7 @@ static BOOL module_is_container_loaded(const struct process* pcs, base < module->module.BaseOfImage + module->module.ImageSize) { modname = get_filename(module->module.LoadedImageName, NULL); + if (dll_prefix_len && !strncmpW( modname, dll_prefix, dll_prefix_len )) modname += dll_prefix_len; if (!strncmpiW(modname, filename, len) && !memcmp(modname + len, S_DotSoW, 3 * sizeof(WCHAR))) { diff --git a/dll/win32/dbghelp/msc.c b/dll/win32/dbghelp/msc.c index 73df7398e4d..110f5b3dab7 100644 --- a/dll/win32/dbghelp/msc.c +++ b/dll/win32/dbghelp/msc.c @@ -631,9 +631,9 @@ static struct symt* codeview_add_type_array(struct codeview_type_parse* ctp, return &symt_new_array(ctp->module, 0, -arr_len, elem, index)->symt; } -static int codeview_add_type_enum_field_list(struct module* module, - struct symt_enum* symt, - const union codeview_reftype* ref_type) +static BOOL codeview_add_type_enum_field_list(struct module* module, + struct symt_enum* symt, + const union codeview_reftype* ref_type) { const unsigned char* ptr = ref_type->fieldlist.list; const unsigned char* last = (const BYTE*)ref_type + ref_type->generic.len + 2; @@ -1307,12 +1307,12 @@ static struct symt* codeview_parse_one_type(struct codeview_type_parse* ctp, default: FIXME("Unsupported type-id leaf %x\n", type->generic.id); dump(type, 2 + type->generic.len); - return FALSE; + return NULL; } return codeview_add_type(curr_type, symt) ? symt : NULL; } -static int codeview_parse_type_table(struct codeview_type_parse* ctp) +static BOOL codeview_parse_type_table(struct codeview_type_parse* ctp) { unsigned int curr_type = FIRST_DEFINABLE_TYPE; const union codeview_type* type; @@ -1537,8 +1537,8 @@ static inline void codeview_add_variable(const struct msc_debug_info* msc_dbg, } } -static int codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* root, - int offset, int size, BOOL do_globals) +static BOOL codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* root, + int offset, int size, BOOL do_globals) { struct symt_function* curr_func = NULL; int i, length; @@ -1984,8 +1984,8 @@ static int codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* root return TRUE; } -static int codeview_snarf_public(const struct msc_debug_info* msc_dbg, const BYTE* root, - int offset, int size) +static BOOL codeview_snarf_public(const struct msc_debug_info* msc_dbg, const BYTE* root, + int offset, int size) { int i, length; @@ -2619,7 +2619,7 @@ static void pdb_process_symbol_imports(const struct process* pcs, while (imp < (const PDB_SYMBOL_IMPORT*)last) { ptr = (const char*)imp + sizeof(*imp) + strlen(imp->filename); - if (i >= CV_MAX_MODULES) FIXME("Out of bounds !!!\n"); + if (i >= CV_MAX_MODULES) FIXME("Out of bounds!!!\n"); if (!strcasecmp(pdb_lookup->filename, imp->filename)) { if (module_index != -1) FIXME("Twice the entry\n"); @@ -2652,7 +2652,7 @@ static void pdb_process_symbol_imports(const struct process* pcs, pdb_module_info->used_subfiles = 1; } cv_current_module = &cv_zmodules[module_index]; - if (cv_current_module->allowed) FIXME("Already allowed ??\n"); + if (cv_current_module->allowed) FIXME("Already allowed??\n"); cv_current_module->allowed = TRUE; } @@ -3235,7 +3235,7 @@ static BOOL codeview_process_info(const struct process* pcs, ctp.table = (const BYTE*)(ctp.offset + types->cTypes); cv_current_module = &cv_zmodules[0]; - if (cv_current_module->allowed) FIXME("Already allowed ??\n"); + if (cv_current_module->allowed) FIXME("Already allowed??\n"); cv_current_module->allowed = TRUE; codeview_parse_type_table(&ctp); diff --git a/dll/win32/dbghelp/storage.c b/dll/win32/dbghelp/storage.c index 5f9c62426e1..32e80d46ef9 100644 --- a/dll/win32/dbghelp/storage.c +++ b/dll/win32/dbghelp/storage.c @@ -282,7 +282,7 @@ void* sparse_array_add(struct sparse_array* sa, unsigned long key, pk2i = sparse_array_lookup(sa, key, &idx); if (pk2i && pk2i->key == key) { - FIXME("re adding an existing key\n"); + FIXME("re-adding an existing key\n"); return NULL; } to = vector_add(&sa->key2index, pool); @@ -353,13 +353,13 @@ void hash_table_destroy(struct hash_table* ht) variance = (double)sq / ht->num_buckets - mean * mean; FIXME("STATS: elts[num:%-4u size:%u mean:%f] buckets[min:%-4u variance:%+f max:%-4u]\n", ht->num_elts, ht->num_buckets, mean, min, variance, max); -#if 1 + for (i = 0; i < ht->num_buckets; i++) { for (len = 0, elt = ht->buckets[i]; elt; elt = elt->next) len++; if (len == max) { - FIXME("Longuest bucket:\n"); + FIXME("Longest bucket:\n"); for (elt = ht->buckets[i]; elt; elt = elt->next) FIXME("\t%s\n", elt->name); break; @@ -367,7 +367,6 @@ void hash_table_destroy(struct hash_table* ht) } #endif -#endif } void hash_table_add(struct hash_table* ht, struct hash_table_elt* elt) diff --git a/dll/win32/dbghelp/symbol.c b/dll/win32/dbghelp/symbol.c index 48ebb33bdb4..0e15943ad91 100644 --- a/dll/win32/dbghelp/symbol.c +++ b/dll/win32/dbghelp/symbol.c @@ -24,7 +24,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp); WINE_DECLARE_DEBUG_CHANNEL(dbghelp_symt); -static WCHAR starW[] = {'*','\0'}; +static const WCHAR starW[] = {'*','\0'}; static inline int cmp_addr(ULONG64 a1, ULONG64 a2) { @@ -703,8 +703,8 @@ static void symt_fill_sym_info(struct module_pair* pair, if (sym_info->MaxNameLen) { if (sym->tag != SymTagPublicSymbol || !(dbghelp_options & SYMOPT_UNDNAME) || - (sym_info->NameLen = UnDecorateSymbolName(name, sym_info->Name, - sym_info->MaxNameLen, UNDNAME_NAME_ONLY) == 0)) + ((sym_info->NameLen = UnDecorateSymbolName(name, sym_info->Name, + sym_info->MaxNameLen, UNDNAME_NAME_ONLY)) == 0)) { sym_info->NameLen = min(strlen(name), sym_info->MaxNameLen - 1); memcpy(sym_info->Name, name, sym_info->NameLen); @@ -1236,7 +1236,8 @@ BOOL WINAPI SymFromAddr(HANDLE hProcess, DWORD64 Address, if ((sym = symt_find_nearest(pair.effective, Address)) == NULL) return FALSE; symt_fill_sym_info(&pair, NULL, &sym->symt, Symbol); - *Displacement = Address - Symbol->Address; + if (Displacement) + *Displacement = Address - Symbol->Address; return TRUE; } @@ -1766,6 +1767,7 @@ DWORD WINAPI UnDecorateSymbolName(PCSTR DecoratedName, PSTR UnDecoratedName, DWORD UndecoratedLength, DWORD Flags) { /* undocumented from msvcrt */ + static HANDLE hMsvcrt; static char* (CDECL *p_undname)(char*, const char*, int, void* (CDECL*)(size_t), void (CDECL*)(void*), unsigned short); static const WCHAR szMsvcrt[] = {'m','s','v','c','r','t','.','d','l','l',0}; diff --git a/dll/win32/hnetcfg/hnetcfg.idl b/dll/win32/hnetcfg/hnetcfg.idl index 8603b72aa4d..0ba4be29f80 100644 --- a/dll/win32/hnetcfg/hnetcfg.idl +++ b/dll/win32/hnetcfg/hnetcfg.idl @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma makedep register + [ helpstring("HNetCfg.FwMgr"), progid("HNetCfg.FwMgr"), diff --git a/dll/win32/hnetcfg/hnetcfg_tlb.idl b/dll/win32/hnetcfg/hnetcfg_tlb.idl index 6a202b2de9e..33e8cc87ae0 100644 --- a/dll/win32/hnetcfg/hnetcfg_tlb.idl +++ b/dll/win32/hnetcfg/hnetcfg_tlb.idl @@ -18,4 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma makedep regtypelib + #include "netfw.idl" diff --git a/dll/win32/ieframe/ieframe.h b/dll/win32/ieframe/ieframe.h index bed94de0563..31b3f22a330 100644 --- a/dll/win32/ieframe/ieframe.h +++ b/dll/win32/ieframe/ieframe.h @@ -74,6 +74,7 @@ typedef struct { IHlinkFrame IHlinkFrame_iface; ITargetFrame2 ITargetFrame2_iface; ITargetFramePriv2 ITargetFramePriv2_iface; + IWebBrowserPriv2IE9 IWebBrowserPriv2IE9_iface; IUnknown *outer; DocHost *doc_host; diff --git a/dll/win32/ieframe/ieframe.rgs b/dll/win32/ieframe/ieframe.rgs index cf8f3b45ee0..f99e6b63523 100644 --- a/dll/win32/ieframe/ieframe.rgs +++ b/dll/win32/ieframe/ieframe.rgs @@ -34,9 +34,13 @@ HKCR { shellex { - MayChangeDefaultMenu {} + MayChangeDefaultMenu } } + '{8856f961-340a-11d0-a96b-00c04fd705a2}' + { + Control + } } 'InternetShortcut' { diff --git a/dll/win32/ieframe/ieframe_v1.idl b/dll/win32/ieframe/ieframe_v1.idl index a7d3543e4ef..9b64a600043 100644 --- a/dll/win32/ieframe/ieframe_v1.idl +++ b/dll/win32/ieframe/ieframe_v1.idl @@ -16,6 +16,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma makedep regtypelib +#pragma makedep register + #include "exdisp.idl" [ diff --git a/dll/win32/ieframe/navigate.c b/dll/win32/ieframe/navigate.c index 72390ee720e..7586b69424e 100644 --- a/dll/win32/ieframe/navigate.c +++ b/dll/win32/ieframe/navigate.c @@ -1437,6 +1437,45 @@ static const ITargetFramePriv2Vtbl TargetFramePriv2Vtbl = { TargetFramePriv2_AggregatedNavigation2 }; +static inline HlinkFrame *impl_from_IWebBrowserPriv2IE9(IWebBrowserPriv2IE9 *iface) +{ + return CONTAINING_RECORD(iface, HlinkFrame, IWebBrowserPriv2IE9_iface); +} + +static HRESULT WINAPI WebBrowserPriv2IE9_QueryInterface(IWebBrowserPriv2IE9 *iface, REFIID riid, void **ppv) +{ + HlinkFrame *This = impl_from_IWebBrowserPriv2IE9(iface); + return IUnknown_QueryInterface(This->outer, riid, ppv); +} + +static ULONG WINAPI WebBrowserPriv2IE9_AddRef(IWebBrowserPriv2IE9 *iface) +{ + HlinkFrame *This = impl_from_IWebBrowserPriv2IE9(iface); + return IUnknown_AddRef(This->outer); +} + +static ULONG WINAPI WebBrowserPriv2IE9_Release(IWebBrowserPriv2IE9 *iface) +{ + HlinkFrame *This = impl_from_IWebBrowserPriv2IE9(iface); + return IUnknown_Release(This->outer); +} + +static HRESULT WINAPI WebBrowserPriv2IE9_NavigateWithBindCtx2(IWebBrowserPriv2IE9 *iface, IUri *uri, VARIANT *flags, + VARIANT *target_frame, VARIANT *post_data, VARIANT *headers, IBindCtx *bind_ctx, LPOLESTR url_fragment, DWORD unused) +{ + HlinkFrame *This = impl_from_IWebBrowserPriv2IE9(iface); + FIXME("(%p)->(%p %s %s %s %s %p %s)\n", This, uri, debugstr_variant(flags), debugstr_variant(target_frame), + debugstr_variant(post_data), debugstr_variant(headers), bind_ctx, debugstr_w(url_fragment)); + return E_NOTIMPL; +} + +static const IWebBrowserPriv2IE9Vtbl WebBrowserPriv2IE9Vtbl = { + WebBrowserPriv2IE9_QueryInterface, + WebBrowserPriv2IE9_AddRef, + WebBrowserPriv2IE9_Release, + WebBrowserPriv2IE9_NavigateWithBindCtx2 +}; + BOOL HlinkFrame_QI(HlinkFrame *This, REFIID riid, void **ppv) { if(IsEqualGUID(&IID_IHlinkFrame, riid)) { @@ -1451,6 +1490,9 @@ BOOL HlinkFrame_QI(HlinkFrame *This, REFIID riid, void **ppv) }else if(IsEqualGUID(&IID_ITargetFramePriv2, riid)) { TRACE("(%p)->(IID_ITargetFramePriv2 %p)\n", This, ppv); *ppv = &This->ITargetFramePriv2_iface; + }else if(IsEqualGUID(&IID_IWebBrowserPriv2IE9, riid)) { + TRACE("(%p)->(IID_IWebBrowserPriv2IE9 %p)\n", This, ppv); + *ppv = &This->IWebBrowserPriv2IE9_iface; }else { return FALSE; } @@ -1464,6 +1506,7 @@ void HlinkFrame_Init(HlinkFrame *This, IUnknown *outer, DocHost *doc_host) This->IHlinkFrame_iface.lpVtbl = &HlinkFrameVtbl; This->ITargetFrame2_iface.lpVtbl = &TargetFrame2Vtbl; This->ITargetFramePriv2_iface.lpVtbl = &TargetFramePriv2Vtbl; + This->IWebBrowserPriv2IE9_iface.lpVtbl = &WebBrowserPriv2IE9Vtbl; This->outer = outer; This->doc_host = doc_host; diff --git a/dll/win32/ieframe/shellbrowser.c b/dll/win32/ieframe/shellbrowser.c index d117c373e89..7c728bbb757 100644 --- a/dll/win32/ieframe/shellbrowser.c +++ b/dll/win32/ieframe/shellbrowser.c @@ -688,7 +688,7 @@ static HRESULT WINAPI DocObjectService_FireBeforeNavigate2( V_VT(params+3) = (VT_BYREF|VT_VARIANT); V_VARIANTREF(params+3) = &var_frame_name; V_VT(&var_frame_name) = VT_BSTR; - V_BSTR(&var_frame_name) = NULL; + V_BSTR(&var_frame_name) = lpszFrameName ? SysAllocString(lpszFrameName) : NULL; V_VT(params+4) = (VT_BYREF|VT_VARIANT); V_VARIANTREF(params+4) = &var_flags; @@ -709,6 +709,7 @@ static HRESULT WINAPI DocObjectService_FireBeforeNavigate2( SysFreeString(V_BSTR(&var_url)); SysFreeString(V_BSTR(&var_headers)); + SysFreeString(V_BSTR(&var_frame_name)); SafeArrayDestroy(post_data); *pfCancel = !!cancel; diff --git a/dll/win32/inseng/inseng.idl b/dll/win32/inseng/inseng.idl index 372d1333e58..ba7a0f91819 100644 --- a/dll/win32/inseng/inseng.idl +++ b/dll/win32/inseng/inseng.idl @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma makedep register + [ helpstring("Microsoft Active Setup Engine"), threading(apartment), diff --git a/dll/win32/msafd/msafd.h b/dll/win32/msafd/msafd.h index 97f3816563d..b4e5be44689 100644 --- a/dll/win32/msafd/msafd.h +++ b/dll/win32/msafd/msafd.h @@ -480,8 +480,8 @@ SockReenableAsyncSelectEvent ( typedef VOID (*PASYNC_COMPLETION_ROUTINE)(PVOID Context, PIO_STATUS_BLOCK IoStatusBlock); -DWORD FORCEINLINE +DWORD MsafdReturnWithErrno(NTSTATUS Status, LPINT Errno, DWORD Received, diff --git a/dll/win32/msgina/gui.c b/dll/win32/msgina/gui.c index 41b7689f470..8293604c078 100644 --- a/dll/win32/msgina/gui.c +++ b/dll/win32/msgina/gui.c @@ -73,12 +73,14 @@ StartupWindowThread(LPVOID lpParam) FALSE, DUPLICATE_SAME_ACCESS)) { + ERR("Duplicating handle failed!\n"); HeapFree(GetProcessHeap(), 0, lpParam); return FALSE; } if(!SetThreadDesktop(hDesk)) { + ERR("Setting thread desktop failed!\n"); HeapFree(GetProcessHeap(), 0, lpParam); return FALSE; } diff --git a/dll/win32/msgina/resources/reactos.bmp b/dll/win32/msgina/resources/reactos.bmp index 2e45185ed43..41986988417 100644 Binary files a/dll/win32/msgina/resources/reactos.bmp and b/dll/win32/msgina/resources/reactos.bmp differ diff --git a/dll/win32/msgina/resources/reactos.svg b/dll/win32/msgina/resources/reactos.svg index 2df7a66a289..e91643d441a 100644 --- a/dll/win32/msgina/resources/reactos.svg +++ b/dll/win32/msgina/resources/reactos.svg @@ -11,8 +11,8 @@ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="413" - height="88" - id="svg3989" + height="72" + id="svg2" version="1.1" inkscape:version="0.48.2 r9819" sodipodi:docname="reactos.svg" @@ -20,687 +20,29 @@ inkscape:export-xdpi="90" inkscape:export-ydpi="90"> + id="defs4"> + id="linearGradient3755"> + id="stop3757" /> + id="stop3759" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + id="linearGradient17671"> + id="linearGradient5206"> + id="stop5208" /> + id="stop5210" /> + id="linearGradient5213"> + id="stop5215" /> + id="stop5217" /> + id="linearGradient5220"> + id="stop5222" /> + id="stop5224" /> + id="linearGradient4522"> + id="linearGradient5231"> + id="stop5233" /> + id="stop5235" /> + id="linearGradient3800"> + id="linearGradient5244"> + id="stop5246" /> + id="stop5248" /> + id="linearGradient5253"> + id="stop5255" /> + id="stop5257" /> + id="feGaussianBlur5261" /> + id="linearGradient7995"> + id="linearGradient5271"> + id="stop5273" /> + id="stop5275" /> + id="linearGradient5278"> + id="stop5280" /> + id="stop5282" /> + id="stop5284" /> + id="stop5286" /> + id="stop5288" /> + id="linearGradient5291"> + id="stop5293" /> + id="stop5295" /> + id="linearGradient5300"> + id="stop5302" /> + id="stop5304" /> + id="linearGradient5307"> + id="stop5309" /> + id="stop5311" /> + id="linearGradient5314"> + id="stop5316" /> + id="stop5318" /> + id="linearGradient5321"> + id="stop5323" /> + id="stop5325" /> + id="linearGradient5328"> + id="stop5330" /> + id="stop5332" /> + id="linearGradient5341"> + id="stop5343" /> + id="stop5345" /> + id="linearGradient5350"> + id="stop5352" /> + id="stop5354" /> + id="stop5356" /> + id="stop5358" /> + id="stop5360" /> + id="linearGradient5367"> + id="stop5369" /> + id="stop5371" /> + id="stop5373" /> + id="stop5375" /> + id="stop5377" /> + id="linearGradient5380"> + id="stop5382" /> + id="stop5384" /> + id="linearGradient5387"> + id="stop5389" /> + id="stop5391" /> + id="linearGradient5394"> + id="stop5396" /> + id="stop5398" /> + id="linearGradient5401"> + id="stop5403" /> + id="stop5405" /> + id="linearGradient5408"> + id="stop5410" /> + id="stop5412" /> + id="linearGradient5415"> + id="stop5417" /> + id="stop5419" /> + id="linearGradient5422"> + id="stop5424" /> + id="stop5426" /> + id="linearGradient5429"> + id="stop5431" /> + id="stop5433" /> + id="linearGradient5436"> + id="stop5438" /> + id="stop5440" /> + id="linearGradient5443"> + id="stop5445" /> + id="stop5447" /> + id="linearGradient5450"> + id="stop5452" /> + id="stop5454" /> + id="linearGradient5459"> + id="stop5461" /> + id="stop5463" /> + id="linearGradient5466"> + id="stop5468" /> + id="stop5470" /> + id="linearGradient5473"> + id="stop5475" /> + id="stop5477" /> + id="linearGradient5480"> + id="stop5482" /> + id="stop5484" /> + id="linearGradient5489"> + id="stop5491" /> + id="stop5493" /> + id="linearGradient5498"> + id="stop5500" /> + id="stop5502" /> + id="linearGradient5507"> + id="stop5509" /> + id="stop5511" /> + id="linearGradient5516"> + id="stop5518" /> + id="stop5520" /> + id="linearGradient5525"> + id="stop5527" /> + id="stop5529" /> + id="linearGradient5534"> + id="stop5536" /> + id="stop5538" /> + id="linearGradient5550"> + id="stop5552" /> + id="stop5554" /> + id="stop5556" /> + id="stop5558" /> + id="stop5560" /> + id="linearGradient4583"> + id="linearGradient5570"> + id="stop5572" /> + id="stop5574" /> + id="stop5576" /> + id="feGaussianBlur5592" /> + id="feGaussianBlur5602" /> + id="feGaussianBlur5606" /> + id="linearGradient5609"> + id="stop5611" /> + id="stop5613" /> + id="linearGradient5618"> + id="stop5620" /> + id="stop5622" /> + id="linearGradient5627"> + id="stop5629" /> + id="stop5631" /> + id="linearGradient5634"> + id="stop5636" /> + id="stop5638" /> + id="linearGradient5641"> + id="stop5643" /> + id="stop5645" /> + id="feGaussianBlur5649" /> + id="linearGradient5652"> + id="stop5654" /> + id="stop5656" /> + id="linearGradient5659"> + id="stop5661" /> + id="stop5663" /> + id="linearGradient5668"> + id="stop5670" /> + id="stop5672" /> + id="stop5674" /> + id="stop5676" /> + id="stop5678" /> + id="linearGradient5681"> + id="stop5683" /> + id="stop5685" /> - - + inkscape:window-maximized="1" + inkscape:showpageshadow="false" + showborder="true" /> + id="metadata7"> @@ -2568,527 +1907,545 @@ - + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(0,-980.36218)"> + + Copyright © 1996-2014 ReactOS Team & Contributors + transform="matrix(0.16958533,0,0,0.16958533,89.849943,981.79073)" + id="g15501"> + id="g15398"> + id="g15296"> + id="g15195"> + id="g15095"> + id="g14996"> - - - - - - - - - - - - - - - - - - - - + style="fill-rule:nonzero" + id="g14217" + transform="matrix(1.7547748,0,0,1.7612968,151.71989,-245.7869)"> + style="fill:#ffffff" + id="g14219" + transform="matrix(0.7424504,0,0,0.7446541,98.39156,63.707562)"> + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + id="g14632"> + id="g14554"> + id="path14101" + d="m 386.64071,183.59775 c 0,62.56097 -50.62472,113.27685 -113.07315,113.27685 -62.44877,0 -113.07315,-50.71569 -113.07315,-113.27685 0,-62.56098 50.62473,-113.276856 113.07315,-113.276856 62.44878,0 113.07315,50.715686 113.07315,113.276856 z" /> + id="path14103" + d="m 401.94096,167.78741 c 0,62.56097 -50.62472,113.27685 -113.07315,113.27685 -62.44877,0 -113.07315,-50.71569 -113.07315,-113.27685 0,-62.56098 50.62473,-113.276856 113.07315,-113.276856 62.44878,0 113.07315,50.715686 113.07315,113.276856 z" /> + id="path14105" + d="m 177.43211,148.56198 c -2.648,15.347 -2.047,30.515 1.257,44.795 0.632,2.734 1.358,5.434 2.187,8.098 0.003,0.007 -0.002,0.017 0,0.024 0.275,0.882 0.565,1.755 0.861,2.629 0.583,1.72 1.199,3.411 1.862,5.096 0.013,0.033 0.034,0.061 0.047,0.093 0.009,0.023 0.014,0.047 0.023,0.07 0.647,1.639 1.326,3.283 2.048,4.887 0.021,0.047 0.048,0.093 0.069,0.14 0.353,0.78 0.701,1.555 1.071,2.327 0.027,0.056 0.066,0.106 0.093,0.163 0.374,0.777 0.749,1.558 1.14,2.327 0.191,0.374 0.387,0.744 0.582,1.117 0.249,0.475 0.489,0.947 0.745,1.419 0.034,0.064 0.081,0.122 0.116,0.186 0.365,0.672 0.739,1.338 1.117,2.002 0.045,0.078 0.095,0.154 0.14,0.232 0.433,0.756 0.875,1.512 1.326,2.258 0.047,0.077 0.092,0.155 0.14,0.232 1.387,2.283 2.855,4.524 4.398,6.702 0.466,0.658 0.94,1.307 1.419,1.955 0.06,0.08 0.127,0.153 0.186,0.233 16.703,22.429 41.66,38.742 71.348,43.864 5.315,-25.965 -14.767,-42.512 -29.554,-56.663 -2.392,-4.189 -10.443,-7.435 -13.799,-11.985 -11.027,-17.094 -27.558,-32.763 -48.822,-62.201 z" /> + id="path14107" + d="m 401.94111,167.78698 c 0.273,21.378 -6.183,42.928 -18.113,61.405 -5.965,9.239 -13.299,17.709 -21.844,25.005 -21.015,-0.527 -35.043,-9.597 -36.802,-14.473 27.237,-25.009 47.426,-57.083 40.464,-67.826 4.648,-12.087 12.152,-24.235 18.157,-33.398 l 9.536,-14.552 c 5.954,13.673 8.652,29.467 8.602,43.839 z" /> + id="path14109" + d="m 383.83829,132.07019 c 2.70931,7.86826 -1.63804,14.2167 -9.71011,14.17964 -8.07204,-0.0371 -16.81209,-6.44561 -19.5214,-14.31387 -2.70931,-7.86825 1.63803,-14.21669 9.71011,-14.17963 8.07204,0.0371 16.81209,6.44561 19.5214,14.31386 z" /> + id="path14111" + d="m 378.1231,130.64139 c 2.70931,7.86826 -1.63804,14.2167 -9.71011,14.17964 -8.07204,-0.0371 -16.81209,-6.44561 -19.5214,-14.31387 -2.70931,-7.86825 1.63803,-14.21669 9.71011,-14.17963 8.07204,0.0371 16.81209,6.44561 19.5214,14.31386 z" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - @@ -3099,16 +2456,4 @@ - Copyright © 1996-2014 ReactOS Team & Contributors diff --git a/dll/win32/mshtml/CMakeLists.txt b/dll/win32/mshtml/CMakeLists.txt index f2866888cec..d0de62d0140 100644 --- a/dll/win32/mshtml/CMakeLists.txt +++ b/dll/win32/mshtml/CMakeLists.txt @@ -21,8 +21,6 @@ list(APPEND SOURCE htmlcomment.c htmlcurstyle.c htmldoc.c - htmldoc3.c - htmldoc5.c htmlelem.c htmlelem2.c htmlelem3.c diff --git a/dll/win32/mshtml/binding.h b/dll/win32/mshtml/binding.h index 392713b56f8..63ac8828327 100644 --- a/dll/win32/mshtml/binding.h +++ b/dll/win32/mshtml/binding.h @@ -49,6 +49,12 @@ typedef struct { struct list request_headers; } nsChannel; +typedef struct { + WCHAR *headers; + HGLOBAL post_data; + ULONG post_data_len; +} request_data_t; + typedef struct BSCallbackVtbl BSCallbackVtbl; struct BSCallback { @@ -61,9 +67,7 @@ struct BSCallback { LONG ref; - LPWSTR headers; - HGLOBAL post_data; - ULONG post_data_len; + request_data_t request_data; ULONG readed; DWORD bindf; BOOL bindinfo_ready; @@ -102,6 +106,8 @@ typedef struct { #define BINDING_REPLACE 0x0002 #define BINDING_FROMHIST 0x0004 #define BINDING_REFRESH 0x0008 +#define BINDING_SUBMIT 0x0010 +#define BINDING_NOFRAG 0x0020 HRESULT set_http_header(struct list*,const WCHAR*,int,const WCHAR*,int) DECLSPEC_HIDDEN; HRESULT create_redirect_nschannel(const WCHAR*,nsChannel*,nsChannel**) DECLSPEC_HIDDEN; @@ -116,9 +122,10 @@ HRESULT super_navigate(HTMLOuterWindow*,IUri*,DWORD,const WCHAR*,BYTE*,DWORD) DE HRESULT load_uri(HTMLOuterWindow*,IUri*,DWORD) DECLSPEC_HIDDEN; HRESULT navigate_new_window(HTMLOuterWindow*,IUri*,const WCHAR*,IHTMLWindow2**) DECLSPEC_HIDDEN; HRESULT navigate_url(HTMLOuterWindow*,const WCHAR*,IUri*,DWORD) DECLSPEC_HIDDEN; +HRESULT submit_form(HTMLOuterWindow*,IUri*,nsIInputStream*) DECLSPEC_HIDDEN; HRESULT create_channelbsc(IMoniker*,const WCHAR*,BYTE*,DWORD,BOOL,nsChannelBSC**) DECLSPEC_HIDDEN; -HRESULT channelbsc_load_stream(HTMLInnerWindow*,IStream*) DECLSPEC_HIDDEN; +HRESULT channelbsc_load_stream(HTMLInnerWindow*,IMoniker*,IStream*) DECLSPEC_HIDDEN; void channelbsc_set_channel(nsChannelBSC*,nsChannel*,nsIStreamListener*,nsISupports*) DECLSPEC_HIDDEN; IUri *nsuri_get_uri(nsWineURI*) DECLSPEC_HIDDEN; diff --git a/dll/win32/mshtml/htmlanchor.c b/dll/win32/mshtml/htmlanchor.c index 4aee0f718ff..85332c043f1 100644 --- a/dll/win32/mshtml/htmlanchor.c +++ b/dll/win32/mshtml/htmlanchor.c @@ -53,47 +53,81 @@ static HRESULT navigate_anchor_window(HTMLAnchorElement *This, const WCHAR *targ return hres; } -static HRESULT navigate_anchor(HTMLAnchorElement *This) +HTMLOuterWindow *get_target_window(HTMLOuterWindow *window, nsAString *target_str, BOOL *use_new_window) { - nsAString href_str, target_str; - HTMLOuterWindow *window = NULL; - nsresult nsres; - HRESULT hres = E_FAIL; + HTMLOuterWindow *top_window, *ret_window; + const PRUnichar *target; + HRESULT hres; - static const WCHAR _parentW[] = {'p','a','r','e','n','t',0}; + static const WCHAR _parentW[] = {'_','p','a','r','e','n','t',0}; static const WCHAR _selfW[] = {'_','s','e','l','f',0}; static const WCHAR _topW[] = {'_','t','o','p',0}; + *use_new_window = FALSE; + + nsAString_GetData(target_str, &target); + TRACE("%s\n", debugstr_w(target)); + + if(!*target || !strcmpiW(target, _selfW)) { + IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface); + return window; + } + + if(!strcmpiW(target, _topW)) { + get_top_window(window, &top_window); + IHTMLWindow2_AddRef(&top_window->base.IHTMLWindow2_iface); + return top_window; + } + + if(!strcmpiW(target, _parentW)) { + if(!window->parent) { + WARN("Window has no parent\n"); + return NULL; + } + + IHTMLWindow2_AddRef(&window->parent->base.IHTMLWindow2_iface); + return window->parent; + } + + get_top_window(window, &top_window); + + hres = get_frame_by_name(top_window, target, TRUE, &ret_window); + if(FAILED(hres) || !ret_window) { + *use_new_window = TRUE; + return NULL; + } + + IHTMLWindow2_AddRef(&ret_window->base.IHTMLWindow2_iface); + return ret_window; +} + +static HRESULT navigate_anchor(HTMLAnchorElement *This) +{ + nsAString href_str, target_str; + HTMLOuterWindow *window; + BOOL use_new_window; + nsresult nsres; + HRESULT hres = E_FAIL; + + nsAString_Init(&target_str, NULL); nsres = nsIDOMHTMLAnchorElement_GetTarget(This->nsanchor, &target_str); - if(NS_SUCCEEDED(nsres)) { + if(NS_FAILED(nsres)) + return E_FAIL; + + window = get_target_window(This->element.node.doc->basedoc.window, &target_str, &use_new_window); + if(!window && use_new_window) { const PRUnichar *target; nsAString_GetData(&target_str, &target); - TRACE("target %s\n", debugstr_w(target)); - if(*target && strcmpiW(target, _selfW)) { - if(!strcmpiW(target, _topW)) { - TRACE("target _top\n"); - get_top_window(This->element.node.doc->basedoc.window, &window); - }else if(!strcmpiW(target, _parentW)) { - FIXME("Navigating to target _parent is not implemented\n"); - nsAString_Finish(&target_str); - return S_OK; - }else { - HTMLOuterWindow *top_window; - - get_top_window(This->element.node.doc->basedoc.window, &top_window); - - hres = get_frame_by_name(top_window, target, TRUE, &window); - if(FAILED(hres) || !window) { - hres = navigate_anchor_window(This, target); - nsAString_Finish(&target_str); - return hres; - } - } - } + hres = navigate_anchor_window(This, target); + nsAString_Finish(&target_str); + return hres; } + nsAString_Finish(&target_str); + if(!window) + return S_OK; nsAString_Init(&href_str, NULL); nsres = nsIDOMHTMLAnchorElement_GetHref(This->nsanchor, &href_str); @@ -102,15 +136,14 @@ static HRESULT navigate_anchor(HTMLAnchorElement *This) nsAString_GetData(&href_str, &href); if(*href) { - if(!window) - window = This->element.node.doc->basedoc.window; - hres = navigate_url(window, href, window->uri, BINDING_NAVIGATED); + hres = navigate_url(window, href, window->uri_nofrag, BINDING_NAVIGATED); }else { TRACE("empty href\n"); hres = S_OK; } } nsAString_Finish(&href_str); + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); return hres; } diff --git a/dll/win32/mshtml/htmlbody.c b/dll/win32/mshtml/htmlbody.c index 69ea194da16..eb01b961085 100644 --- a/dll/win32/mshtml/htmlbody.c +++ b/dll/win32/mshtml/htmlbody.c @@ -108,7 +108,7 @@ static int loose_hex_to_rgb(const WCHAR *hex) | comp_value(hex+2*dpc, dpc); } -static HRESULT nscolor_to_str(LPCWSTR color, BSTR *ret) +HRESULT nscolor_to_str(LPCWSTR color, BSTR *ret) { unsigned int i; int rgb = -1; @@ -139,7 +139,7 @@ static HRESULT nscolor_to_str(LPCWSTR color, BSTR *ret) return S_OK; } -static BOOL variant_to_nscolor(const VARIANT *v, nsAString *nsstr) +BOOL variant_to_nscolor(const VARIANT *v, nsAString *nsstr) { switch(V_VT(v)) { case VT_BSTR: @@ -587,18 +587,71 @@ static HRESULT WINAPI HTMLBodyElement_get_onunload(IHTMLBodyElement *iface, VARI return E_NOTIMPL; } +static const WCHAR autoW[] = {'a','u','t','o',0}; +static const WCHAR hiddenW[] = {'h','i','d','d','e','n',0}; +static const WCHAR scrollW[] = {'s','c','r','o','l','l',0}; +static const WCHAR visibleW[] = {'v','i','s','i','b','l','e',0}; +static const WCHAR yesW[] = {'y','e','s',0}; +static const WCHAR noW[] = {'n','o',0}; + static HRESULT WINAPI HTMLBodyElement_put_scroll(IHTMLBodyElement *iface, BSTR v) { HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; + static const WCHAR *val; + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + /* Emulate with CSS visibility attribute */ + if(!strcmpW(v, yesW)) { + val = scrollW; + }else if(!strcmpW(v, autoW)) { + val = visibleW; + }else if(!strcmpW(v, noW)) { + val = hiddenW; + }else { + WARN("Invalid argument %s\n", debugstr_w(v)); + return E_INVALIDARG; + } + + return set_elem_style(&This->textcont.element, STYLEID_OVERFLOW, val); } static HRESULT WINAPI HTMLBodyElement_get_scroll(IHTMLBodyElement *iface, BSTR *p) { HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + const WCHAR *ret = NULL; + BSTR overflow; + HRESULT hres; + + TRACE("(%p)->(%p)\n", This, p); + + /* Emulate with CSS visibility attribute */ + hres = get_elem_style(&This->textcont.element, STYLEID_OVERFLOW, &overflow); + if(FAILED(hres)) + return hres; + + if(!overflow || !*overflow) { + *p = NULL; + hres = S_OK; + }else if(!strcmpW(overflow, visibleW) || !strcmpW(overflow, autoW)) { + ret = autoW; + }else if(!strcmpW(overflow, scrollW)) { + ret = yesW; + }else if(!strcmpW(overflow, hiddenW)) { + ret = noW; + }else { + TRACE("Defaulting %s to NULL\n", debugstr_w(overflow)); + *p = NULL; + hres = S_OK; + } + + SysFreeString(overflow); + if(ret) { + *p = SysAllocString(ret); + hres = *p ? S_OK : E_OUTOFMEMORY; + } + + return hres; } static HRESULT WINAPI HTMLBodyElement_put_onselect(IHTMLBodyElement *iface, VARIANT v) diff --git a/dll/win32/mshtml/htmldoc.c b/dll/win32/mshtml/htmldoc.c index 6e1fc5db568..a6516be34d3 100644 --- a/dll/win32/mshtml/htmldoc.c +++ b/dll/win32/mshtml/htmldoc.c @@ -18,6 +18,79 @@ #include "mshtml_private.h" +HRESULT get_doc_elem_by_id(HTMLDocumentNode *doc, const WCHAR *id, HTMLElement **ret) +{ + nsIDOMNodeList *nsnode_list; + nsIDOMElement *nselem; + nsIDOMNode *nsnode; + nsAString id_str; + nsresult nsres; + HRESULT hres; + + if(!doc->nsdoc) { + WARN("NULL nsdoc\n"); + return E_UNEXPECTED; + } + + nsAString_InitDepend(&id_str, id); + /* get element by id attribute */ + nsres = nsIDOMHTMLDocument_GetElementById(doc->nsdoc, &id_str, &nselem); + if(FAILED(nsres)) { + ERR("GetElementById failed: %08x\n", nsres); + nsAString_Finish(&id_str); + return E_FAIL; + } + + /* get first element by name attribute */ + nsres = nsIDOMHTMLDocument_GetElementsByName(doc->nsdoc, &id_str, &nsnode_list); + nsAString_Finish(&id_str); + if(FAILED(nsres)) { + ERR("getElementsByName failed: %08x\n", nsres); + if(nselem) + nsIDOMElement_Release(nselem); + return E_FAIL; + } + + nsres = nsIDOMNodeList_Item(nsnode_list, 0, &nsnode); + nsIDOMNodeList_Release(nsnode_list); + assert(nsres == NS_OK); + + if(nsnode && nselem) { + UINT16 pos; + + nsres = nsIDOMNode_CompareDocumentPosition(nsnode, (nsIDOMNode*)nselem, &pos); + if(NS_FAILED(nsres)) { + FIXME("CompareDocumentPosition failed: 0x%08x\n", nsres); + nsIDOMNode_Release(nsnode); + nsIDOMElement_Release(nselem); + return E_FAIL; + } + + TRACE("CompareDocumentPosition gave: 0x%x\n", pos); + if(!(pos & (DOCUMENT_POSITION_PRECEDING | DOCUMENT_POSITION_CONTAINS))) { + nsIDOMElement_Release(nselem); + nselem = NULL; + } + } + + if(nsnode) { + if(!nselem) { + nsres = nsIDOMNode_QueryInterface(nsnode, &IID_nsIDOMElement, (void**)&nselem); + assert(nsres == NS_OK); + } + nsIDOMNode_Release(nsnode); + } + + if(!nselem) { + *ret = NULL; + return S_OK; + } + + hres = get_elem(doc, nselem, ret); + nsIDOMElement_Release(nselem); + return hres; +} + static inline HTMLDocument *impl_from_IHTMLDocument2(IHTMLDocument2 *iface) { return CONTAINING_RECORD(iface, HTMLDocument, IHTMLDocument2_iface); @@ -163,8 +236,35 @@ static HRESULT WINAPI HTMLDocument_get_body(IHTMLDocument2 *iface, IHTMLElement static HRESULT WINAPI HTMLDocument_get_activeElement(IHTMLDocument2 *iface, IHTMLElement **p) { HTMLDocument *This = impl_from_IHTMLDocument2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + nsIDOMElement *nselem; + HTMLElement *elem; + nsresult nsres; + HRESULT hres; + + TRACE("(%p)->(%p)\n", This, p); + + if(!This->doc_node->nsdoc) { + *p = NULL; + return S_OK; + } + + /* + * NOTE: Gecko may return an active element even if the document is not visible. + * IE returns NULL in this case. + */ + nsres = nsIDOMHTMLDocument_GetActiveElement(This->doc_node->nsdoc, &nselem); + if(NS_FAILED(nsres)) { + ERR("GetActiveElement failed: %08x\n", nsres); + return E_FAIL; + } + + hres = get_elem(This->doc_node, nselem, &elem); + nsIDOMElement_Release(nselem); + if(FAILED(hres)) + return hres; + + *p = &elem->IHTMLElement_iface; + return S_OK; } static HRESULT WINAPI HTMLDocument_get_images(IHTMLDocument2 *iface, IHTMLElementCollection **p) @@ -437,7 +537,7 @@ static HRESULT WINAPI HTMLDocument_put_designMode(IHTMLDocument2 *iface, BSTR v) static HRESULT WINAPI HTMLDocument_get_designMode(IHTMLDocument2 *iface, BSTR *p) { HTMLDocument *This = impl_from_IHTMLDocument2(iface); - static WCHAR szOff[] = {'O','f','f',0}; + static const WCHAR szOff[] = {'O','f','f',0}; FIXME("(%p)->(%p) always returning Off\n", This, p); if(!p) @@ -1633,12 +1733,2087 @@ static const IHTMLDocument2Vtbl HTMLDocumentVtbl = { HTMLDocument_createStyleSheet }; +static inline HTMLDocument *impl_from_IHTMLDocument3(IHTMLDocument3 *iface) +{ + return CONTAINING_RECORD(iface, HTMLDocument, IHTMLDocument3_iface); +} + +static HRESULT WINAPI HTMLDocument3_QueryInterface(IHTMLDocument3 *iface, + REFIID riid, void **ppv) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + return htmldoc_query_interface(This, riid, ppv); +} + +static ULONG WINAPI HTMLDocument3_AddRef(IHTMLDocument3 *iface) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + return htmldoc_addref(This); +} + +static ULONG WINAPI HTMLDocument3_Release(IHTMLDocument3 *iface) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + return htmldoc_release(This); +} + +static HRESULT WINAPI HTMLDocument3_GetTypeInfoCount(IHTMLDocument3 *iface, UINT *pctinfo) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + return IDispatchEx_GetTypeInfoCount(&This->IDispatchEx_iface, pctinfo); +} + +static HRESULT WINAPI HTMLDocument3_GetTypeInfo(IHTMLDocument3 *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + return IDispatchEx_GetTypeInfo(&This->IDispatchEx_iface, iTInfo, lcid, ppTInfo); +} + +static HRESULT WINAPI HTMLDocument3_GetIDsOfNames(IHTMLDocument3 *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, + LCID lcid, DISPID *rgDispId) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + return IDispatchEx_GetIDsOfNames(&This->IDispatchEx_iface, riid, rgszNames, cNames, lcid, + rgDispId); +} + +static HRESULT WINAPI HTMLDocument3_Invoke(IHTMLDocument3 *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + return IDispatchEx_Invoke(&This->IDispatchEx_iface, dispIdMember, riid, lcid, wFlags, + pDispParams, pVarResult, pExcepInfo, puArgErr); +} + +static HRESULT WINAPI HTMLDocument3_releaseCapture(IHTMLDocument3 *iface) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_recalc(IHTMLDocument3 *iface, VARIANT_BOOL fForce) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->(%x)\n", This, fForce); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_createTextNode(IHTMLDocument3 *iface, BSTR text, + IHTMLDOMNode **newTextNode) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + nsIDOMText *nstext; + HTMLDOMNode *node; + nsAString text_str; + nsresult nsres; + HRESULT hres; + + TRACE("(%p)->(%s %p)\n", This, debugstr_w(text), newTextNode); + + if(!This->doc_node->nsdoc) { + WARN("NULL nsdoc\n"); + return E_UNEXPECTED; + } + + nsAString_InitDepend(&text_str, text); + nsres = nsIDOMHTMLDocument_CreateTextNode(This->doc_node->nsdoc, &text_str, &nstext); + nsAString_Finish(&text_str); + if(NS_FAILED(nsres)) { + ERR("CreateTextNode failed: %08x\n", nsres); + return E_FAIL; + } + + hres = HTMLDOMTextNode_Create(This->doc_node, (nsIDOMNode*)nstext, &node); + nsIDOMText_Release(nstext); + if(FAILED(hres)) + return hres; + + *newTextNode = &node->IHTMLDOMNode_iface; + return S_OK; +} + +static HRESULT WINAPI HTMLDocument3_get_documentElement(IHTMLDocument3 *iface, IHTMLElement **p) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + nsIDOMElement *nselem = NULL; + HTMLDOMNode *node; + nsresult nsres; + HRESULT hres; + + TRACE("(%p)->(%p)\n", This, p); + + if(This->window->readystate == READYSTATE_UNINITIALIZED) { + *p = NULL; + return S_OK; + } + + if(!This->doc_node->nsdoc) { + WARN("NULL nsdoc\n"); + return E_UNEXPECTED; + } + + nsres = nsIDOMHTMLDocument_GetDocumentElement(This->doc_node->nsdoc, &nselem); + if(NS_FAILED(nsres)) { + ERR("GetDocumentElement failed: %08x\n", nsres); + return E_FAIL; + } + + if(!nselem) { + *p = NULL; + return S_OK; + } + + hres = get_node(This->doc_node, (nsIDOMNode *)nselem, TRUE, &node); + nsIDOMElement_Release(nselem); + if(FAILED(hres)) + return hres; + + hres = IHTMLDOMNode_QueryInterface(&node->IHTMLDOMNode_iface, &IID_IHTMLElement, (void**)p); + node_release(node); + return hres; +} + +static HRESULT WINAPI HTMLDocument3_uniqueID(IHTMLDocument3 *iface, BSTR *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_attachEvent(IHTMLDocument3 *iface, BSTR event, + IDispatch* pDisp, VARIANT_BOOL *pfResult) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + + TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(event), pDisp, pfResult); + + return attach_event(&This->doc_node->node.event_target, This, event, pDisp, pfResult); +} + +static HRESULT WINAPI HTMLDocument3_detachEvent(IHTMLDocument3 *iface, BSTR event, + IDispatch *pDisp) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_w(event), pDisp); + + return detach_event(This->doc_node->node.event_target, This, event, pDisp); +} + +static HRESULT WINAPI HTMLDocument3_put_onrowsdelete(IHTMLDocument3 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_get_onrowsdelete(IHTMLDocument3 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_put_onrowsinserted(IHTMLDocument3 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_get_onrowsinserted(IHTMLDocument3 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_put_oncellchange(IHTMLDocument3 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_get_oncellchange(IHTMLDocument3 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_put_ondatasetchanged(IHTMLDocument3 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_get_ondatasetchanged(IHTMLDocument3 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_put_ondataavailable(IHTMLDocument3 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_get_ondataavailable(IHTMLDocument3 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_put_ondatasetcomplete(IHTMLDocument3 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_get_ondatasetcomplete(IHTMLDocument3 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_put_onpropertychange(IHTMLDocument3 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_get_onpropertychange(IHTMLDocument3 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_put_dir(IHTMLDocument3 *iface, BSTR v) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_get_dir(IHTMLDocument3 *iface, BSTR *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_put_oncontextmenu(IHTMLDocument3 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + + TRACE("(%p)->()\n", This); + + return set_doc_event(This, EVENTID_CONTEXTMENU, &v); +} + +static HRESULT WINAPI HTMLDocument3_get_oncontextmenu(IHTMLDocument3 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + + TRACE("(%p)->(%p)\n", This, p); + + return get_doc_event(This, EVENTID_CONTEXTMENU, p); +} + +static HRESULT WINAPI HTMLDocument3_put_onstop(IHTMLDocument3 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_get_onstop(IHTMLDocument3 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_createDocumentFragment(IHTMLDocument3 *iface, + IHTMLDocument2 **ppNewDoc) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + nsIDOMDocumentFragment *doc_frag; + HTMLDocumentNode *docnode; + nsresult nsres; + HRESULT hres; + + TRACE("(%p)->(%p)\n", This, ppNewDoc); + + if(!This->doc_node->nsdoc) { + FIXME("NULL nsdoc\n"); + return E_NOTIMPL; + } + + nsres = nsIDOMHTMLDocument_CreateDocumentFragment(This->doc_node->nsdoc, &doc_frag); + if(NS_FAILED(nsres)) { + ERR("CreateDocumentFragment failed: %08x\n", nsres); + return E_FAIL; + } + + hres = create_document_fragment((nsIDOMNode*)doc_frag, This->doc_node, &docnode); + nsIDOMDocumentFragment_Release(doc_frag); + if(FAILED(hres)) + return hres; + + *ppNewDoc = &docnode->basedoc.IHTMLDocument2_iface; + return S_OK; +} + +static HRESULT WINAPI HTMLDocument3_get_parentDocument(IHTMLDocument3 *iface, + IHTMLDocument2 **p) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_put_enableDownload(IHTMLDocument3 *iface, + VARIANT_BOOL v) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->(%x)\n", This, v); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_get_enableDownload(IHTMLDocument3 *iface, + VARIANT_BOOL *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_put_baseUrl(IHTMLDocument3 *iface, BSTR v) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_get_baseUrl(IHTMLDocument3 *iface, BSTR *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_get_childNodes(IHTMLDocument3 *iface, IDispatch **p) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + + TRACE("(%p)->(%p)\n", This, p); + + return IHTMLDOMNode_get_childNodes(&This->doc_node->node.IHTMLDOMNode_iface, p); +} + +static HRESULT WINAPI HTMLDocument3_put_inheritStyleSheets(IHTMLDocument3 *iface, + VARIANT_BOOL v) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_get_inheritStyleSheets(IHTMLDocument3 *iface, + VARIANT_BOOL *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_put_onbeforeeditfocus(IHTMLDocument3 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_get_onbeforeeditfocus(IHTMLDocument3 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument3_getElementsByName(IHTMLDocument3 *iface, BSTR v, + IHTMLElementCollection **ppelColl) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + nsIDOMNodeList *node_list; + nsAString selector_str; + WCHAR *selector; + nsresult nsres; + + static const WCHAR formatW[] = {'*','[','i','d','=','%','s',']',',','*','[','n','a','m','e','=','%','s',']',0}; + + TRACE("(%p)->(%s %p)\n", This, debugstr_w(v), ppelColl); + + if(!This->doc_node || !This->doc_node->nsdoc) { + /* We should probably return an empty collection. */ + FIXME("No nsdoc\n"); + return E_NOTIMPL; + } + + selector = heap_alloc(2*SysStringLen(v)*sizeof(WCHAR) + sizeof(formatW)); + if(!selector) + return E_OUTOFMEMORY; + sprintfW(selector, formatW, v, v); + + /* + * NOTE: IE getElementsByName implementation differs from Gecko. It searches both name and id attributes. + * That's why we use CSS selector instead. We should also use name only when it applies to given element + * types and search should be case insensitive. Those are currently not supported properly. + */ + nsAString_InitDepend(&selector_str, selector); + nsres = nsIDOMNodeSelector_QuerySelectorAll(This->doc_node->nsnode_selector, &selector_str, &node_list); + nsAString_Finish(&selector_str); + heap_free(selector); + if(NS_FAILED(nsres)) { + ERR("QuerySelectorAll failed: %08x\n", nsres); + return E_FAIL; + } + + *ppelColl = create_collection_from_nodelist(This->doc_node, node_list); + nsIDOMNodeList_Release(node_list); + return S_OK; +} + + +static HRESULT WINAPI HTMLDocument3_getElementById(IHTMLDocument3 *iface, BSTR v, + IHTMLElement **pel) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + HTMLElement *elem; + HRESULT hres; + + TRACE("(%p)->(%s %p)\n", This, debugstr_w(v), pel); + + hres = get_doc_elem_by_id(This->doc_node, v, &elem); + if(FAILED(hres) || !elem) { + *pel = NULL; + return hres; + } + + *pel = &elem->IHTMLElement_iface; + return S_OK; +} + + +static HRESULT WINAPI HTMLDocument3_getElementsByTagName(IHTMLDocument3 *iface, BSTR v, + IHTMLElementCollection **pelColl) +{ + HTMLDocument *This = impl_from_IHTMLDocument3(iface); + nsIDOMNodeList *nslist; + nsAString id_str; + nsresult nsres; + + TRACE("(%p)->(%s %p)\n", This, debugstr_w(v), pelColl); + + if(!This->doc_node->nsdoc) { + WARN("NULL nsdoc\n"); + return E_UNEXPECTED; + } + + nsAString_InitDepend(&id_str, v); + nsres = nsIDOMHTMLDocument_GetElementsByTagName(This->doc_node->nsdoc, &id_str, &nslist); + nsAString_Finish(&id_str); + if(FAILED(nsres)) { + ERR("GetElementByName failed: %08x\n", nsres); + return E_FAIL; + } + + *pelColl = create_collection_from_nodelist(This->doc_node, nslist); + nsIDOMNodeList_Release(nslist); + + return S_OK; +} + +static const IHTMLDocument3Vtbl HTMLDocument3Vtbl = { + HTMLDocument3_QueryInterface, + HTMLDocument3_AddRef, + HTMLDocument3_Release, + HTMLDocument3_GetTypeInfoCount, + HTMLDocument3_GetTypeInfo, + HTMLDocument3_GetIDsOfNames, + HTMLDocument3_Invoke, + HTMLDocument3_releaseCapture, + HTMLDocument3_recalc, + HTMLDocument3_createTextNode, + HTMLDocument3_get_documentElement, + HTMLDocument3_uniqueID, + HTMLDocument3_attachEvent, + HTMLDocument3_detachEvent, + HTMLDocument3_put_onrowsdelete, + HTMLDocument3_get_onrowsdelete, + HTMLDocument3_put_onrowsinserted, + HTMLDocument3_get_onrowsinserted, + HTMLDocument3_put_oncellchange, + HTMLDocument3_get_oncellchange, + HTMLDocument3_put_ondatasetchanged, + HTMLDocument3_get_ondatasetchanged, + HTMLDocument3_put_ondataavailable, + HTMLDocument3_get_ondataavailable, + HTMLDocument3_put_ondatasetcomplete, + HTMLDocument3_get_ondatasetcomplete, + HTMLDocument3_put_onpropertychange, + HTMLDocument3_get_onpropertychange, + HTMLDocument3_put_dir, + HTMLDocument3_get_dir, + HTMLDocument3_put_oncontextmenu, + HTMLDocument3_get_oncontextmenu, + HTMLDocument3_put_onstop, + HTMLDocument3_get_onstop, + HTMLDocument3_createDocumentFragment, + HTMLDocument3_get_parentDocument, + HTMLDocument3_put_enableDownload, + HTMLDocument3_get_enableDownload, + HTMLDocument3_put_baseUrl, + HTMLDocument3_get_baseUrl, + HTMLDocument3_get_childNodes, + HTMLDocument3_put_inheritStyleSheets, + HTMLDocument3_get_inheritStyleSheets, + HTMLDocument3_put_onbeforeeditfocus, + HTMLDocument3_get_onbeforeeditfocus, + HTMLDocument3_getElementsByName, + HTMLDocument3_getElementById, + HTMLDocument3_getElementsByTagName +}; + +static inline HTMLDocument *impl_from_IHTMLDocument4(IHTMLDocument4 *iface) +{ + return CONTAINING_RECORD(iface, HTMLDocument, IHTMLDocument4_iface); +} + +static HRESULT WINAPI HTMLDocument4_QueryInterface(IHTMLDocument4 *iface, + REFIID riid, void **ppv) +{ + HTMLDocument *This = impl_from_IHTMLDocument4(iface); + return htmldoc_query_interface(This, riid, ppv); +} + +static ULONG WINAPI HTMLDocument4_AddRef(IHTMLDocument4 *iface) +{ + HTMLDocument *This = impl_from_IHTMLDocument4(iface); + return htmldoc_addref(This); +} + +static ULONG WINAPI HTMLDocument4_Release(IHTMLDocument4 *iface) +{ + HTMLDocument *This = impl_from_IHTMLDocument4(iface); + return htmldoc_release(This); +} + +static HRESULT WINAPI HTMLDocument4_GetTypeInfoCount(IHTMLDocument4 *iface, UINT *pctinfo) +{ + HTMLDocument *This = impl_from_IHTMLDocument4(iface); + return IDispatchEx_GetTypeInfoCount(&This->IDispatchEx_iface, pctinfo); +} + +static HRESULT WINAPI HTMLDocument4_GetTypeInfo(IHTMLDocument4 *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + HTMLDocument *This = impl_from_IHTMLDocument4(iface); + return IDispatchEx_GetTypeInfo(&This->IDispatchEx_iface, iTInfo, lcid, ppTInfo); +} + +static HRESULT WINAPI HTMLDocument4_GetIDsOfNames(IHTMLDocument4 *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, + LCID lcid, DISPID *rgDispId) +{ + HTMLDocument *This = impl_from_IHTMLDocument4(iface); + return IDispatchEx_GetIDsOfNames(&This->IDispatchEx_iface, riid, rgszNames, cNames, lcid, + rgDispId); +} + +static HRESULT WINAPI HTMLDocument4_Invoke(IHTMLDocument4 *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + HTMLDocument *This = impl_from_IHTMLDocument4(iface); + return IDispatchEx_Invoke(&This->IDispatchEx_iface, dispIdMember, riid, lcid, wFlags, + pDispParams, pVarResult, pExcepInfo, puArgErr); +} + +static HRESULT WINAPI HTMLDocument4_focus(IHTMLDocument4 *iface) +{ + HTMLDocument *This = impl_from_IHTMLDocument4(iface); + nsIDOMHTMLElement *nsbody; + nsresult nsres; + + TRACE("(%p)->()\n", This); + + nsres = nsIDOMHTMLDocument_GetBody(This->doc_node->nsdoc, &nsbody); + if(NS_FAILED(nsres) || !nsbody) { + ERR("GetBody failed: %08x\n", nsres); + return E_FAIL; + } + + nsres = nsIDOMHTMLElement_Focus(nsbody); + nsIDOMHTMLElement_Release(nsbody); + if(NS_FAILED(nsres)) { + ERR("Focus failed: %08x\n", nsres); + return E_FAIL; + } + + return S_OK; +} + +static HRESULT WINAPI HTMLDocument4_hasFocus(IHTMLDocument4 *iface, VARIANT_BOOL *pfFocus) +{ + HTMLDocument *This = impl_from_IHTMLDocument4(iface); + FIXME("(%p)->(%p)\n", This, pfFocus); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument4_put_onselectionchange(IHTMLDocument4 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument4(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument4_get_onselectionchange(IHTMLDocument4 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument4(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument4_get_namespace(IHTMLDocument4 *iface, IDispatch **p) +{ + HTMLDocument *This = impl_from_IHTMLDocument4(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument4_createDocumentFromUrl(IHTMLDocument4 *iface, BSTR bstrUrl, + BSTR bstrOptions, IHTMLDocument2 **newDoc) +{ + HTMLDocument *This = impl_from_IHTMLDocument4(iface); + FIXME("(%p)->(%s %s %p)\n", This, debugstr_w(bstrUrl), debugstr_w(bstrOptions), newDoc); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument4_put_media(IHTMLDocument4 *iface, BSTR v) +{ + HTMLDocument *This = impl_from_IHTMLDocument4(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument4_get_media(IHTMLDocument4 *iface, BSTR *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument4(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument4_createEventObject(IHTMLDocument4 *iface, + VARIANT *pvarEventObject, IHTMLEventObj **ppEventObj) +{ + HTMLDocument *This = impl_from_IHTMLDocument4(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_variant(pvarEventObject), ppEventObj); + + if(pvarEventObject && V_VT(pvarEventObject) != VT_ERROR && V_VT(pvarEventObject) != VT_EMPTY) { + FIXME("unsupported pvarEventObject %s\n", debugstr_variant(pvarEventObject)); + return E_NOTIMPL; + } + + return create_event_obj(ppEventObj); +} + +static HRESULT WINAPI HTMLDocument4_fireEvent(IHTMLDocument4 *iface, BSTR bstrEventName, + VARIANT *pvarEventObject, VARIANT_BOOL *pfCanceled) +{ + HTMLDocument *This = impl_from_IHTMLDocument4(iface); + + TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(bstrEventName), pvarEventObject, pfCanceled); + + return dispatch_event(&This->doc_node->node, bstrEventName, pvarEventObject, pfCanceled); +} + +static HRESULT WINAPI HTMLDocument4_createRenderStyle(IHTMLDocument4 *iface, BSTR v, + IHTMLRenderStyle **ppIHTMLRenderStyle) +{ + HTMLDocument *This = impl_from_IHTMLDocument4(iface); + FIXME("(%p)->(%s %p)\n", This, debugstr_w(v), ppIHTMLRenderStyle); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument4_put_oncontrolselect(IHTMLDocument4 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument4(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument4_get_oncontrolselect(IHTMLDocument4 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument4(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument4_get_URLEncoded(IHTMLDocument4 *iface, BSTR *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument4(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static const IHTMLDocument4Vtbl HTMLDocument4Vtbl = { + HTMLDocument4_QueryInterface, + HTMLDocument4_AddRef, + HTMLDocument4_Release, + HTMLDocument4_GetTypeInfoCount, + HTMLDocument4_GetTypeInfo, + HTMLDocument4_GetIDsOfNames, + HTMLDocument4_Invoke, + HTMLDocument4_focus, + HTMLDocument4_hasFocus, + HTMLDocument4_put_onselectionchange, + HTMLDocument4_get_onselectionchange, + HTMLDocument4_get_namespace, + HTMLDocument4_createDocumentFromUrl, + HTMLDocument4_put_media, + HTMLDocument4_get_media, + HTMLDocument4_createEventObject, + HTMLDocument4_fireEvent, + HTMLDocument4_createRenderStyle, + HTMLDocument4_put_oncontrolselect, + HTMLDocument4_get_oncontrolselect, + HTMLDocument4_get_URLEncoded +}; + +static inline HTMLDocument *impl_from_IHTMLDocument5(IHTMLDocument5 *iface) +{ + return CONTAINING_RECORD(iface, HTMLDocument, IHTMLDocument5_iface); +} + +static HRESULT WINAPI HTMLDocument5_QueryInterface(IHTMLDocument5 *iface, + REFIID riid, void **ppv) +{ + HTMLDocument *This = impl_from_IHTMLDocument5(iface); + return htmldoc_query_interface(This, riid, ppv); +} + +static ULONG WINAPI HTMLDocument5_AddRef(IHTMLDocument5 *iface) +{ + HTMLDocument *This = impl_from_IHTMLDocument5(iface); + return htmldoc_addref(This); +} + +static ULONG WINAPI HTMLDocument5_Release(IHTMLDocument5 *iface) +{ + HTMLDocument *This = impl_from_IHTMLDocument5(iface); + return htmldoc_release(This); +} + +static HRESULT WINAPI HTMLDocument5_GetTypeInfoCount(IHTMLDocument5 *iface, UINT *pctinfo) +{ + HTMLDocument *This = impl_from_IHTMLDocument5(iface); + return IDispatchEx_GetTypeInfoCount(&This->IDispatchEx_iface, pctinfo); +} + +static HRESULT WINAPI HTMLDocument5_GetTypeInfo(IHTMLDocument5 *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + HTMLDocument *This = impl_from_IHTMLDocument5(iface); + return IDispatchEx_GetTypeInfo(&This->IDispatchEx_iface, iTInfo, lcid, ppTInfo); +} + +static HRESULT WINAPI HTMLDocument5_GetIDsOfNames(IHTMLDocument5 *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + HTMLDocument *This = impl_from_IHTMLDocument5(iface); + return IDispatchEx_GetIDsOfNames(&This->IDispatchEx_iface, riid, rgszNames, cNames, lcid, + rgDispId); +} + +static HRESULT WINAPI HTMLDocument5_Invoke(IHTMLDocument5 *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + HTMLDocument *This = impl_from_IHTMLDocument5(iface); + return IDispatchEx_Invoke(&This->IDispatchEx_iface, dispIdMember, riid, lcid, wFlags, + pDispParams, pVarResult, pExcepInfo, puArgErr); +} + +static HRESULT WINAPI HTMLDocument5_put_onmousewheel(IHTMLDocument5 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument5(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument5_get_onmousewheel(IHTMLDocument5 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument5(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument5_get_doctype(IHTMLDocument5 *iface, IHTMLDOMNode **p) +{ + HTMLDocument *This = impl_from_IHTMLDocument5(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument5_get_implementation(IHTMLDocument5 *iface, IHTMLDOMImplementation **p) +{ + HTMLDocument *This = impl_from_IHTMLDocument5(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument5_createAttribute(IHTMLDocument5 *iface, BSTR bstrattrName, + IHTMLDOMAttribute **ppattribute) +{ + HTMLDocument *This = impl_from_IHTMLDocument5(iface); + HTMLDOMAttribute *attr; + HRESULT hres; + + TRACE("(%p)->(%s %p)\n", This, debugstr_w(bstrattrName), ppattribute); + + hres = HTMLDOMAttribute_Create(bstrattrName, NULL, 0, &attr); + if(FAILED(hres)) + return hres; + + *ppattribute = &attr->IHTMLDOMAttribute_iface; + return S_OK; +} + +static HRESULT WINAPI HTMLDocument5_createComment(IHTMLDocument5 *iface, BSTR bstrdata, + IHTMLDOMNode **ppRetNode) +{ + HTMLDocument *This = impl_from_IHTMLDocument5(iface); + nsIDOMComment *nscomment; + HTMLElement *elem; + nsAString str; + nsresult nsres; + HRESULT hres; + + TRACE("(%p)->(%s %p)\n", This, debugstr_w(bstrdata), ppRetNode); + + if(!This->doc_node->nsdoc) { + WARN("NULL nsdoc\n"); + return E_UNEXPECTED; + } + + nsAString_InitDepend(&str, bstrdata); + nsres = nsIDOMHTMLDocument_CreateComment(This->doc_node->nsdoc, &str, &nscomment); + nsAString_Finish(&str); + if(NS_FAILED(nsres)) { + ERR("CreateTextNode failed: %08x\n", nsres); + return E_FAIL; + } + + hres = HTMLCommentElement_Create(This->doc_node, (nsIDOMNode*)nscomment, &elem); + nsIDOMComment_Release(nscomment); + if(FAILED(hres)) + return hres; + + *ppRetNode = &elem->node.IHTMLDOMNode_iface; + return S_OK; +} + +static HRESULT WINAPI HTMLDocument5_put_onfocusin(IHTMLDocument5 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument5(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument5_get_onfocusin(IHTMLDocument5 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument5(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument5_put_onfocusout(IHTMLDocument5 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument5(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument5_get_onfocusout(IHTMLDocument5 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument5(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument5_put_onactivate(IHTMLDocument5 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument5(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument5_get_onactivate(IHTMLDocument5 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument5(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument5_put_ondeactivate(IHTMLDocument5 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument5(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument5_get_ondeactivate(IHTMLDocument5 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument5(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument5_put_onbeforeactivate(IHTMLDocument5 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument5(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument5_get_onbeforeactivate(IHTMLDocument5 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument5(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument5_put_onbeforedeactivate(IHTMLDocument5 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument5(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument5_get_onbeforedeactivate(IHTMLDocument5 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument5(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument5_get_compatMode(IHTMLDocument5 *iface, BSTR *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument5(iface); + nsAString mode_str; + const PRUnichar *mode; + + TRACE("(%p)->(%p)\n", This, p); + + if(!This->doc_node->nsdoc) { + WARN("NULL nsdoc\n"); + return E_UNEXPECTED; + } + + nsAString_Init(&mode_str, NULL); + nsIDOMHTMLDocument_GetCompatMode(This->doc_node->nsdoc, &mode_str); + + nsAString_GetData(&mode_str, &mode); + *p = SysAllocString(mode); + nsAString_Finish(&mode_str); + + return S_OK; +} + +static const IHTMLDocument5Vtbl HTMLDocument5Vtbl = { + HTMLDocument5_QueryInterface, + HTMLDocument5_AddRef, + HTMLDocument5_Release, + HTMLDocument5_GetTypeInfoCount, + HTMLDocument5_GetTypeInfo, + HTMLDocument5_GetIDsOfNames, + HTMLDocument5_Invoke, + HTMLDocument5_put_onmousewheel, + HTMLDocument5_get_onmousewheel, + HTMLDocument5_get_doctype, + HTMLDocument5_get_implementation, + HTMLDocument5_createAttribute, + HTMLDocument5_createComment, + HTMLDocument5_put_onfocusin, + HTMLDocument5_get_onfocusin, + HTMLDocument5_put_onfocusout, + HTMLDocument5_get_onfocusout, + HTMLDocument5_put_onactivate, + HTMLDocument5_get_onactivate, + HTMLDocument5_put_ondeactivate, + HTMLDocument5_get_ondeactivate, + HTMLDocument5_put_onbeforeactivate, + HTMLDocument5_get_onbeforeactivate, + HTMLDocument5_put_onbeforedeactivate, + HTMLDocument5_get_onbeforedeactivate, + HTMLDocument5_get_compatMode +}; + +static inline HTMLDocument *impl_from_IHTMLDocument6(IHTMLDocument6 *iface) +{ + return CONTAINING_RECORD(iface, HTMLDocument, IHTMLDocument6_iface); +} + +static HRESULT WINAPI HTMLDocument6_QueryInterface(IHTMLDocument6 *iface, + REFIID riid, void **ppv) +{ + HTMLDocument *This = impl_from_IHTMLDocument6(iface); + return htmldoc_query_interface(This, riid, ppv); +} + +static ULONG WINAPI HTMLDocument6_AddRef(IHTMLDocument6 *iface) +{ + HTMLDocument *This = impl_from_IHTMLDocument6(iface); + return htmldoc_addref(This); +} + +static ULONG WINAPI HTMLDocument6_Release(IHTMLDocument6 *iface) +{ + HTMLDocument *This = impl_from_IHTMLDocument6(iface); + return htmldoc_release(This); +} + +static HRESULT WINAPI HTMLDocument6_GetTypeInfoCount(IHTMLDocument6 *iface, UINT *pctinfo) +{ + HTMLDocument *This = impl_from_IHTMLDocument6(iface); + return IDispatchEx_GetTypeInfoCount(&This->IDispatchEx_iface, pctinfo); +} + +static HRESULT WINAPI HTMLDocument6_GetTypeInfo(IHTMLDocument6 *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + HTMLDocument *This = impl_from_IHTMLDocument6(iface); + return IDispatchEx_GetTypeInfo(&This->IDispatchEx_iface, iTInfo, lcid, ppTInfo); +} + +static HRESULT WINAPI HTMLDocument6_GetIDsOfNames(IHTMLDocument6 *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + HTMLDocument *This = impl_from_IHTMLDocument6(iface); + return IDispatchEx_GetIDsOfNames(&This->IDispatchEx_iface, riid, rgszNames, cNames, lcid, + rgDispId); +} + +static HRESULT WINAPI HTMLDocument6_Invoke(IHTMLDocument6 *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + HTMLDocument *This = impl_from_IHTMLDocument6(iface); + return IDispatchEx_Invoke(&This->IDispatchEx_iface, dispIdMember, riid, lcid, wFlags, + pDispParams, pVarResult, pExcepInfo, puArgErr); +} + +static HRESULT WINAPI HTMLDocument6_get_compatible(IHTMLDocument6 *iface, + IHTMLDocumentCompatibleInfoCollection **p) +{ + HTMLDocument *This = impl_from_IHTMLDocument6(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument6_get_documentMode(IHTMLDocument6 *iface, + VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument6(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument6_get_onstorage(IHTMLDocument6 *iface, + VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument6(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument6_put_onstorage(IHTMLDocument6 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument6(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument6_get_onstoragecommit(IHTMLDocument6 *iface, + VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument6(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument6_put_onstoragecommit(IHTMLDocument6 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument6(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument6_getElementById(IHTMLDocument6 *iface, + BSTR bstrId, IHTMLElement2 **p) +{ + HTMLDocument *This = impl_from_IHTMLDocument6(iface); + FIXME("(%p)->(%s %p)\n", This, debugstr_w(bstrId), p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument6_updateSettings(IHTMLDocument6 *iface) +{ + HTMLDocument *This = impl_from_IHTMLDocument6(iface); + FIXME("(%p)->()\n", This); + return E_NOTIMPL; +} + +static const IHTMLDocument6Vtbl HTMLDocument6Vtbl = { + HTMLDocument6_QueryInterface, + HTMLDocument6_AddRef, + HTMLDocument6_Release, + HTMLDocument6_GetTypeInfoCount, + HTMLDocument6_GetTypeInfo, + HTMLDocument6_GetIDsOfNames, + HTMLDocument6_Invoke, + HTMLDocument6_get_compatible, + HTMLDocument6_get_documentMode, + HTMLDocument6_put_onstorage, + HTMLDocument6_get_onstorage, + HTMLDocument6_put_onstoragecommit, + HTMLDocument6_get_onstoragecommit, + HTMLDocument6_getElementById, + HTMLDocument6_updateSettings +}; + +static inline HTMLDocument *impl_from_IHTMLDocument7(IHTMLDocument7 *iface) +{ + return CONTAINING_RECORD(iface, HTMLDocument, IHTMLDocument7_iface); +} + +static HRESULT WINAPI HTMLDocument7_QueryInterface(IHTMLDocument7 *iface, REFIID riid, void **ppv) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + return htmldoc_query_interface(This, riid, ppv); +} + +static ULONG WINAPI HTMLDocument7_AddRef(IHTMLDocument7 *iface) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + return htmldoc_addref(This); +} + +static ULONG WINAPI HTMLDocument7_Release(IHTMLDocument7 *iface) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + return htmldoc_release(This); +} + +static HRESULT WINAPI HTMLDocument7_GetTypeInfoCount(IHTMLDocument7 *iface, UINT *pctinfo) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + return IDispatchEx_GetTypeInfoCount(&This->IDispatchEx_iface, pctinfo); +} + +static HRESULT WINAPI HTMLDocument7_GetTypeInfo(IHTMLDocument7 *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + return IDispatchEx_GetTypeInfo(&This->IDispatchEx_iface, iTInfo, lcid, ppTInfo); +} + +static HRESULT WINAPI HTMLDocument7_GetIDsOfNames(IHTMLDocument7 *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + return IDispatchEx_GetIDsOfNames(&This->IDispatchEx_iface, riid, rgszNames, cNames, lcid, + rgDispId); +} + +static HRESULT WINAPI HTMLDocument7_Invoke(IHTMLDocument7 *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + return IDispatchEx_Invoke(&This->IDispatchEx_iface, dispIdMember, riid, lcid, wFlags, + pDispParams, pVarResult, pExcepInfo, puArgErr); +} + +static HRESULT WINAPI HTMLDocument7_get_defaultView(IHTMLDocument7 *iface, IHTMLWindow2 **p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_createCDATASection(IHTMLDocument7 *iface, BSTR text, IHTMLDOMNode **newCDATASectionNode) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, newCDATASectionNode); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_getSelection(IHTMLDocument7 *iface, IHTMLSelection **ppIHTMLSelection) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, ppIHTMLSelection); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_getElementsByTagNameNS(IHTMLDocument7 *iface, VARIANT *pvarNS, + BSTR bstrLocalName, IHTMLElementCollection **pelColl) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s %s %p)\n", This, debugstr_variant(pvarNS), debugstr_w(bstrLocalName), pelColl); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_createElementNS(IHTMLDocument7 *iface, VARIANT *pvarNS, BSTR bstrTag, IHTMLElement **newElem) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s %s %p)\n", This, debugstr_variant(pvarNS), debugstr_w(bstrTag), newElem); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_createAttributeNS(IHTMLDocument7 *iface, VARIANT *pvarNS, + BSTR bstrAttrName, IHTMLDOMAttribute **ppAttribute) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s %s %p)\n", This, debugstr_variant(pvarNS), debugstr_w(bstrAttrName), ppAttribute); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_onmsthumbnailclick(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_onmsthumbnailclick(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_characterSet(IHTMLDocument7 *iface, BSTR *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_createElement(IHTMLDocument7 *iface, BSTR bstrTag, IHTMLElement **newElem) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s %p)\n", This, debugstr_w(bstrTag), newElem); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_createAttribute(IHTMLDocument7 *iface, BSTR bstrAttrName, IHTMLDOMAttribute **ppAttribute) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s %p)\n", This, debugstr_w(bstrAttrName), ppAttribute); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_getElementByClassName(IHTMLDocument7 *iface, BSTR v, IHTMLElementCollection **pel) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s %p)\n", This, debugstr_w(v), pel); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_createProcessingInstruction(IHTMLDocument7 *iface, BSTR target, + BSTR data, IDOMProcessingInstruction **newProcessingInstruction) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s %s %p)\n", This, debugstr_w(target), debugstr_w(data), newProcessingInstruction); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_adoptNode(IHTMLDocument7 *iface, IHTMLDOMNode *pNodeSource, IHTMLDOMNode3 **ppNodeDest) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p %p)\n", This, pNodeSource, ppNodeDest); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_onmssitemodejumplistitemremoved(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_onmssitemodejumplistitemremoved(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_all(IHTMLDocument7 *iface, IHTMLElementCollection **p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_inputEncoding(IHTMLDocument7 *iface, BSTR *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_xmlEncoding(IHTMLDocument7 *iface, BSTR *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_xmlStandalone(IHTMLDocument7 *iface, VARIANT_BOOL v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%x)\n", This, v); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_xmlStandalone(IHTMLDocument7 *iface, VARIANT_BOOL *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_xmlVersion(IHTMLDocument7 *iface, BSTR v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_xmlVersion(IHTMLDocument7 *iface, BSTR *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_hasAttributes(IHTMLDocument7 *iface, VARIANT_BOOL *pfHasAttributes) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, pfHasAttributes); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_onabort(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_onabort(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_onblur(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_onblur(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_oncanplay(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_oncanplay(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_oncanplaythrough(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_oncanplaythrough(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_onchange(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_onchange(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_ondrag(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_ondrag(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_ondragend(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_ondragend(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_ondragenter(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_ondragenter(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_ondragleave(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_ondragleave(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_ondragover(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_ondragover(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_ondrop(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_ondrop(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_ondurationchange(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_ondurationchange(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_onemptied(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_onemptied(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_onended(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_onended(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_onerror(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_onerror(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_onfocus(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_onfocus(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_oninput(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_oninput(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_onload(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_onload(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_onloadeddata(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_onloadeddata(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_onloadedmetadata(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_onloadedmetadata(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_onloadstart(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_onloadstart(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_onpause(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_onpause(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_onplay(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_onplay(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_onplaying(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_onplaying(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_onprogress(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_onprogress(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_onratechange(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_onratechange(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_onreset(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_onreset(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_onscroll(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_onscroll(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_onseekend(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_onseekend(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_onseeking(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_onseeking(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_onselect(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_onselect(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_onstalled(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_onstalled(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_onsubmit(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_onsubmit(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_onsuspend(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_onsuspend(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_ontimeupdate(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_ontimeupdate(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_onvolumechange(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_onvolumechange(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_onwaiting(IHTMLDocument7 *iface, VARIANT v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_onwaiting(IHTMLDocument7 *iface, VARIANT *p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_normalize(IHTMLDocument7 *iface) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_importNode(IHTMLDocument7 *iface, IHTMLDOMNode *pNodeSource, + VARIANT_BOOL fDeep, IHTMLDOMNode3 **ppNodeDest) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p %x %p)\n", This, pNodeSource, fDeep, ppNodeDest); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_parentWindow(IHTMLDocument7 *iface, IHTMLWindow2 **p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_put_body(IHTMLDocument7 *iface, IHTMLElement *v) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, v); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_body(IHTMLDocument7 *iface, IHTMLElement **p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLDocument7_get_head(IHTMLDocument7 *iface, IHTMLElement **p) +{ + HTMLDocument *This = impl_from_IHTMLDocument7(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static const IHTMLDocument7Vtbl HTMLDocument7Vtbl = { + HTMLDocument7_QueryInterface, + HTMLDocument7_AddRef, + HTMLDocument7_Release, + HTMLDocument7_GetTypeInfoCount, + HTMLDocument7_GetTypeInfo, + HTMLDocument7_GetIDsOfNames, + HTMLDocument7_Invoke, + HTMLDocument7_get_defaultView, + HTMLDocument7_createCDATASection, + HTMLDocument7_getSelection, + HTMLDocument7_getElementsByTagNameNS, + HTMLDocument7_createElementNS, + HTMLDocument7_createAttributeNS, + HTMLDocument7_put_onmsthumbnailclick, + HTMLDocument7_get_onmsthumbnailclick, + HTMLDocument7_get_characterSet, + HTMLDocument7_createElement, + HTMLDocument7_createAttribute, + HTMLDocument7_getElementByClassName, + HTMLDocument7_createProcessingInstruction, + HTMLDocument7_adoptNode, + HTMLDocument7_put_onmssitemodejumplistitemremoved, + HTMLDocument7_get_onmssitemodejumplistitemremoved, + HTMLDocument7_get_all, + HTMLDocument7_get_inputEncoding, + HTMLDocument7_get_xmlEncoding, + HTMLDocument7_put_xmlStandalone, + HTMLDocument7_get_xmlStandalone, + HTMLDocument7_put_xmlVersion, + HTMLDocument7_get_xmlVersion, + HTMLDocument7_hasAttributes, + HTMLDocument7_put_onabort, + HTMLDocument7_get_onabort, + HTMLDocument7_put_onblur, + HTMLDocument7_get_onblur, + HTMLDocument7_put_oncanplay, + HTMLDocument7_get_oncanplay, + HTMLDocument7_put_oncanplaythrough, + HTMLDocument7_get_oncanplaythrough, + HTMLDocument7_put_onchange, + HTMLDocument7_get_onchange, + HTMLDocument7_put_ondrag, + HTMLDocument7_get_ondrag, + HTMLDocument7_put_ondragend, + HTMLDocument7_get_ondragend, + HTMLDocument7_put_ondragenter, + HTMLDocument7_get_ondragenter, + HTMLDocument7_put_ondragleave, + HTMLDocument7_get_ondragleave, + HTMLDocument7_put_ondragover, + HTMLDocument7_get_ondragover, + HTMLDocument7_put_ondrop, + HTMLDocument7_get_ondrop, + HTMLDocument7_put_ondurationchange, + HTMLDocument7_get_ondurationchange, + HTMLDocument7_put_onemptied, + HTMLDocument7_get_onemptied, + HTMLDocument7_put_onended, + HTMLDocument7_get_onended, + HTMLDocument7_put_onerror, + HTMLDocument7_get_onerror, + HTMLDocument7_put_onfocus, + HTMLDocument7_get_onfocus, + HTMLDocument7_put_oninput, + HTMLDocument7_get_oninput, + HTMLDocument7_put_onload, + HTMLDocument7_get_onload, + HTMLDocument7_put_onloadeddata, + HTMLDocument7_get_onloadeddata, + HTMLDocument7_put_onloadedmetadata, + HTMLDocument7_get_onloadedmetadata, + HTMLDocument7_put_onloadstart, + HTMLDocument7_get_onloadstart, + HTMLDocument7_put_onpause, + HTMLDocument7_get_onpause, + HTMLDocument7_put_onplay, + HTMLDocument7_get_onplay, + HTMLDocument7_put_onplaying, + HTMLDocument7_get_onplaying, + HTMLDocument7_put_onprogress, + HTMLDocument7_get_onprogress, + HTMLDocument7_put_onratechange, + HTMLDocument7_get_onratechange, + HTMLDocument7_put_onreset, + HTMLDocument7_get_onreset, + HTMLDocument7_put_onscroll, + HTMLDocument7_get_onscroll, + HTMLDocument7_put_onseekend, + HTMLDocument7_get_onseekend, + HTMLDocument7_put_onseeking, + HTMLDocument7_get_onseeking, + HTMLDocument7_put_onselect, + HTMLDocument7_get_onselect, + HTMLDocument7_put_onstalled, + HTMLDocument7_get_onstalled, + HTMLDocument7_put_onsubmit, + HTMLDocument7_get_onsubmit, + HTMLDocument7_put_onsuspend, + HTMLDocument7_get_onsuspend, + HTMLDocument7_put_ontimeupdate, + HTMLDocument7_get_ontimeupdate, + HTMLDocument7_put_onvolumechange, + HTMLDocument7_get_onvolumechange, + HTMLDocument7_put_onwaiting, + HTMLDocument7_get_onwaiting, + HTMLDocument7_normalize, + HTMLDocument7_importNode, + HTMLDocument7_get_parentWindow, + HTMLDocument7_put_body, + HTMLDocument7_get_body, + HTMLDocument7_get_head +}; + static void HTMLDocument_on_advise(IUnknown *iface, cp_static_data_t *cp) { HTMLDocument *This = impl_from_IHTMLDocument2((IHTMLDocument2*)iface); if(This->window) - update_cp_events(This->window->base.inner_window, &This->doc_node->node.event_target, cp, This->doc_node->node.nsnode); + update_cp_events(This->window->base.inner_window, &This->doc_node->node.event_target, cp); } static inline HTMLDocument *impl_from_ISupportErrorInfo(ISupportErrorInfo *iface) @@ -1965,6 +4140,9 @@ static BOOL htmldoc_qi(HTMLDocument *This, REFIID riid, void **ppv) }else if(IsEqualGUID(&IID_IHTMLDocument6, riid)) { TRACE("(%p)->(IID_IHTMLDocument6, %p)\n", This, ppv); *ppv = &This->IHTMLDocument6_iface; + }else if(IsEqualGUID(&IID_IHTMLDocument7, riid)) { + TRACE("(%p)->(IID_IHTMLDocument7, %p)\n", This, ppv); + *ppv = &This->IHTMLDocument7_iface; }else if(IsEqualGUID(&IID_IPersist, riid)) { TRACE("(%p)->(IID_IPersist, %p)\n", This, ppv); *ppv = &This->IPersistFile_iface; @@ -2086,6 +4264,11 @@ static const cpc_entry_t HTMLDocument_cpc[] = { static void init_doc(HTMLDocument *doc, IUnknown *unk_impl, IDispatchEx *dispex) { doc->IHTMLDocument2_iface.lpVtbl = &HTMLDocumentVtbl; + doc->IHTMLDocument3_iface.lpVtbl = &HTMLDocument3Vtbl; + doc->IHTMLDocument4_iface.lpVtbl = &HTMLDocument4Vtbl; + doc->IHTMLDocument5_iface.lpVtbl = &HTMLDocument5Vtbl; + doc->IHTMLDocument6_iface.lpVtbl = &HTMLDocument6Vtbl; + doc->IHTMLDocument7_iface.lpVtbl = &HTMLDocument7Vtbl; doc->IDispatchEx_iface.lpVtbl = &DocDispatchExVtbl; doc->ISupportErrorInfo_iface.lpVtbl = &SupportErrorInfoVtbl; doc->IProvideClassInfo_iface.lpVtbl = &ProvideClassInfoVtbl; @@ -2094,8 +4277,6 @@ static void init_doc(HTMLDocument *doc, IUnknown *unk_impl, IDispatchEx *dispex) doc->dispex = dispex; doc->task_magic = get_task_target_magic(); - HTMLDocument_HTMLDocument3_Init(doc); - HTMLDocument_HTMLDocument5_Init(doc); HTMLDocument_Persist_Init(doc); HTMLDocument_OleCmd_Init(doc); HTMLDocument_OleObj_Init(doc); diff --git a/dll/win32/mshtml/htmldoc3.c b/dll/win32/mshtml/htmldoc3.c deleted file mode 100644 index 01661f7b992..00000000000 --- a/dll/win32/mshtml/htmldoc3.c +++ /dev/null @@ -1,837 +0,0 @@ -/* - * Copyright 2005 Jacek Caban for CodeWeavers - * - * 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 "mshtml_private.h" - -HRESULT get_doc_elem_by_id(HTMLDocumentNode *doc, const WCHAR *id, HTMLElement **ret) -{ - nsIDOMNodeList *nsnode_list; - nsIDOMElement *nselem; - nsIDOMNode *nsnode; - nsAString id_str; - nsresult nsres; - HRESULT hres; - - if(!doc->nsdoc) { - WARN("NULL nsdoc\n"); - return E_UNEXPECTED; - } - - nsAString_InitDepend(&id_str, id); - /* get element by id attribute */ - nsres = nsIDOMHTMLDocument_GetElementById(doc->nsdoc, &id_str, &nselem); - if(FAILED(nsres)) { - ERR("GetElementById failed: %08x\n", nsres); - nsAString_Finish(&id_str); - return E_FAIL; - } - - /* get first element by name attribute */ - nsres = nsIDOMHTMLDocument_GetElementsByName(doc->nsdoc, &id_str, &nsnode_list); - nsAString_Finish(&id_str); - if(FAILED(nsres)) { - ERR("getElementsByName failed: %08x\n", nsres); - if(nselem) - nsIDOMElement_Release(nselem); - return E_FAIL; - } - - nsres = nsIDOMNodeList_Item(nsnode_list, 0, &nsnode); - nsIDOMNodeList_Release(nsnode_list); - assert(nsres == NS_OK); - - if(nsnode && nselem) { - UINT16 pos; - - nsres = nsIDOMNode_CompareDocumentPosition(nsnode, (nsIDOMNode*)nselem, &pos); - if(NS_FAILED(nsres)) { - FIXME("CompareDocumentPosition failed: 0x%08x\n", nsres); - nsIDOMNode_Release(nsnode); - nsIDOMElement_Release(nselem); - return E_FAIL; - } - - TRACE("CompareDocumentPosition gave: 0x%x\n", pos); - if(!(pos & (DOCUMENT_POSITION_PRECEDING | DOCUMENT_POSITION_CONTAINS))) { - nsIDOMElement_Release(nselem); - nselem = NULL; - } - } - - if(nsnode) { - if(!nselem) { - nsres = nsIDOMNode_QueryInterface(nsnode, &IID_nsIDOMElement, (void**)&nselem); - assert(nsres == NS_OK); - } - nsIDOMNode_Release(nsnode); - } - - if(!nselem) { - *ret = NULL; - return S_OK; - } - - hres = get_elem(doc, nselem, ret); - nsIDOMElement_Release(nselem); - return hres; -} - -static inline HTMLDocument *impl_from_IHTMLDocument3(IHTMLDocument3 *iface) -{ - return CONTAINING_RECORD(iface, HTMLDocument, IHTMLDocument3_iface); -} - -static HRESULT WINAPI HTMLDocument3_QueryInterface(IHTMLDocument3 *iface, - REFIID riid, void **ppv) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - return htmldoc_query_interface(This, riid, ppv); -} - -static ULONG WINAPI HTMLDocument3_AddRef(IHTMLDocument3 *iface) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - return htmldoc_addref(This); -} - -static ULONG WINAPI HTMLDocument3_Release(IHTMLDocument3 *iface) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - return htmldoc_release(This); -} - -static HRESULT WINAPI HTMLDocument3_GetTypeInfoCount(IHTMLDocument3 *iface, UINT *pctinfo) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - return IDispatchEx_GetTypeInfoCount(&This->IDispatchEx_iface, pctinfo); -} - -static HRESULT WINAPI HTMLDocument3_GetTypeInfo(IHTMLDocument3 *iface, UINT iTInfo, - LCID lcid, ITypeInfo **ppTInfo) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - return IDispatchEx_GetTypeInfo(&This->IDispatchEx_iface, iTInfo, lcid, ppTInfo); -} - -static HRESULT WINAPI HTMLDocument3_GetIDsOfNames(IHTMLDocument3 *iface, REFIID riid, - LPOLESTR *rgszNames, UINT cNames, - LCID lcid, DISPID *rgDispId) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - return IDispatchEx_GetIDsOfNames(&This->IDispatchEx_iface, riid, rgszNames, cNames, lcid, - rgDispId); -} - -static HRESULT WINAPI HTMLDocument3_Invoke(IHTMLDocument3 *iface, DISPID dispIdMember, - REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, - VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - return IDispatchEx_Invoke(&This->IDispatchEx_iface, dispIdMember, riid, lcid, wFlags, - pDispParams, pVarResult, pExcepInfo, puArgErr); -} - -static HRESULT WINAPI HTMLDocument3_releaseCapture(IHTMLDocument3 *iface) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)\n", This); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_recalc(IHTMLDocument3 *iface, VARIANT_BOOL fForce) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->(%x)\n", This, fForce); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_createTextNode(IHTMLDocument3 *iface, BSTR text, - IHTMLDOMNode **newTextNode) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - nsIDOMText *nstext; - HTMLDOMNode *node; - nsAString text_str; - nsresult nsres; - HRESULT hres; - - TRACE("(%p)->(%s %p)\n", This, debugstr_w(text), newTextNode); - - if(!This->doc_node->nsdoc) { - WARN("NULL nsdoc\n"); - return E_UNEXPECTED; - } - - nsAString_InitDepend(&text_str, text); - nsres = nsIDOMHTMLDocument_CreateTextNode(This->doc_node->nsdoc, &text_str, &nstext); - nsAString_Finish(&text_str); - if(NS_FAILED(nsres)) { - ERR("CreateTextNode failed: %08x\n", nsres); - return E_FAIL; - } - - hres = HTMLDOMTextNode_Create(This->doc_node, (nsIDOMNode*)nstext, &node); - nsIDOMText_Release(nstext); - if(FAILED(hres)) - return hres; - - *newTextNode = &node->IHTMLDOMNode_iface; - return S_OK; -} - -static HRESULT WINAPI HTMLDocument3_get_documentElement(IHTMLDocument3 *iface, IHTMLElement **p) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - nsIDOMElement *nselem = NULL; - HTMLDOMNode *node; - nsresult nsres; - HRESULT hres; - - TRACE("(%p)->(%p)\n", This, p); - - if(This->window->readystate == READYSTATE_UNINITIALIZED) { - *p = NULL; - return S_OK; - } - - if(!This->doc_node->nsdoc) { - WARN("NULL nsdoc\n"); - return E_UNEXPECTED; - } - - nsres = nsIDOMHTMLDocument_GetDocumentElement(This->doc_node->nsdoc, &nselem); - if(NS_FAILED(nsres)) { - ERR("GetDocumentElement failed: %08x\n", nsres); - return E_FAIL; - } - - if(!nselem) { - *p = NULL; - return S_OK; - } - - hres = get_node(This->doc_node, (nsIDOMNode *)nselem, TRUE, &node); - nsIDOMElement_Release(nselem); - if(FAILED(hres)) - return hres; - - hres = IHTMLDOMNode_QueryInterface(&node->IHTMLDOMNode_iface, &IID_IHTMLElement, (void**)p); - node_release(node); - return hres; -} - -static HRESULT WINAPI HTMLDocument3_uniqueID(IHTMLDocument3 *iface, BSTR *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_attachEvent(IHTMLDocument3 *iface, BSTR event, - IDispatch* pDisp, VARIANT_BOOL *pfResult) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - - TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(event), pDisp, pfResult); - - return attach_event(&This->doc_node->node.event_target, This->doc_node->node.nsnode, This, event, pDisp, pfResult); -} - -static HRESULT WINAPI HTMLDocument3_detachEvent(IHTMLDocument3 *iface, BSTR event, - IDispatch *pDisp) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - - TRACE("(%p)->(%s %p)\n", This, debugstr_w(event), pDisp); - - return detach_event(This->doc_node->node.event_target, This, event, pDisp); -} - -static HRESULT WINAPI HTMLDocument3_put_onrowsdelete(IHTMLDocument3 *iface, VARIANT v) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->()\n", This); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_get_onrowsdelete(IHTMLDocument3 *iface, VARIANT *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_put_onrowsinserted(IHTMLDocument3 *iface, VARIANT v) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->()\n", This); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_get_onrowsinserted(IHTMLDocument3 *iface, VARIANT *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_put_oncellchange(IHTMLDocument3 *iface, VARIANT v) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->()\n", This); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_get_oncellchange(IHTMLDocument3 *iface, VARIANT *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_put_ondatasetchanged(IHTMLDocument3 *iface, VARIANT v) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->()\n", This); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_get_ondatasetchanged(IHTMLDocument3 *iface, VARIANT *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_put_ondataavailable(IHTMLDocument3 *iface, VARIANT v) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->()\n", This); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_get_ondataavailable(IHTMLDocument3 *iface, VARIANT *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_put_ondatasetcomplete(IHTMLDocument3 *iface, VARIANT v) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->()\n", This); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_get_ondatasetcomplete(IHTMLDocument3 *iface, VARIANT *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_put_onpropertychange(IHTMLDocument3 *iface, VARIANT v) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->()\n", This); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_get_onpropertychange(IHTMLDocument3 *iface, VARIANT *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_put_dir(IHTMLDocument3 *iface, BSTR v) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_get_dir(IHTMLDocument3 *iface, BSTR *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_put_oncontextmenu(IHTMLDocument3 *iface, VARIANT v) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - - TRACE("(%p)->()\n", This); - - return set_doc_event(This, EVENTID_CONTEXTMENU, &v); -} - -static HRESULT WINAPI HTMLDocument3_get_oncontextmenu(IHTMLDocument3 *iface, VARIANT *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - - TRACE("(%p)->(%p)\n", This, p); - - return get_doc_event(This, EVENTID_CONTEXTMENU, p); -} - -static HRESULT WINAPI HTMLDocument3_put_onstop(IHTMLDocument3 *iface, VARIANT v) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->()\n", This); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_get_onstop(IHTMLDocument3 *iface, VARIANT *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_createDocumentFragment(IHTMLDocument3 *iface, - IHTMLDocument2 **ppNewDoc) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - nsIDOMDocumentFragment *doc_frag; - HTMLDocumentNode *docnode; - nsresult nsres; - HRESULT hres; - - TRACE("(%p)->(%p)\n", This, ppNewDoc); - - if(!This->doc_node->nsdoc) { - FIXME("NULL nsdoc\n"); - return E_NOTIMPL; - } - - nsres = nsIDOMHTMLDocument_CreateDocumentFragment(This->doc_node->nsdoc, &doc_frag); - if(NS_FAILED(nsres)) { - ERR("CreateDocumentFragment failed: %08x\n", nsres); - return E_FAIL; - } - - hres = create_document_fragment((nsIDOMNode*)doc_frag, This->doc_node, &docnode); - nsIDOMDocumentFragment_Release(doc_frag); - if(FAILED(hres)) - return hres; - - *ppNewDoc = &docnode->basedoc.IHTMLDocument2_iface; - return S_OK; -} - -static HRESULT WINAPI HTMLDocument3_get_parentDocument(IHTMLDocument3 *iface, - IHTMLDocument2 **p) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_put_enableDownload(IHTMLDocument3 *iface, - VARIANT_BOOL v) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->(%x)\n", This, v); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_get_enableDownload(IHTMLDocument3 *iface, - VARIANT_BOOL *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_put_baseUrl(IHTMLDocument3 *iface, BSTR v) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_get_baseUrl(IHTMLDocument3 *iface, BSTR *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_get_childNodes(IHTMLDocument3 *iface, IDispatch **p) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - - TRACE("(%p)->(%p)\n", This, p); - - return IHTMLDOMNode_get_childNodes(&This->doc_node->node.IHTMLDOMNode_iface, p); -} - -static HRESULT WINAPI HTMLDocument3_put_inheritStyleSheets(IHTMLDocument3 *iface, - VARIANT_BOOL v) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->()\n", This); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_get_inheritStyleSheets(IHTMLDocument3 *iface, - VARIANT_BOOL *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_put_onbeforeeditfocus(IHTMLDocument3 *iface, VARIANT v) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->()\n", This); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_get_onbeforeeditfocus(IHTMLDocument3 *iface, VARIANT *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument3_getElementsByName(IHTMLDocument3 *iface, BSTR v, - IHTMLElementCollection **ppelColl) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - FIXME("(%p)->(%s %p)\n", This, debugstr_w(v), ppelColl); - return E_NOTIMPL; -} - - -static HRESULT WINAPI HTMLDocument3_getElementById(IHTMLDocument3 *iface, BSTR v, - IHTMLElement **pel) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - HTMLElement *elem; - HRESULT hres; - - TRACE("(%p)->(%s %p)\n", This, debugstr_w(v), pel); - - hres = get_doc_elem_by_id(This->doc_node, v, &elem); - if(FAILED(hres) || !elem) { - *pel = NULL; - return hres; - } - - *pel = &elem->IHTMLElement_iface; - return S_OK; -} - - -static HRESULT WINAPI HTMLDocument3_getElementsByTagName(IHTMLDocument3 *iface, BSTR v, - IHTMLElementCollection **pelColl) -{ - HTMLDocument *This = impl_from_IHTMLDocument3(iface); - nsIDOMNodeList *nslist; - nsAString id_str; - nsresult nsres; - - TRACE("(%p)->(%s %p)\n", This, debugstr_w(v), pelColl); - - if(!This->doc_node->nsdoc) { - WARN("NULL nsdoc\n"); - return E_UNEXPECTED; - } - - nsAString_InitDepend(&id_str, v); - nsres = nsIDOMHTMLDocument_GetElementsByTagName(This->doc_node->nsdoc, &id_str, &nslist); - nsAString_Finish(&id_str); - if(FAILED(nsres)) { - ERR("GetElementByName failed: %08x\n", nsres); - return E_FAIL; - } - - *pelColl = create_collection_from_nodelist(This->doc_node, nslist); - nsIDOMNodeList_Release(nslist); - - return S_OK; -} - -static const IHTMLDocument3Vtbl HTMLDocument3Vtbl = { - HTMLDocument3_QueryInterface, - HTMLDocument3_AddRef, - HTMLDocument3_Release, - HTMLDocument3_GetTypeInfoCount, - HTMLDocument3_GetTypeInfo, - HTMLDocument3_GetIDsOfNames, - HTMLDocument3_Invoke, - HTMLDocument3_releaseCapture, - HTMLDocument3_recalc, - HTMLDocument3_createTextNode, - HTMLDocument3_get_documentElement, - HTMLDocument3_uniqueID, - HTMLDocument3_attachEvent, - HTMLDocument3_detachEvent, - HTMLDocument3_put_onrowsdelete, - HTMLDocument3_get_onrowsdelete, - HTMLDocument3_put_onrowsinserted, - HTMLDocument3_get_onrowsinserted, - HTMLDocument3_put_oncellchange, - HTMLDocument3_get_oncellchange, - HTMLDocument3_put_ondatasetchanged, - HTMLDocument3_get_ondatasetchanged, - HTMLDocument3_put_ondataavailable, - HTMLDocument3_get_ondataavailable, - HTMLDocument3_put_ondatasetcomplete, - HTMLDocument3_get_ondatasetcomplete, - HTMLDocument3_put_onpropertychange, - HTMLDocument3_get_onpropertychange, - HTMLDocument3_put_dir, - HTMLDocument3_get_dir, - HTMLDocument3_put_oncontextmenu, - HTMLDocument3_get_oncontextmenu, - HTMLDocument3_put_onstop, - HTMLDocument3_get_onstop, - HTMLDocument3_createDocumentFragment, - HTMLDocument3_get_parentDocument, - HTMLDocument3_put_enableDownload, - HTMLDocument3_get_enableDownload, - HTMLDocument3_put_baseUrl, - HTMLDocument3_get_baseUrl, - HTMLDocument3_get_childNodes, - HTMLDocument3_put_inheritStyleSheets, - HTMLDocument3_get_inheritStyleSheets, - HTMLDocument3_put_onbeforeeditfocus, - HTMLDocument3_get_onbeforeeditfocus, - HTMLDocument3_getElementsByName, - HTMLDocument3_getElementById, - HTMLDocument3_getElementsByTagName -}; - -static inline HTMLDocument *impl_from_IHTMLDocument4(IHTMLDocument4 *iface) -{ - return CONTAINING_RECORD(iface, HTMLDocument, IHTMLDocument4_iface); -} - -static HRESULT WINAPI HTMLDocument4_QueryInterface(IHTMLDocument4 *iface, - REFIID riid, void **ppv) -{ - HTMLDocument *This = impl_from_IHTMLDocument4(iface); - return htmldoc_query_interface(This, riid, ppv); -} - -static ULONG WINAPI HTMLDocument4_AddRef(IHTMLDocument4 *iface) -{ - HTMLDocument *This = impl_from_IHTMLDocument4(iface); - return htmldoc_addref(This); -} - -static ULONG WINAPI HTMLDocument4_Release(IHTMLDocument4 *iface) -{ - HTMLDocument *This = impl_from_IHTMLDocument4(iface); - return htmldoc_release(This); -} - -static HRESULT WINAPI HTMLDocument4_GetTypeInfoCount(IHTMLDocument4 *iface, UINT *pctinfo) -{ - HTMLDocument *This = impl_from_IHTMLDocument4(iface); - return IDispatchEx_GetTypeInfoCount(&This->IDispatchEx_iface, pctinfo); -} - -static HRESULT WINAPI HTMLDocument4_GetTypeInfo(IHTMLDocument4 *iface, UINT iTInfo, - LCID lcid, ITypeInfo **ppTInfo) -{ - HTMLDocument *This = impl_from_IHTMLDocument4(iface); - return IDispatchEx_GetTypeInfo(&This->IDispatchEx_iface, iTInfo, lcid, ppTInfo); -} - -static HRESULT WINAPI HTMLDocument4_GetIDsOfNames(IHTMLDocument4 *iface, REFIID riid, - LPOLESTR *rgszNames, UINT cNames, - LCID lcid, DISPID *rgDispId) -{ - HTMLDocument *This = impl_from_IHTMLDocument4(iface); - return IDispatchEx_GetIDsOfNames(&This->IDispatchEx_iface, riid, rgszNames, cNames, lcid, - rgDispId); -} - -static HRESULT WINAPI HTMLDocument4_Invoke(IHTMLDocument4 *iface, DISPID dispIdMember, - REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, - VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) -{ - HTMLDocument *This = impl_from_IHTMLDocument4(iface); - return IDispatchEx_Invoke(&This->IDispatchEx_iface, dispIdMember, riid, lcid, wFlags, - pDispParams, pVarResult, pExcepInfo, puArgErr); -} - -static HRESULT WINAPI HTMLDocument4_focus(IHTMLDocument4 *iface) -{ - HTMLDocument *This = impl_from_IHTMLDocument4(iface); - nsIDOMHTMLElement *nsbody; - nsresult nsres; - - TRACE("(%p)->()\n", This); - - nsres = nsIDOMHTMLDocument_GetBody(This->doc_node->nsdoc, &nsbody); - if(NS_FAILED(nsres) || !nsbody) { - ERR("GetBody failed: %08x\n", nsres); - return E_FAIL; - } - - nsres = nsIDOMHTMLElement_Focus(nsbody); - nsIDOMHTMLElement_Release(nsbody); - if(NS_FAILED(nsres)) { - ERR("Focus failed: %08x\n", nsres); - return E_FAIL; - } - - return S_OK; -} - -static HRESULT WINAPI HTMLDocument4_hasFocus(IHTMLDocument4 *iface, VARIANT_BOOL *pfFocus) -{ - HTMLDocument *This = impl_from_IHTMLDocument4(iface); - FIXME("(%p)->(%p)\n", This, pfFocus); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument4_put_onselectionchange(IHTMLDocument4 *iface, VARIANT v) -{ - HTMLDocument *This = impl_from_IHTMLDocument4(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument4_get_onselectionchange(IHTMLDocument4 *iface, VARIANT *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument4(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument4_get_namespace(IHTMLDocument4 *iface, IDispatch **p) -{ - HTMLDocument *This = impl_from_IHTMLDocument4(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument4_createDocumentFromUrl(IHTMLDocument4 *iface, BSTR bstrUrl, - BSTR bstrOptions, IHTMLDocument2 **newDoc) -{ - HTMLDocument *This = impl_from_IHTMLDocument4(iface); - FIXME("(%p)->(%s %s %p)\n", This, debugstr_w(bstrUrl), debugstr_w(bstrOptions), newDoc); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument4_put_media(IHTMLDocument4 *iface, BSTR v) -{ - HTMLDocument *This = impl_from_IHTMLDocument4(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument4_get_media(IHTMLDocument4 *iface, BSTR *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument4(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument4_createEventObject(IHTMLDocument4 *iface, - VARIANT *pvarEventObject, IHTMLEventObj **ppEventObj) -{ - HTMLDocument *This = impl_from_IHTMLDocument4(iface); - - TRACE("(%p)->(%s %p)\n", This, debugstr_variant(pvarEventObject), ppEventObj); - - if(pvarEventObject && V_VT(pvarEventObject) != VT_ERROR && V_VT(pvarEventObject) != VT_EMPTY) { - FIXME("unsupported pvarEventObject %s\n", debugstr_variant(pvarEventObject)); - return E_NOTIMPL; - } - - return create_event_obj(ppEventObj); -} - -static HRESULT WINAPI HTMLDocument4_fireEvent(IHTMLDocument4 *iface, BSTR bstrEventName, - VARIANT *pvarEventObject, VARIANT_BOOL *pfCanceled) -{ - HTMLDocument *This = impl_from_IHTMLDocument4(iface); - - TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(bstrEventName), pvarEventObject, pfCanceled); - - return dispatch_event(&This->doc_node->node, bstrEventName, pvarEventObject, pfCanceled); -} - -static HRESULT WINAPI HTMLDocument4_createRenderStyle(IHTMLDocument4 *iface, BSTR v, - IHTMLRenderStyle **ppIHTMLRenderStyle) -{ - HTMLDocument *This = impl_from_IHTMLDocument4(iface); - FIXME("(%p)->(%s %p)\n", This, debugstr_w(v), ppIHTMLRenderStyle); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument4_put_oncontrolselect(IHTMLDocument4 *iface, VARIANT v) -{ - HTMLDocument *This = impl_from_IHTMLDocument4(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument4_get_oncontrolselect(IHTMLDocument4 *iface, VARIANT *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument4(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument4_get_URLEncoded(IHTMLDocument4 *iface, BSTR *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument4(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static const IHTMLDocument4Vtbl HTMLDocument4Vtbl = { - HTMLDocument4_QueryInterface, - HTMLDocument4_AddRef, - HTMLDocument4_Release, - HTMLDocument4_GetTypeInfoCount, - HTMLDocument4_GetTypeInfo, - HTMLDocument4_GetIDsOfNames, - HTMLDocument4_Invoke, - HTMLDocument4_focus, - HTMLDocument4_hasFocus, - HTMLDocument4_put_onselectionchange, - HTMLDocument4_get_onselectionchange, - HTMLDocument4_get_namespace, - HTMLDocument4_createDocumentFromUrl, - HTMLDocument4_put_media, - HTMLDocument4_get_media, - HTMLDocument4_createEventObject, - HTMLDocument4_fireEvent, - HTMLDocument4_createRenderStyle, - HTMLDocument4_put_oncontrolselect, - HTMLDocument4_get_oncontrolselect, - HTMLDocument4_get_URLEncoded -}; - -void HTMLDocument_HTMLDocument3_Init(HTMLDocument *This) -{ - This->IHTMLDocument3_iface.lpVtbl = &HTMLDocument3Vtbl; - This->IHTMLDocument4_iface.lpVtbl = &HTMLDocument4Vtbl; -} diff --git a/dll/win32/mshtml/htmldoc5.c b/dll/win32/mshtml/htmldoc5.c deleted file mode 100644 index 71b8cb87497..00000000000 --- a/dll/win32/mshtml/htmldoc5.c +++ /dev/null @@ -1,427 +0,0 @@ -/* - * Copyright 2007 Jacek Caban for CodeWeavers - * - * 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 "mshtml_private.h" - -static inline HTMLDocument *impl_from_IHTMLDocument5(IHTMLDocument5 *iface) -{ - return CONTAINING_RECORD(iface, HTMLDocument, IHTMLDocument5_iface); -} - -static HRESULT WINAPI HTMLDocument5_QueryInterface(IHTMLDocument5 *iface, - REFIID riid, void **ppv) -{ - HTMLDocument *This = impl_from_IHTMLDocument5(iface); - return htmldoc_query_interface(This, riid, ppv); -} - -static ULONG WINAPI HTMLDocument5_AddRef(IHTMLDocument5 *iface) -{ - HTMLDocument *This = impl_from_IHTMLDocument5(iface); - return htmldoc_addref(This); -} - -static ULONG WINAPI HTMLDocument5_Release(IHTMLDocument5 *iface) -{ - HTMLDocument *This = impl_from_IHTMLDocument5(iface); - return htmldoc_release(This); -} - -static HRESULT WINAPI HTMLDocument5_GetTypeInfoCount(IHTMLDocument5 *iface, UINT *pctinfo) -{ - HTMLDocument *This = impl_from_IHTMLDocument5(iface); - return IDispatchEx_GetTypeInfoCount(&This->IDispatchEx_iface, pctinfo); -} - -static HRESULT WINAPI HTMLDocument5_GetTypeInfo(IHTMLDocument5 *iface, UINT iTInfo, - LCID lcid, ITypeInfo **ppTInfo) -{ - HTMLDocument *This = impl_from_IHTMLDocument5(iface); - return IDispatchEx_GetTypeInfo(&This->IDispatchEx_iface, iTInfo, lcid, ppTInfo); -} - -static HRESULT WINAPI HTMLDocument5_GetIDsOfNames(IHTMLDocument5 *iface, REFIID riid, - LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) -{ - HTMLDocument *This = impl_from_IHTMLDocument5(iface); - return IDispatchEx_GetIDsOfNames(&This->IDispatchEx_iface, riid, rgszNames, cNames, lcid, - rgDispId); -} - -static HRESULT WINAPI HTMLDocument5_Invoke(IHTMLDocument5 *iface, DISPID dispIdMember, - REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, - VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) -{ - HTMLDocument *This = impl_from_IHTMLDocument5(iface); - return IDispatchEx_Invoke(&This->IDispatchEx_iface, dispIdMember, riid, lcid, wFlags, - pDispParams, pVarResult, pExcepInfo, puArgErr); -} - -static HRESULT WINAPI HTMLDocument5_put_onmousewheel(IHTMLDocument5 *iface, VARIANT v) -{ - HTMLDocument *This = impl_from_IHTMLDocument5(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument5_get_onmousewheel(IHTMLDocument5 *iface, VARIANT *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument5(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument5_get_doctype(IHTMLDocument5 *iface, IHTMLDOMNode **p) -{ - HTMLDocument *This = impl_from_IHTMLDocument5(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument5_get_implementation(IHTMLDocument5 *iface, IHTMLDOMImplementation **p) -{ - HTMLDocument *This = impl_from_IHTMLDocument5(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument5_createAttribute(IHTMLDocument5 *iface, BSTR bstrattrName, - IHTMLDOMAttribute **ppattribute) -{ - HTMLDocument *This = impl_from_IHTMLDocument5(iface); - HTMLDOMAttribute *attr; - HRESULT hres; - - TRACE("(%p)->(%s %p)\n", This, debugstr_w(bstrattrName), ppattribute); - - hres = HTMLDOMAttribute_Create(bstrattrName, NULL, 0, &attr); - if(FAILED(hres)) - return hres; - - *ppattribute = &attr->IHTMLDOMAttribute_iface; - return S_OK; -} - -static HRESULT WINAPI HTMLDocument5_createComment(IHTMLDocument5 *iface, BSTR bstrdata, - IHTMLDOMNode **ppRetNode) -{ - HTMLDocument *This = impl_from_IHTMLDocument5(iface); - nsIDOMComment *nscomment; - HTMLElement *elem; - nsAString str; - nsresult nsres; - HRESULT hres; - - TRACE("(%p)->(%s %p)\n", This, debugstr_w(bstrdata), ppRetNode); - - if(!This->doc_node->nsdoc) { - WARN("NULL nsdoc\n"); - return E_UNEXPECTED; - } - - nsAString_InitDepend(&str, bstrdata); - nsres = nsIDOMHTMLDocument_CreateComment(This->doc_node->nsdoc, &str, &nscomment); - nsAString_Finish(&str); - if(NS_FAILED(nsres)) { - ERR("CreateTextNode failed: %08x\n", nsres); - return E_FAIL; - } - - hres = HTMLCommentElement_Create(This->doc_node, (nsIDOMNode*)nscomment, &elem); - nsIDOMComment_Release(nscomment); - if(FAILED(hres)) - return hres; - - *ppRetNode = &elem->node.IHTMLDOMNode_iface; - return S_OK; -} - -static HRESULT WINAPI HTMLDocument5_put_onfocusin(IHTMLDocument5 *iface, VARIANT v) -{ - HTMLDocument *This = impl_from_IHTMLDocument5(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument5_get_onfocusin(IHTMLDocument5 *iface, VARIANT *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument5(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument5_put_onfocusout(IHTMLDocument5 *iface, VARIANT v) -{ - HTMLDocument *This = impl_from_IHTMLDocument5(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument5_get_onfocusout(IHTMLDocument5 *iface, VARIANT *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument5(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument5_put_onactivate(IHTMLDocument5 *iface, VARIANT v) -{ - HTMLDocument *This = impl_from_IHTMLDocument5(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument5_get_onactivate(IHTMLDocument5 *iface, VARIANT *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument5(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument5_put_ondeactivate(IHTMLDocument5 *iface, VARIANT v) -{ - HTMLDocument *This = impl_from_IHTMLDocument5(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument5_get_ondeactivate(IHTMLDocument5 *iface, VARIANT *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument5(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument5_put_onbeforeactivate(IHTMLDocument5 *iface, VARIANT v) -{ - HTMLDocument *This = impl_from_IHTMLDocument5(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument5_get_onbeforeactivate(IHTMLDocument5 *iface, VARIANT *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument5(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument5_put_onbeforedeactivate(IHTMLDocument5 *iface, VARIANT v) -{ - HTMLDocument *This = impl_from_IHTMLDocument5(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument5_get_onbeforedeactivate(IHTMLDocument5 *iface, VARIANT *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument5(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument5_get_compatMode(IHTMLDocument5 *iface, BSTR *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument5(iface); - nsAString mode_str; - const PRUnichar *mode; - - TRACE("(%p)->(%p)\n", This, p); - - if(!This->doc_node->nsdoc) { - WARN("NULL nsdoc\n"); - return E_UNEXPECTED; - } - - nsAString_Init(&mode_str, NULL); - nsIDOMHTMLDocument_GetCompatMode(This->doc_node->nsdoc, &mode_str); - - nsAString_GetData(&mode_str, &mode); - *p = SysAllocString(mode); - nsAString_Finish(&mode_str); - - return S_OK; -} - -static const IHTMLDocument5Vtbl HTMLDocument5Vtbl = { - HTMLDocument5_QueryInterface, - HTMLDocument5_AddRef, - HTMLDocument5_Release, - HTMLDocument5_GetTypeInfoCount, - HTMLDocument5_GetTypeInfo, - HTMLDocument5_GetIDsOfNames, - HTMLDocument5_Invoke, - HTMLDocument5_put_onmousewheel, - HTMLDocument5_get_onmousewheel, - HTMLDocument5_get_doctype, - HTMLDocument5_get_implementation, - HTMLDocument5_createAttribute, - HTMLDocument5_createComment, - HTMLDocument5_put_onfocusin, - HTMLDocument5_get_onfocusin, - HTMLDocument5_put_onfocusout, - HTMLDocument5_get_onfocusout, - HTMLDocument5_put_onactivate, - HTMLDocument5_get_onactivate, - HTMLDocument5_put_ondeactivate, - HTMLDocument5_get_ondeactivate, - HTMLDocument5_put_onbeforeactivate, - HTMLDocument5_get_onbeforeactivate, - HTMLDocument5_put_onbeforedeactivate, - HTMLDocument5_get_onbeforedeactivate, - HTMLDocument5_get_compatMode -}; - -static inline HTMLDocument *impl_from_IHTMLDocument6(IHTMLDocument6 *iface) -{ - return CONTAINING_RECORD(iface, HTMLDocument, IHTMLDocument6_iface); -} - -static HRESULT WINAPI HTMLDocument6_QueryInterface(IHTMLDocument6 *iface, - REFIID riid, void **ppv) -{ - HTMLDocument *This = impl_from_IHTMLDocument6(iface); - return htmldoc_query_interface(This, riid, ppv); -} - -static ULONG WINAPI HTMLDocument6_AddRef(IHTMLDocument6 *iface) -{ - HTMLDocument *This = impl_from_IHTMLDocument6(iface); - return htmldoc_addref(This); -} - -static ULONG WINAPI HTMLDocument6_Release(IHTMLDocument6 *iface) -{ - HTMLDocument *This = impl_from_IHTMLDocument6(iface); - return htmldoc_release(This); -} - -static HRESULT WINAPI HTMLDocument6_GetTypeInfoCount(IHTMLDocument6 *iface, UINT *pctinfo) -{ - HTMLDocument *This = impl_from_IHTMLDocument6(iface); - return IDispatchEx_GetTypeInfoCount(&This->IDispatchEx_iface, pctinfo); -} - -static HRESULT WINAPI HTMLDocument6_GetTypeInfo(IHTMLDocument6 *iface, UINT iTInfo, - LCID lcid, ITypeInfo **ppTInfo) -{ - HTMLDocument *This = impl_from_IHTMLDocument6(iface); - return IDispatchEx_GetTypeInfo(&This->IDispatchEx_iface, iTInfo, lcid, ppTInfo); -} - -static HRESULT WINAPI HTMLDocument6_GetIDsOfNames(IHTMLDocument6 *iface, REFIID riid, - LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) -{ - HTMLDocument *This = impl_from_IHTMLDocument6(iface); - return IDispatchEx_GetIDsOfNames(&This->IDispatchEx_iface, riid, rgszNames, cNames, lcid, - rgDispId); -} - -static HRESULT WINAPI HTMLDocument6_Invoke(IHTMLDocument6 *iface, DISPID dispIdMember, - REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, - VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) -{ - HTMLDocument *This = impl_from_IHTMLDocument6(iface); - return IDispatchEx_Invoke(&This->IDispatchEx_iface, dispIdMember, riid, lcid, wFlags, - pDispParams, pVarResult, pExcepInfo, puArgErr); -} - -static HRESULT WINAPI HTMLDocument6_get_compatible(IHTMLDocument6 *iface, - IHTMLDocumentCompatibleInfoCollection **p) -{ - HTMLDocument *This = impl_from_IHTMLDocument6(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument6_get_documentMode(IHTMLDocument6 *iface, - VARIANT *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument6(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument6_get_onstorage(IHTMLDocument6 *iface, - VARIANT *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument6(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument6_put_onstorage(IHTMLDocument6 *iface, VARIANT v) -{ - HTMLDocument *This = impl_from_IHTMLDocument6(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument6_get_onstoragecommit(IHTMLDocument6 *iface, - VARIANT *p) -{ - HTMLDocument *This = impl_from_IHTMLDocument6(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument6_put_onstoragecommit(IHTMLDocument6 *iface, VARIANT v) -{ - HTMLDocument *This = impl_from_IHTMLDocument6(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument6_getElementById(IHTMLDocument6 *iface, - BSTR bstrId, IHTMLElement2 **p) -{ - HTMLDocument *This = impl_from_IHTMLDocument6(iface); - FIXME("(%p)->(%s %p)\n", This, debugstr_w(bstrId), p); - return E_NOTIMPL; -} - -static HRESULT WINAPI HTMLDocument6_updateSettings(IHTMLDocument6 *iface) -{ - HTMLDocument *This = impl_from_IHTMLDocument6(iface); - FIXME("(%p)->()\n", This); - return E_NOTIMPL; -} - -static const IHTMLDocument6Vtbl HTMLDocument6Vtbl = { - HTMLDocument6_QueryInterface, - HTMLDocument6_AddRef, - HTMLDocument6_Release, - HTMLDocument6_GetTypeInfoCount, - HTMLDocument6_GetTypeInfo, - HTMLDocument6_GetIDsOfNames, - HTMLDocument6_Invoke, - HTMLDocument6_get_compatible, - HTMLDocument6_get_documentMode, - HTMLDocument6_put_onstorage, - HTMLDocument6_get_onstorage, - HTMLDocument6_put_onstoragecommit, - HTMLDocument6_get_onstoragecommit, - HTMLDocument6_getElementById, - HTMLDocument6_updateSettings -}; - -void HTMLDocument_HTMLDocument5_Init(HTMLDocument *This) -{ - This->IHTMLDocument5_iface.lpVtbl = &HTMLDocument5Vtbl; - This->IHTMLDocument6_iface.lpVtbl = &HTMLDocument6Vtbl; -} diff --git a/dll/win32/mshtml/htmlelem.c b/dll/win32/mshtml/htmlelem.c index f0287d2ab75..88b5ebfee7c 100644 --- a/dll/win32/mshtml/htmlelem.c +++ b/dll/win32/mshtml/htmlelem.c @@ -1710,8 +1710,8 @@ static HRESULT HTMLElement_invoke(DispatchEx *dispex, DISPID id, LCID lcid, static HRESULT HTMLElement_populate_props(DispatchEx *dispex) { HTMLElement *This = impl_from_DispatchEx(dispex); - nsIDOMNamedNodeMap *attrs; - nsIDOMNode *node; + nsIDOMMozNamedAttrMap *attrs; + nsIDOMAttr *attr; nsAString nsstr; const PRUnichar *str; BSTR name; @@ -1729,40 +1729,40 @@ static HRESULT HTMLElement_populate_props(DispatchEx *dispex) if(NS_FAILED(nsres)) return E_FAIL; - nsres = nsIDOMNamedNodeMap_GetLength(attrs, &len); + nsres = nsIDOMMozNamedAttrMap_GetLength(attrs, &len); if(NS_FAILED(nsres)) { - nsIDOMNamedNodeMap_Release(attrs); + nsIDOMMozNamedAttrMap_Release(attrs); return E_FAIL; } nsAString_Init(&nsstr, NULL); for(i=0; iIDispatchEx_iface, name, fdexNameCaseInsensitive, &id); if(hres != DISP_E_UNKNOWNNAME) { - nsIDOMNode_Release(node); + nsIDOMAttr_Release(attr); SysFreeString(name); continue; } - nsres = nsIDOMNode_GetNodeValue(node, &nsstr); - nsIDOMNode_Release(node); + nsres = nsIDOMAttr_GetNodeValue(attr, &nsstr); + nsIDOMAttr_Release(attr); if(NS_FAILED(nsres)) { SysFreeString(name); continue; @@ -1785,7 +1785,7 @@ static HRESULT HTMLElement_populate_props(DispatchEx *dispex) } nsAString_Finish(&nsstr); - nsIDOMNamedNodeMap_Release(attrs); + nsIDOMMozNamedAttrMap_Release(attrs); return S_OK; } diff --git a/dll/win32/mshtml/htmlelem2.c b/dll/win32/mshtml/htmlelem2.c index cd5f3d44b87..b2cf30f209d 100644 --- a/dll/win32/mshtml/htmlelem2.c +++ b/dll/win32/mshtml/htmlelem2.c @@ -847,7 +847,7 @@ static HRESULT WINAPI HTMLElement2_attachEvent(IHTMLElement2 *iface, BSTR event, TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(event), pDisp, pfResult); - return attach_event(get_node_event_target(&This->node), This->node.nsnode, &This->node.doc->basedoc, event, pDisp, pfResult); + return attach_event(get_node_event_target(&This->node), &This->node.doc->basedoc, event, pDisp, pfResult); } static HRESULT WINAPI HTMLElement2_detachEvent(IHTMLElement2 *iface, BSTR event, IDispatch *pDisp) diff --git a/dll/win32/mshtml/htmlevent.c b/dll/win32/mshtml/htmlevent.c index 4ed833b3c69..b6278cd3a0f 100644 --- a/dll/win32/mshtml/htmlevent.c +++ b/dll/win32/mshtml/htmlevent.c @@ -25,7 +25,6 @@ typedef struct { } handler_vector_t; struct event_target_t { - DWORD node_handlers_mask; handler_vector_t *event_table[EVENTID_LAST]; }; @@ -142,13 +141,13 @@ typedef struct { #define EVENT_DEFAULTLISTENER 0x0001 #define EVENT_BUBBLE 0x0002 #define EVENT_FORWARDBODY 0x0004 -#define EVENT_NODEHANDLER 0x0008 +#define EVENT_BIND_TO_BODY 0x0008 #define EVENT_CANCELABLE 0x0010 #define EVENT_HASDEFAULTHANDLERS 0x0020 static const event_info_t event_info[] = { {abortW, onabortW, EVENTT_NONE, DISPID_EVMETH_ONABORT, - EVENT_NODEHANDLER}, + EVENT_BIND_TO_BODY}, {beforeunloadW, onbeforeunloadW, EVENTT_NONE, DISPID_EVMETH_ONBEFOREUNLOAD, EVENT_DEFAULTLISTENER|EVENT_FORWARDBODY}, {blurW, onblurW, EVENTT_HTML, DISPID_EVMETH_ONBLUR, @@ -168,7 +167,7 @@ static const event_info_t event_info[] = { {dragstartW, ondragstartW, EVENTT_MOUSE, DISPID_EVMETH_ONDRAGSTART, EVENT_CANCELABLE}, {errorW, onerrorW, EVENTT_NONE, DISPID_EVMETH_ONERROR, - EVENT_NODEHANDLER}, + EVENT_BIND_TO_BODY}, {focusW, onfocusW, EVENTT_HTML, DISPID_EVMETH_ONFOCUS, EVENT_DEFAULTLISTENER}, {helpW, onhelpW, EVENTT_KEY, DISPID_EVMETH_ONHELP, @@ -180,7 +179,7 @@ static const event_info_t event_info[] = { {keyupW, onkeyupW, EVENTT_KEY, DISPID_EVMETH_ONKEYUP, EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, {loadW, onloadW, EVENTT_HTML, DISPID_EVMETH_ONLOAD, - EVENT_NODEHANDLER}, + EVENT_BIND_TO_BODY}, {mousedownW, onmousedownW, EVENTT_MOUSE, DISPID_EVMETH_ONMOUSEDOWN, EVENT_DEFAULTLISTENER|EVENT_BUBBLE}, {mousemoveW, onmousemoveW, EVENTT_MOUSE, DISPID_EVMETH_ONMOUSEMOVE, @@ -205,8 +204,6 @@ static const event_info_t event_info[] = { EVENT_DEFAULTLISTENER|EVENT_BUBBLE|EVENT_CANCELABLE} }; -static const eventid_t node_handled_list[] = { EVENTID_ABORT, EVENTID_ERROR, EVENTID_LOAD }; - eventid_t str_to_eid(LPCWSTR str) { int i; @@ -232,19 +229,6 @@ static eventid_t attr_to_eid(LPCWSTR str) return EVENTID_LAST; } -static DWORD get_node_handler_mask(eventid_t eid) -{ - DWORD i; - - for(i=0; i(%p)\n", This, p); + TRACE("(%p)->(%p)\n", This, p); - *p = -1; + if(This->nsevent) { + nsIDOMUIEvent *ui_event; + nsresult nsres; + + nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMUIEvent, (void**)&ui_event); + if(NS_SUCCEEDED(nsres)) { + /* NOTE: pageX is not exactly right here. */ + nsres = nsIDOMUIEvent_GetPageX(ui_event, &x); + assert(nsres == NS_OK); + nsIDOMUIEvent_Release(ui_event); + } + } + + *p = x; return S_OK; } static HRESULT WINAPI HTMLEventObj_get_y(IHTMLEventObj *iface, LONG *p) { HTMLEventObj *This = impl_from_IHTMLEventObj(iface); + LONG y = 0; - FIXME("(%p)->(%p)\n", This, p); + TRACE("(%p)->(%p)\n", This, p); - *p = -1; + if(This->nsevent) { + nsIDOMUIEvent *ui_event; + nsresult nsres; + + nsres = nsIDOMEvent_QueryInterface(This->nsevent, &IID_nsIDOMUIEvent, (void**)&ui_event); + if(NS_SUCCEEDED(nsres)) { + /* NOTE: pageY is not exactly right here. */ + nsres = nsIDOMUIEvent_GetPageY(ui_event, &y); + assert(nsres == NS_OK); + nsIDOMUIEvent_Release(ui_event); + } + } + + *p = y; return S_OK; } @@ -1292,31 +1304,33 @@ static BOOL alloc_handler_vector(event_target_t *event_target, eventid_t eid, in return TRUE; } -static HRESULT ensure_nsevent_handler(HTMLDocumentNode *doc, event_target_t *event_target, nsIDOMNode *nsnode, eventid_t eid) +static HRESULT ensure_nsevent_handler(HTMLDocumentNode *doc, event_target_t *event_target, eventid_t eid) { - if(!doc->nsdoc) + nsIDOMNode *nsnode = NULL; + + TRACE("%s\n", debugstr_w(event_info[eid].name)); + + if(!doc->nsdoc || doc->event_vector[eid] || !(event_info[eid].flags & (EVENT_DEFAULTLISTENER|EVENT_BIND_TO_BODY))) return S_OK; - if(event_info[eid].flags & EVENT_NODEHANDLER) { - DWORD mask; + if(event_info[eid].flags & EVENT_BIND_TO_BODY) { + nsIDOMHTMLElement *nsbody; + nsresult nsres; - mask = get_node_handler_mask(eid); - if(event_target->node_handlers_mask & mask) - return S_OK; - - add_nsevent_listener(doc, nsnode, event_info[eid].name); - event_target->node_handlers_mask |= mask; - return S_OK; + nsres = nsIDOMHTMLDocument_GetBody(doc->nsdoc, &nsbody); + if(NS_SUCCEEDED(nsres) && nsbody) { + nsnode = (nsIDOMNode*)nsbody; + }else { + ERR("GetBody failed: %08x\n", nsres); + return E_UNEXPECTED; + } } - if(!(event_info[eid].flags & EVENT_DEFAULTLISTENER)) - return S_OK; - - if(!doc->event_vector[eid]) { - doc->event_vector[eid] = TRUE; - add_nsevent_listener(doc, NULL, event_info[eid].name); - } + doc->event_vector[eid] = TRUE; + add_nsevent_listener(doc, nsnode, event_info[eid].name); + if(nsnode) + nsIDOMNode_Release(nsnode); return S_OK; } @@ -1347,7 +1361,7 @@ static HRESULT remove_event_handler(event_target_t **event_target, eventid_t eid return S_OK; } -static HRESULT set_event_handler_disp(event_target_t **event_target_ptr, nsIDOMNode *nsnode, HTMLDocumentNode *doc, +static HRESULT set_event_handler_disp(event_target_t **event_target_ptr, HTMLDocumentNode *doc, eventid_t eid, IDispatch *disp) { event_target_t *event_target; @@ -1368,17 +1382,17 @@ static HRESULT set_event_handler_disp(event_target_t **event_target_ptr, nsIDOMN event_target->event_table[eid]->handler_prop = disp; IDispatch_AddRef(disp); - return ensure_nsevent_handler(doc, event_target, nsnode, eid); + return ensure_nsevent_handler(doc, event_target, eid); } -HRESULT set_event_handler(event_target_t **event_target, nsIDOMNode *nsnode, HTMLDocumentNode *doc, eventid_t eid, VARIANT *var) +HRESULT set_event_handler(event_target_t **event_target, HTMLDocumentNode *doc, eventid_t eid, VARIANT *var) { switch(V_VT(var)) { case VT_NULL: return remove_event_handler(event_target, eid); case VT_DISPATCH: - return set_event_handler_disp(event_target, nsnode, doc, eid, V_DISPATCH(var)); + return set_event_handler_disp(event_target, doc, eid, V_DISPATCH(var)); default: FIXME("not handler %s\n", debugstr_variant(var)); @@ -1403,7 +1417,7 @@ HRESULT get_event_handler(event_target_t **event_target, eventid_t eid, VARIANT return S_OK; } -HRESULT attach_event(event_target_t **event_target_ptr, nsIDOMNode *nsnode, HTMLDocument *doc, BSTR name, +HRESULT attach_event(event_target_t **event_target_ptr, HTMLDocument *doc, BSTR name, IDispatch *disp, VARIANT_BOOL *res) { event_target_t *event_target; @@ -1434,7 +1448,7 @@ HRESULT attach_event(event_target_t **event_target_ptr, nsIDOMNode *nsnode, HTML event_target->event_table[eid]->handlers[i] = disp; *res = VARIANT_TRUE; - return ensure_nsevent_handler(doc->doc_node, event_target, nsnode, eid); + return ensure_nsevent_handler(doc->doc_node, event_target, eid); } HRESULT detach_event(event_target_t *event_target, HTMLDocument *doc, BSTR name, IDispatch *disp) @@ -1465,11 +1479,11 @@ HRESULT detach_event(event_target_t *event_target, HTMLDocument *doc, BSTR name, return S_OK; } -void bind_elem_event(HTMLDocumentNode *doc, HTMLElement *elem, const WCHAR *event, IDispatch *disp) +void bind_node_event(HTMLDocumentNode *doc, event_target_t **event_target, HTMLDOMNode *node, const WCHAR *event, IDispatch *disp) { eventid_t eid; - TRACE("(%p %p %s %p)\n", doc, elem, debugstr_w(event), disp); + TRACE("(%p %p %p %s %p)\n", doc, event_target, node, debugstr_w(event), disp); eid = attr_to_eid(event); if(eid == EVENTID_LAST) { @@ -1477,10 +1491,10 @@ void bind_elem_event(HTMLDocumentNode *doc, HTMLElement *elem, const WCHAR *even return; } - set_event_handler_disp(&elem->node.event_target, elem->node.nsnode, doc, eid, disp); + set_event_handler_disp(event_target, doc, eid, disp); } -void update_cp_events(HTMLInnerWindow *window, event_target_t **event_target_ptr, cp_static_data_t *cp, nsIDOMNode *nsnode) +void update_cp_events(HTMLInnerWindow *window, event_target_t **event_target_ptr, cp_static_data_t *cp) { event_target_t *event_target; int i; @@ -1491,7 +1505,7 @@ void update_cp_events(HTMLInnerWindow *window, event_target_t **event_target_ptr for(i=0; i < EVENTID_LAST; i++) { if((event_info[i].flags & EVENT_DEFAULTLISTENER) && is_cp_event(cp, event_info[i].dispid)) - ensure_nsevent_handler(window->doc, event_target, nsnode, i); + ensure_nsevent_handler(window->doc, event_target, i); } } @@ -1522,7 +1536,7 @@ void check_event_attr(HTMLDocumentNode *doc, nsIDOMElement *nselem) if(disp) { hres = get_node(doc, (nsIDOMNode*)nselem, TRUE, &node); if(SUCCEEDED(hres)) { - set_event_handler_disp(get_node_event_target(node), node->nsnode, node->doc, i, disp); + set_event_handler_disp(get_node_event_target(node), node->doc, i, disp); node_release(node); } IDispatch_Release(disp); @@ -1547,7 +1561,7 @@ HRESULT doc_init_events(HTMLDocumentNode *doc) for(i=0; i < EVENTID_LAST; i++) { if(event_info[i].flags & EVENT_HASDEFAULTHANDLERS) { - hres = ensure_nsevent_handler(doc, NULL, NULL, i); + hres = ensure_nsevent_handler(doc, NULL, i); if(FAILED(hres)) return hres; } diff --git a/dll/win32/mshtml/htmlevent.h b/dll/win32/mshtml/htmlevent.h index ca39038c13c..528eded8f16 100644 --- a/dll/win32/mshtml/htmlevent.h +++ b/dll/win32/mshtml/htmlevent.h @@ -51,18 +51,18 @@ typedef enum { eventid_t str_to_eid(LPCWSTR) DECLSPEC_HIDDEN; void check_event_attr(HTMLDocumentNode*,nsIDOMElement*) DECLSPEC_HIDDEN; void release_event_target(event_target_t*) DECLSPEC_HIDDEN; - void fire_event(HTMLDocumentNode*,eventid_t,BOOL,nsIDOMNode*,nsIDOMEvent*,IDispatch*) DECLSPEC_HIDDEN; -HRESULT set_event_handler(event_target_t**,nsIDOMNode*,HTMLDocumentNode*,eventid_t,VARIANT*) DECLSPEC_HIDDEN; +void fire_event(HTMLDocumentNode*,eventid_t,BOOL,nsIDOMNode*,nsIDOMEvent*,IDispatch*) DECLSPEC_HIDDEN; +HRESULT set_event_handler(event_target_t**,HTMLDocumentNode*,eventid_t,VARIANT*) DECLSPEC_HIDDEN; HRESULT get_event_handler(event_target_t**,eventid_t,VARIANT*) DECLSPEC_HIDDEN; -HRESULT attach_event(event_target_t**,nsIDOMNode*,HTMLDocument*,BSTR,IDispatch*,VARIANT_BOOL*) DECLSPEC_HIDDEN; +HRESULT attach_event(event_target_t**,HTMLDocument*,BSTR,IDispatch*,VARIANT_BOOL*) DECLSPEC_HIDDEN; HRESULT detach_event(event_target_t*,HTMLDocument*,BSTR,IDispatch*) DECLSPEC_HIDDEN; HRESULT dispatch_event(HTMLDOMNode*,const WCHAR*,VARIANT*,VARIANT_BOOL*) DECLSPEC_HIDDEN; HRESULT call_fire_event(HTMLDOMNode*,eventid_t) DECLSPEC_HIDDEN; -void update_cp_events(HTMLInnerWindow*,event_target_t**,cp_static_data_t*,nsIDOMNode*) DECLSPEC_HIDDEN; +void update_cp_events(HTMLInnerWindow*,event_target_t**,cp_static_data_t*) DECLSPEC_HIDDEN; HRESULT doc_init_events(HTMLDocumentNode*) DECLSPEC_HIDDEN; void detach_events(HTMLDocumentNode *doc) DECLSPEC_HIDDEN; HRESULT create_event_obj(IHTMLEventObj**) DECLSPEC_HIDDEN; -void bind_elem_event(HTMLDocumentNode*,HTMLElement*,const WCHAR*,IDispatch*) DECLSPEC_HIDDEN; +void bind_node_event(HTMLDocumentNode*,event_target_t**,HTMLDOMNode*,const WCHAR*,IDispatch*) DECLSPEC_HIDDEN; void init_nsevents(HTMLDocumentNode*) DECLSPEC_HIDDEN; void release_nsevents(HTMLDocumentNode*) DECLSPEC_HIDDEN; @@ -76,7 +76,7 @@ static inline event_target_t **get_node_event_target(HTMLDOMNode *node) static inline HRESULT set_node_event(HTMLDOMNode *node, eventid_t eid, VARIANT *var) { - return set_event_handler(get_node_event_target(node), node->nsnode, node->doc, eid, var); + return set_event_handler(get_node_event_target(node), node->doc, eid, var); } static inline HRESULT get_node_event(HTMLDOMNode *node, eventid_t eid, VARIANT *var) diff --git a/dll/win32/mshtml/htmlform.c b/dll/win32/mshtml/htmlform.c index 0a0ed682df0..7eba35cee25 100644 --- a/dll/win32/mshtml/htmlform.c +++ b/dll/win32/mshtml/htmlform.c @@ -346,17 +346,75 @@ static HRESULT WINAPI HTMLFormElement_get_onreset(IHTMLFormElement *iface, VARIA static HRESULT WINAPI HTMLFormElement_submit(IHTMLFormElement *iface) { HTMLFormElement *This = impl_from_IHTMLFormElement(iface); + HTMLOuterWindow *window = NULL, *this_window = NULL; + nsIInputStream *post_stream; + nsAString action_uri_str, target_str; + IUri *uri; nsresult nsres; + HRESULT hres; TRACE("(%p)->()\n", This); - nsres = nsIDOMHTMLFormElement_Submit(This->nsform); - if(NS_FAILED(nsres)) { - ERR("Submit failed: %08x\n", nsres); - return E_FAIL; + if(This->element.node.doc) { + HTMLDocumentNode *doc = This->element.node.doc; + if(doc->window && doc->window->base.outer_window) + this_window = doc->window->base.outer_window; + } + if(!this_window) { + TRACE("No outer window\n"); + return S_OK; } - return S_OK; + nsAString_Init(&target_str, NULL); + nsres = nsIDOMHTMLFormElement_GetTarget(This->nsform, &target_str); + if(NS_SUCCEEDED(nsres)) { + BOOL use_new_window; + window = get_target_window(this_window, &target_str, &use_new_window); + if(use_new_window) + FIXME("submit to new window is not supported\n"); + } + nsAString_Finish(&target_str); + if(!window) + return S_OK; + + /* + * FIXME: We currently don't use our submit implementation for sub-windows because + * load_nsuri can't support post data. We should fix it. + */ + if(!window->doc_obj || window->doc_obj->basedoc.window != window) { + nsres = nsIDOMHTMLFormElement_Submit(This->nsform); + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); + if(NS_FAILED(nsres)) { + ERR("Submit failed: %08x\n", nsres); + return E_FAIL; + } + + return S_OK; + } + + nsAString_Init(&action_uri_str, NULL); + nsres = nsIDOMHTMLFormElement_GetFormData(This->nsform, NULL, &action_uri_str, &post_stream); + if(NS_SUCCEEDED(nsres)) { + const PRUnichar *action_uri; + + nsAString_GetData(&action_uri_str, &action_uri); + hres = create_uri(action_uri, 0, &uri); + }else { + ERR("GetFormData failed: %08x\n", nsres); + hres = E_FAIL; + } + nsAString_Finish(&action_uri_str); + if(SUCCEEDED(hres)) { + window->readystate_locked++; + hres = submit_form(window, uri, post_stream); + window->readystate_locked--; + IUri_Release(uri); + } + + IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface); + if(post_stream) + nsIInputStream_Release(post_stream); + return hres; } static HRESULT WINAPI HTMLFormElement_reset(IHTMLFormElement *iface) diff --git a/dll/win32/mshtml/htmlframebase.c b/dll/win32/mshtml/htmlframebase.c index c034f837e4b..90caceb921f 100644 --- a/dll/win32/mshtml/htmlframebase.c +++ b/dll/win32/mshtml/htmlframebase.c @@ -578,15 +578,19 @@ static HRESULT WINAPI HTMLFrameBase2_get_contentWindow(IHTMLFrameBase2 *iface, I static HRESULT WINAPI HTMLFrameBase2_put_onload(IHTMLFrameBase2 *iface, VARIANT v) { HTMLFrameBase *This = impl_from_IHTMLFrameBase2(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; + + TRACE("(%p)->(%s)\n", This, debugstr_variant(&v)); + + return set_node_event(&This->element.node, EVENTID_LOAD, &v); } static HRESULT WINAPI HTMLFrameBase2_get_onload(IHTMLFrameBase2 *iface, VARIANT *p) { HTMLFrameBase *This = impl_from_IHTMLFrameBase2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, p); + + return get_node_event(&This->element.node, EVENTID_LOAD, p); } static HRESULT WINAPI HTMLFrameBase2_put_onreadystatechange(IHTMLFrameBase2 *iface, VARIANT v) diff --git a/dll/win32/mshtml/htmlselect.c b/dll/win32/mshtml/htmlselect.c index 20cfb1c2e70..3acc2f78890 100644 --- a/dll/win32/mshtml/htmlselect.c +++ b/dll/win32/mshtml/htmlselect.c @@ -141,15 +141,28 @@ static HRESULT WINAPI HTMLSelectElement_get_size(IHTMLSelectElement *iface, LONG static HRESULT WINAPI HTMLSelectElement_put_multiple(IHTMLSelectElement *iface, VARIANT_BOOL v) { HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); - FIXME("(%p)->(%x)\n", This, v); - return E_NOTIMPL; + nsresult nsres; + + TRACE("(%p)->(%x)\n", This, v); + + nsres = nsIDOMHTMLSelectElement_SetMultiple(This->nsselect, !!v); + assert(nsres == NS_OK); + return S_OK; } static HRESULT WINAPI HTMLSelectElement_get_multiple(IHTMLSelectElement *iface, VARIANT_BOOL *p) { HTMLSelectElement *This = impl_from_IHTMLSelectElement(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + cpp_bool val; + nsresult nsres; + + TRACE("(%p)->(%p)\n", This, p); + + nsres = nsIDOMHTMLSelectElement_GetMultiple(This->nsselect, &val); + assert(nsres == NS_OK); + + *p = val ? VARIANT_TRUE : VARIANT_FALSE; + return S_OK; } static HRESULT WINAPI HTMLSelectElement_put_name(IHTMLSelectElement *iface, BSTR v) diff --git a/dll/win32/mshtml/htmlstyle.c b/dll/win32/mshtml/htmlstyle.c index 374d5bc396d..c838a42107a 100644 --- a/dll/win32/mshtml/htmlstyle.c +++ b/dll/win32/mshtml/htmlstyle.c @@ -74,6 +74,9 @@ static const WCHAR attrBorderWidth[] = {'b','o','r','d','e','r','-','w','i','d','t','h',0}; static const WCHAR attrBottom[] = {'b','o','t','t','o','m',0}; +/* FIXME: Use unprefixed version (requires Gecko changes). */ +static const WCHAR attrBoxSizing[] = + {'-','m','o','z','-','b','o','x','-','s','i','z','i','n','g',0}; static const WCHAR attrClear[] = {'c','l','e','a','r',0}; static const WCHAR attrClip[] = @@ -106,6 +109,8 @@ static const WCHAR attrLetterSpacing[] = {'l','e','t','t','e','r','-','s','p','a','c','i','n','g',0}; static const WCHAR attrLineHeight[] = {'l','i','n','e','-','h','e','i','g','h','t',0}; +static const WCHAR attrListStyleType[] = + {'l','i','s','t','-','s','t','y','l','e','-','t','y','p','e',0}; static const WCHAR attrMargin[] = {'m','a','r','g','i','n',0}; static const WCHAR attrMarginBottom[] = @@ -118,6 +123,8 @@ static const WCHAR attrMarginTop[] = {'m','a','r','g','i','n','-','t','o','p',0}; static const WCHAR attrMinHeight[] = {'m','i','n','-','h','e','i','g','h','t',0}; +static const WCHAR attrOutline[] = + {'o','u','t','l','i','n','e',0}; static const WCHAR attrOverflow[] = {'o','v','e','r','f','l','o','w',0}; static const WCHAR attrOverflowX[] = @@ -202,6 +209,7 @@ static const style_tbl_entry_t style_tbl[] = { {attrBorderTopWidth, DISPID_IHTMLSTYLE_BORDERTOPWIDTH}, {attrBorderWidth, DISPID_IHTMLSTYLE_BORDERWIDTH}, {attrBottom, DISPID_IHTMLSTYLE2_BOTTOM}, + {attrBoxSizing, DISPID_IHTMLSTYLE6_BOXSIZING}, {attrClear, DISPID_IHTMLSTYLE_CLEAR}, {attrClip, DISPID_IHTMLSTYLE_CLIP}, {attrColor, DISPID_IHTMLSTYLE_COLOR}, @@ -218,12 +226,14 @@ static const style_tbl_entry_t style_tbl[] = { {attrLeft, DISPID_IHTMLSTYLE_LEFT}, {attrLetterSpacing, DISPID_IHTMLSTYLE_LETTERSPACING}, {attrLineHeight, DISPID_IHTMLSTYLE_LINEHEIGHT}, + {attrListStyleType, DISPID_IHTMLSTYLE_LISTSTYLETYPE}, {attrMargin, DISPID_IHTMLSTYLE_MARGIN}, {attrMarginBottom, DISPID_IHTMLSTYLE_MARGINBOTTOM}, {attrMarginLeft, DISPID_IHTMLSTYLE_MARGINLEFT}, {attrMarginRight, DISPID_IHTMLSTYLE_MARGINRIGHT}, {attrMarginTop, DISPID_IHTMLSTYLE_MARGINTOP}, {attrMinHeight, DISPID_IHTMLSTYLE4_MINHEIGHT}, + {attrOutline, DISPID_IHTMLSTYLE6_OUTLINE}, {attrOverflow, DISPID_IHTMLSTYLE_OVERFLOW}, {attrOverflowX, DISPID_IHTMLSTYLE2_OVERFLOWX}, {attrOverflowY, DISPID_IHTMLSTYLE2_OVERFLOWY}, @@ -447,7 +457,7 @@ static HRESULT nsstyle_to_bstr(const WCHAR *val, DWORD flags, BSTR *p) DWORD len; if(!*val) { - *p = NULL; + *p = (flags & ATTR_NO_NULL) ? SysAllocStringLen(NULL, 0) : NULL; return S_OK; } @@ -2144,15 +2154,19 @@ static HRESULT WINAPI HTMLStyle_get_visibility(IHTMLStyle *iface, BSTR *p) static HRESULT WINAPI HTMLStyle_put_listStyleType(IHTMLStyle *iface, BSTR v) { HTMLStyle *This = impl_from_IHTMLStyle(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + return set_style_attr(This, STYLEID_LISTSTYLETYPE, v, 0); } static HRESULT WINAPI HTMLStyle_get_listStyleType(IHTMLStyle *iface, BSTR *p) { HTMLStyle *This = impl_from_IHTMLStyle(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, p); + + return get_style_attr(This, STYLEID_LISTSTYLETYPE, p); } static HRESULT WINAPI HTMLStyle_put_listStylePosition(IHTMLStyle *iface, BSTR v) @@ -3091,11 +3105,9 @@ static dispex_static_data_t HTMLStyle_dispex = { HTMLStyle_iface_tids }; -HRESULT HTMLStyle_Create(HTMLElement *elem, HTMLStyle **ret) +static HRESULT get_style_from_elem(HTMLElement *elem, nsIDOMCSSStyleDeclaration **ret) { nsIDOMElementCSSInlineStyle *nselemstyle; - nsIDOMCSSStyleDeclaration *nsstyle; - HTMLStyle *style; nsresult nsres; if(!elem->nselem) { @@ -3107,13 +3119,26 @@ HRESULT HTMLStyle_Create(HTMLElement *elem, HTMLStyle **ret) (void**)&nselemstyle); assert(nsres == NS_OK); - nsres = nsIDOMElementCSSInlineStyle_GetStyle(nselemstyle, &nsstyle); + nsres = nsIDOMElementCSSInlineStyle_GetStyle(nselemstyle, ret); nsIDOMElementCSSInlineStyle_Release(nselemstyle); if(NS_FAILED(nsres)) { ERR("GetStyle failed: %08x\n", nsres); return E_FAIL; } + return S_OK; +} + +HRESULT HTMLStyle_Create(HTMLElement *elem, HTMLStyle **ret) +{ + nsIDOMCSSStyleDeclaration *nsstyle; + HTMLStyle *style; + HRESULT hres; + + hres = get_style_from_elem(elem, &nsstyle); + if(FAILED(hres)) + return hres; + style = heap_alloc_zero(sizeof(HTMLStyle)); if(!style) { nsIDOMCSSStyleDeclaration_Release(nsstyle); @@ -3134,3 +3159,31 @@ HRESULT HTMLStyle_Create(HTMLElement *elem, HTMLStyle **ret) *ret = style; return S_OK; } + +HRESULT get_elem_style(HTMLElement *elem, styleid_t styleid, BSTR *ret) +{ + nsIDOMCSSStyleDeclaration *style; + HRESULT hres; + + hres = get_style_from_elem(elem, &style); + if(FAILED(hres)) + return hres; + + hres = get_nsstyle_attr(style, styleid, ret, 0); + nsIDOMCSSStyleDeclaration_Release(style); + return hres; +} + +HRESULT set_elem_style(HTMLElement *elem, styleid_t styleid, const WCHAR *val) +{ + nsIDOMCSSStyleDeclaration *style; + HRESULT hres; + + hres = get_style_from_elem(elem, &style); + if(FAILED(hres)) + return hres; + + hres = set_nsstyle_attr(style, styleid, val, 0); + nsIDOMCSSStyleDeclaration_Release(style); + return hres; +} diff --git a/dll/win32/mshtml/htmlstyle.h b/dll/win32/mshtml/htmlstyle.h index 4f2e5ab3421..030d8a1026c 100644 --- a/dll/win32/mshtml/htmlstyle.h +++ b/dll/win32/mshtml/htmlstyle.h @@ -61,6 +61,7 @@ typedef enum { STYLEID_BORDER_TOP_WIDTH, STYLEID_BORDER_WIDTH, STYLEID_BOTTOM, + STYLEID_BOX_SIZING, STYLEID_CLEAR, STYLEID_CLIP, STYLEID_COLOR, @@ -77,12 +78,14 @@ typedef enum { STYLEID_LEFT, STYLEID_LETTER_SPACING, STYLEID_LINE_HEIGHT, + STYLEID_LISTSTYLETYPE, STYLEID_MARGIN, STYLEID_MARGIN_BOTTOM, STYLEID_MARGIN_LEFT, STYLEID_MARGIN_RIGHT, STYLEID_MARGIN_TOP, STYLEID_MIN_HEIGHT, + STYLEID_OUTLINE, STYLEID_OVERFLOW, STYLEID_OVERFLOW_X, STYLEID_OVERFLOW_Y, @@ -118,8 +121,12 @@ HRESULT set_nsstyle_attr(nsIDOMCSSStyleDeclaration*,styleid_t,LPCWSTR,DWORD) DEC HRESULT set_nsstyle_attr_var(nsIDOMCSSStyleDeclaration *nsstyle, styleid_t sid, VARIANT *value, DWORD flags) DECLSPEC_HIDDEN; HRESULT get_nsstyle_attr_var(nsIDOMCSSStyleDeclaration *nsstyle, styleid_t sid, VARIANT *p, DWORD flags) DECLSPEC_HIDDEN; +HRESULT get_elem_style(HTMLElement*,styleid_t,BSTR*) DECLSPEC_HIDDEN; +HRESULT set_elem_style(HTMLElement*,styleid_t,const WCHAR*) DECLSPEC_HIDDEN; + #define ATTR_FIX_PX 0x0001 #define ATTR_FIX_URL 0x0002 #define ATTR_STR_TO_INT 0x0004 #define ATTR_HEX_INT 0x0008 #define ATTR_REMOVE_COMMA 0x0010 +#define ATTR_NO_NULL 0x0020 diff --git a/dll/win32/mshtml/htmlstyle3.c b/dll/win32/mshtml/htmlstyle3.c index 5eacf7f3eb7..7e6bbc6a616 100644 --- a/dll/win32/mshtml/htmlstyle3.c +++ b/dll/win32/mshtml/htmlstyle3.c @@ -688,15 +688,19 @@ static HRESULT WINAPI HTMLStyle6_get_counterReset(IHTMLStyle6 *iface, BSTR *p) static HRESULT WINAPI HTMLStyle6_put_outline(IHTMLStyle6 *iface, BSTR v) { HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + return set_nsstyle_attr(This->nsstyle, STYLEID_OUTLINE, v, 0); } static HRESULT WINAPI HTMLStyle6_get_outline(IHTMLStyle6 *iface, BSTR *p) { HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, p); + + return get_nsstyle_attr(This->nsstyle, STYLEID_OUTLINE, p, ATTR_NO_NULL); } static HRESULT WINAPI HTMLStyle6_put_outlineWidth(IHTMLStyle6 *iface, VARIANT v) @@ -744,15 +748,19 @@ static HRESULT WINAPI HTMLStyle6_get_outlineColor(IHTMLStyle6 *iface, VARIANT *p static HRESULT WINAPI HTMLStyle6_put_boxSizing(IHTMLStyle6 *iface, BSTR v) { HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + return set_nsstyle_attr(This->nsstyle, STYLEID_BOX_SIZING, v, 0); } static HRESULT WINAPI HTMLStyle6_get_boxSizing(IHTMLStyle6 *iface, BSTR *p) { HTMLStyle *This = impl_from_IHTMLStyle6(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, p); + + return get_nsstyle_attr(This->nsstyle, STYLEID_BOX_SIZING, p, 0); } static HRESULT WINAPI HTMLStyle6_put_boxSpacing(IHTMLStyle6 *iface, BSTR v) diff --git a/dll/win32/mshtml/htmlstylesheet.c b/dll/win32/mshtml/htmlstylesheet.c index 4ade7c7a5bc..526168ff462 100644 --- a/dll/win32/mshtml/htmlstylesheet.c +++ b/dll/win32/mshtml/htmlstylesheet.c @@ -539,8 +539,14 @@ static HRESULT WINAPI HTMLStyleSheet_put_href(IHTMLStyleSheet *iface, BSTR v) static HRESULT WINAPI HTMLStyleSheet_get_href(IHTMLStyleSheet *iface, BSTR *p) { HTMLStyleSheet *This = impl_from_IHTMLStyleSheet(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + nsAString href_str; + nsresult nsres; + + TRACE("(%p)->(%p)\n", This, p); + + nsAString_Init(&href_str, NULL); + nsres = nsIDOMCSSStyleSheet_GetHref(This->nsstylesheet, &href_str); + return return_nsstr(nsres, &href_str, p); } static HRESULT WINAPI HTMLStyleSheet_get_type(IHTMLStyleSheet *iface, BSTR *p) diff --git a/dll/win32/mshtml/htmltable.c b/dll/win32/mshtml/htmltable.c index 04bc2ab1542..a1eb77f8a70 100644 --- a/dll/win32/mshtml/htmltable.c +++ b/dll/win32/mshtml/htmltable.c @@ -232,15 +232,48 @@ static HRESULT WINAPI HTMLTable_get_background(IHTMLTable *iface, BSTR *p) static HRESULT WINAPI HTMLTable_put_bgColor(IHTMLTable *iface, VARIANT v) { HTMLTable *This = impl_from_IHTMLTable(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; + nsAString val; + nsresult nsres; + + TRACE("(%p)->(%s)\n", This, debugstr_variant(&v)); + + nsAString_InitDepend(&val, V_BSTR(&v)); + variant_to_nscolor(&v, &val); + nsres = nsIDOMHTMLTableElement_SetBgColor(This->nstable, &val); + nsAString_Finish(&val); + + if (NS_FAILED(nsres)){ + ERR("Set BgColor(%s) failed!\n", debugstr_variant(&v)); + return E_FAIL; + } + + return S_OK; } static HRESULT WINAPI HTMLTable_get_bgColor(IHTMLTable *iface, VARIANT *p) { HTMLTable *This = impl_from_IHTMLTable(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + nsAString strColor; + nsresult nsres; + HRESULT hres; + const PRUnichar *color; + + TRACE("(%p)->(%p)\n", This, p); + + nsAString_Init(&strColor, NULL); + nsres = nsIDOMHTMLTableElement_GetBgColor(This->nstable, &strColor); + + if(NS_SUCCEEDED(nsres)) { + nsAString_GetData(&strColor, &color); + V_VT(p) = VT_BSTR; + hres = nscolor_to_str(color, &V_BSTR(p)); + }else { + ERR("SetBgColor failed: %08x\n", nsres); + hres = E_FAIL; + } + + nsAString_Finish(&strColor); + return hres; } static HRESULT WINAPI HTMLTable_put_borderColor(IHTMLTable *iface, VARIANT v) @@ -288,15 +321,34 @@ static HRESULT WINAPI HTMLTable_get_borderColorDark(IHTMLTable *iface, VARIANT * static HRESULT WINAPI HTMLTable_put_align(IHTMLTable *iface, BSTR v) { HTMLTable *This = impl_from_IHTMLTable(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; + nsAString val; + nsresult nsres; + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + nsAString_InitDepend(&val, v); + + nsres = nsIDOMHTMLTableElement_SetAlign(This->nstable, &val); + nsAString_Finish(&val); + if (NS_FAILED(nsres)){ + ERR("Set Align(%s) failed!\n", debugstr_w(v)); + return E_FAIL; + } + return S_OK; } static HRESULT WINAPI HTMLTable_get_align(IHTMLTable *iface, BSTR *p) { HTMLTable *This = impl_from_IHTMLTable(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + nsAString val; + nsresult nsres; + + TRACE("(%p)->(%p)\n", This, p); + + nsAString_Init(&val, NULL); + nsres = nsIDOMHTMLTableElement_GetAlign(This->nstable, &val); + + return return_nsstr(nsres, &val, p); } static HRESULT WINAPI HTMLTable_refresh(IHTMLTable *iface) diff --git a/dll/win32/mshtml/htmltablerow.c b/dll/win32/mshtml/htmltablerow.c index 07268e15b5a..0d053fa9f69 100644 --- a/dll/win32/mshtml/htmltablerow.c +++ b/dll/win32/mshtml/htmltablerow.c @@ -88,43 +88,116 @@ static HRESULT WINAPI HTMLTableRow_Invoke(IHTMLTableRow *iface, DISPID dispIdMem static HRESULT WINAPI HTMLTableRow_put_align(IHTMLTableRow *iface, BSTR v) { HTMLTableRow *This = impl_from_IHTMLTableRow(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; + nsAString val; + nsresult nsres; + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + nsAString_InitDepend(&val, v); + + nsres = nsIDOMHTMLTableRowElement_SetAlign(This->nsrow, &val); + nsAString_Finish(&val); + if (NS_FAILED(nsres)){ + ERR("Set Align(%s) failed!\n", debugstr_w(v)); + return E_FAIL; + } + return S_OK; } static HRESULT WINAPI HTMLTableRow_get_align(IHTMLTableRow *iface, BSTR *p) { HTMLTableRow *This = impl_from_IHTMLTableRow(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + nsAString val; + nsresult nsres; + + TRACE("(%p)->(%p)\n", This, p); + + nsAString_Init(&val, NULL); + nsres = nsIDOMHTMLTableRowElement_GetAlign(This->nsrow, &val); + + return return_nsstr(nsres, &val, p); } static HRESULT WINAPI HTMLTableRow_put_vAlign(IHTMLTableRow *iface, BSTR v) { HTMLTableRow *This = impl_from_IHTMLTableRow(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; + nsAString val; + nsresult nsres; + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + nsAString_InitDepend(&val, v); + + nsres = nsIDOMHTMLTableRowElement_SetVAlign(This->nsrow, &val); + nsAString_Finish(&val); + + if (NS_FAILED(nsres)){ + ERR("Set VAlign(%s) failed!\n", debugstr_w(v)); + return E_FAIL; + } + + return S_OK; } static HRESULT WINAPI HTMLTableRow_get_vAlign(IHTMLTableRow *iface, BSTR *p) { HTMLTableRow *This = impl_from_IHTMLTableRow(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + nsAString val; + nsresult nsres; + + TRACE("(%p)->(%p)\n", This, p); + + nsAString_Init(&val, NULL); + nsres = nsIDOMHTMLTableRowElement_GetVAlign(This->nsrow, &val); + + return return_nsstr(nsres, &val, p); } static HRESULT WINAPI HTMLTableRow_put_bgColor(IHTMLTableRow *iface, VARIANT v) { HTMLTableRow *This = impl_from_IHTMLTableRow(iface); - FIXME("(%p)->(%s)\n", This, debugstr_variant(&v)); - return E_NOTIMPL; + nsAString val; + nsresult nsres; + + TRACE("(%p)->(%s)\n", This, debugstr_variant(&v)); + + nsAString_InitDepend(&val, V_BSTR(&v)); + variant_to_nscolor(&v, &val); + nsres = nsIDOMHTMLTableRowElement_SetBgColor(This->nsrow, &val); + nsAString_Finish(&val); + + if (NS_FAILED(nsres)){ + ERR("Set BgColor(%s) failed!\n", debugstr_variant(&v)); + return E_FAIL; + } + + return S_OK; } static HRESULT WINAPI HTMLTableRow_get_bgColor(IHTMLTableRow *iface, VARIANT *p) { HTMLTableRow *This = impl_from_IHTMLTableRow(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + nsAString strColor; + nsresult nsres; + HRESULT hres; + const PRUnichar *color; + + TRACE("(%p)->(%p)\n", This, p); + + nsAString_Init(&strColor, NULL); + nsres = nsIDOMHTMLTableRowElement_GetBgColor(This->nsrow, &strColor); + + if(NS_SUCCEEDED(nsres)) { + nsAString_GetData(&strColor, &color); + V_VT(p) = VT_BSTR; + hres = nscolor_to_str(color, &V_BSTR(p)); + }else { + ERR("SetBgColor failed: %08x\n", nsres); + hres = E_FAIL; + } + + nsAString_Finish(&strColor); + return hres; } static HRESULT WINAPI HTMLTableRow_put_borderColor(IHTMLTableRow *iface, VARIANT v) @@ -172,15 +245,29 @@ static HRESULT WINAPI HTMLTableRow_get_borderColorDark(IHTMLTableRow *iface, VAR static HRESULT WINAPI HTMLTableRow_get_rowIndex(IHTMLTableRow *iface, LONG *p) { HTMLTableRow *This = impl_from_IHTMLTableRow(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + nsresult nsres; + + TRACE("(%p)->(%p)\n", This, p); + nsres = nsIDOMHTMLTableRowElement_GetRowIndex(This->nsrow, p); + if(NS_FAILED(nsres)) { + ERR("Get rowIndex failed: %08x\n", nsres); + return E_FAIL; + } + return S_OK; } -static HRESULT WINAPI HTMLTableRow_get_selectionRowIndex(IHTMLTableRow *iface, LONG *p) +static HRESULT WINAPI HTMLTableRow_get_sectionRowIndex(IHTMLTableRow *iface, LONG *p) { HTMLTableRow *This = impl_from_IHTMLTableRow(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + nsresult nsres; + + TRACE("(%p)->(%p)\n", This, p); + nsres = nsIDOMHTMLTableRowElement_GetSectionRowIndex(This->nsrow, p); + if(NS_FAILED(nsres)) { + ERR("Get selectionRowIndex failed: %08x\n", nsres); + return E_FAIL; + } + return S_OK; } static HRESULT WINAPI HTMLTableRow_get_cells(IHTMLTableRow *iface, IHTMLElementCollection **p) @@ -238,7 +325,7 @@ static const IHTMLTableRowVtbl HTMLTableRowVtbl = { HTMLTableRow_put_borderColorDark, HTMLTableRow_get_borderColorDark, HTMLTableRow_get_rowIndex, - HTMLTableRow_get_selectionRowIndex, + HTMLTableRow_get_sectionRowIndex, HTMLTableRow_get_cells, HTMLTableRow_insertCell, HTMLTableRow_deleteCell diff --git a/dll/win32/mshtml/htmlwindow.c b/dll/win32/mshtml/htmlwindow.c index 00919bf7aa4..4493437cb63 100644 --- a/dll/win32/mshtml/htmlwindow.c +++ b/dll/win32/mshtml/htmlwindow.c @@ -71,7 +71,7 @@ static inline HRESULT set_window_event(HTMLWindow *window, eventid_t eid, VARIAN return E_FAIL; } - return set_event_handler(&window->inner_window->doc->body_event_target, NULL, window->inner_window->doc, eid, var); + return set_event_handler(&window->inner_window->doc->body_event_target, window->inner_window->doc, eid, var); } static inline HRESULT get_window_event(HTMLWindow *window, eventid_t eid, VARIANT *var) @@ -91,8 +91,12 @@ static void detach_inner_window(HTMLInnerWindow *window) if(outer_window && outer_window->doc_obj && outer_window == outer_window->doc_obj->basedoc.window) window->doc->basedoc.cp_container.forward_container = NULL; - if(window->doc) + if(window->doc) { detach_events(window->doc); + while(!list_empty(&window->doc->plugin_hosts)) + detach_plugin_host(LIST_ENTRY(list_head(&window->doc->plugin_hosts), PluginHost, entry)); + } + abort_window_bindings(window); remove_target_tasks(window->task_magic); release_script_hosts(window); @@ -1589,7 +1593,7 @@ static HRESULT WINAPI HTMLWindow3_attachEvent(IHTMLWindow3 *iface, BSTR event, I return E_FAIL; } - return attach_event(&window->doc->body_event_target, NULL, &window->doc->basedoc, event, pDisp, pfResult); + return attach_event(&window->doc->body_event_target, &window->doc->basedoc, event, pDisp, pfResult); } static HRESULT WINAPI HTMLWindow3_detachEvent(IHTMLWindow3 *iface, BSTR event, IDispatch *pDisp) @@ -2156,7 +2160,7 @@ static HRESULT WINAPI HTMLPrivateWindow_SuperNavigate(IHTMLPrivateWindow *iface, headers = V_BSTR(headers_var); } - hres = super_navigate(window, uri, BINDING_NAVIGATED, headers, post_data, post_data_size); + hres = super_navigate(window, uri, BINDING_NAVIGATED|BINDING_NOFRAG, headers, post_data, post_data_size); IUri_Release(uri); if(post_data) SafeArrayUnaccessData(V_ARRAY(post_data_var)); diff --git a/dll/win32/mshtml/main.c b/dll/win32/mshtml/main.c index b2696a09424..f22c63c5ea2 100644 --- a/dll/win32/mshtml/main.c +++ b/dll/win32/mshtml/main.c @@ -443,6 +443,8 @@ static HRESULT register_server(BOOL do_register) hres = pRegInstall(hInst, do_register ? "RegisterDll" : "UnregisterDll", &strtable); + FreeLibrary(hAdvpack); + for(i=0; i < sizeof(pse)/sizeof(pse[0]); i++) heap_free(pse[i].pszValue); diff --git a/dll/win32/mshtml/mshtml_classes.idl b/dll/win32/mshtml/mshtml_classes.idl index 9766031979b..b84a50f1cf1 100644 --- a/dll/win32/mshtml/mshtml_classes.idl +++ b/dll/win32/mshtml/mshtml_classes.idl @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma makedep register + [ helpstring("Microsoft HTML About Pluggable Protocol"), threading(apartment), diff --git a/dll/win32/mshtml/mshtml_private.h b/dll/win32/mshtml/mshtml_private.h index e07c1c11741..d5beb2565a9 100644 --- a/dll/win32/mshtml/mshtml_private.h +++ b/dll/win32/mshtml/mshtml_private.h @@ -407,7 +407,10 @@ struct HTMLOuterWindow { nsIDOMWindow *nswindow; HTMLOuterWindow *parent; HTMLFrameBase *frame_element; + READYSTATE readystate; + BOOL readystate_locked; + unsigned readystate_pending; HTMLInnerWindow *pending_window; IMoniker *mon; @@ -507,6 +510,7 @@ struct HTMLDocument { IHTMLDocument4 IHTMLDocument4_iface; IHTMLDocument5 IHTMLDocument5_iface; IHTMLDocument6 IHTMLDocument6_iface; + IHTMLDocument7 IHTMLDocument7_iface; IPersistMoniker IPersistMoniker_iface; IPersistFile IPersistFile_iface; IPersistHistory IPersistHistory_iface; @@ -779,8 +783,6 @@ HRESULT create_history(HTMLInnerWindow*,OmHistory**) DECLSPEC_HIDDEN; HRESULT create_storage(IHTMLStorage**) DECLSPEC_HIDDEN; -void HTMLDocument_HTMLDocument3_Init(HTMLDocument*) DECLSPEC_HIDDEN; -void HTMLDocument_HTMLDocument5_Init(HTMLDocument*) DECLSPEC_HIDDEN; void HTMLDocument_Persist_Init(HTMLDocument*) DECLSPEC_HIDDEN; void HTMLDocument_OleCmd_Init(HTMLDocument*) DECLSPEC_HIDDEN; void HTMLDocument_OleObj_Init(HTMLDocument*) DECLSPEC_HIDDEN; @@ -854,6 +856,7 @@ void get_editor_controller(NSContainer*) DECLSPEC_HIDDEN; nsresult get_nsinterface(nsISupports*,REFIID,void**) DECLSPEC_HIDDEN; nsIWritableVariant *create_nsvariant(void) DECLSPEC_HIDDEN; nsresult create_nsfile(const PRUnichar*,nsIFile**) DECLSPEC_HIDDEN; +char *get_nscategory_entry(const char*,const char*) DECLSPEC_HIDDEN; HRESULT create_pending_window(HTMLOuterWindow*,nsChannelBSC*) DECLSPEC_HIDDEN; HRESULT start_binding(HTMLInnerWindow*,BSCallback*,IBindCtx*) DECLSPEC_HIDDEN; @@ -881,6 +884,10 @@ HRESULT create_element(HTMLDocumentNode*,const WCHAR*,HTMLElement**) DECLSPEC_HI HRESULT HTMLDOMTextNode_Create(HTMLDocumentNode*,nsIDOMNode*,HTMLDOMNode**) DECLSPEC_HIDDEN; +BOOL variant_to_nscolor(const VARIANT *v, nsAString *nsstr) DECLSPEC_HIDDEN; +HRESULT nscolor_to_str(LPCWSTR color, BSTR *ret) DECLSPEC_HIDDEN; + + struct HTMLAttributeCollection { DispatchEx dispex; IHTMLAttributeCollection IHTMLAttributeCollection_iface; @@ -962,6 +969,7 @@ HTMLElement *unsafe_impl_from_IHTMLElement(IHTMLElement*) DECLSPEC_HIDDEN; HRESULT search_window_props(HTMLInnerWindow*,BSTR,DWORD,DISPID*) DECLSPEC_HIDDEN; HRESULT get_frame_by_name(HTMLOuterWindow*,const WCHAR*,BOOL,HTMLOuterWindow**) DECLSPEC_HIDDEN; HRESULT get_doc_elem_by_id(HTMLDocumentNode*,const WCHAR*,HTMLElement**) DECLSPEC_HIDDEN; +HTMLOuterWindow *get_target_window(HTMLOuterWindow*,nsAString*,BOOL*) DECLSPEC_HIDDEN; HRESULT wrap_iface(IUnknown*,IUnknown*,IUnknown**) DECLSPEC_HIDDEN; @@ -986,6 +994,7 @@ void do_ns_command(HTMLDocument*,const char*,nsICommandParams*) DECLSPEC_HIDDEN; void update_doc(HTMLDocument*,DWORD) DECLSPEC_HIDDEN; void update_title(HTMLDocumentObj*) DECLSPEC_HIDDEN; +void set_document_navigation(HTMLDocumentObj*,BOOL) DECLSPEC_HIDDEN; HRESULT do_query_service(IUnknown*,REFGUID,REFIID,void**) DECLSPEC_HIDDEN; diff --git a/dll/win32/mshtml/mutation.c b/dll/win32/mshtml/mutation.c index 0b5be218d1e..dfdc326f5b2 100644 --- a/dll/win32/mshtml/mutation.c +++ b/dll/win32/mshtml/mutation.c @@ -621,7 +621,7 @@ static void NSAPI nsDocumentObserver_BindToDocument(nsIDocumentObserver *iface, nsIDOMElement *nselem; nsresult nsres; - TRACE("(%p)\n", This); + TRACE("(%p)->(%p %p)\n", This, aDocument, aContent); nsres = nsIContent_QueryInterface(aContent, &IID_nsIDOMElement, (void**)&nselem); if(NS_SUCCEEDED(nsres)) { diff --git a/dll/win32/mshtml/navigate.c b/dll/win32/mshtml/navigate.c index 127451a9577..3f278fab586 100644 --- a/dll/win32/mshtml/navigate.c +++ b/dll/win32/mshtml/navigate.c @@ -161,7 +161,7 @@ static nsresult NSAPI nsInputStream_ReadSegments(nsIInputStream *iface, nsres = aWriter(&This->nsIInputStream_iface, aClousure, This->buf, 0, aCount, &written); if(NS_FAILED(nsres)) - TRACE("aWritter failed: %08x\n", nsres); + TRACE("aWriter failed: %08x\n", nsres); else if(written != This->buf_size) FIXME("written %d != buf_size %d\n", written, This->buf_size); @@ -204,6 +204,13 @@ static nsProtocolStream *create_nsprotocol_stream(void) return ret; } +static void release_request_data(request_data_t *request_data) +{ + heap_free(request_data->headers); + if(request_data->post_data) + GlobalFree(request_data->post_data); +} + static inline BSCallback *impl_from_IBindStatusCallback(IBindStatusCallback *iface) { return CONTAINING_RECORD(iface, BSCallback, IBindStatusCallback_iface); @@ -262,15 +269,13 @@ static ULONG WINAPI BindStatusCallback_Release(IBindStatusCallback *iface) TRACE("(%p) ref = %d\n", This, ref); if(!ref) { - if(This->post_data) - GlobalFree(This->post_data); + release_request_data(&This->request_data); if(This->mon) IMoniker_Release(This->mon); if(This->binding) IBinding_Release(This->binding); list_remove(&This->entry); list_init(&This->entry); - heap_free(This->headers); This->vtbl->destroy(This); } @@ -336,6 +341,11 @@ static HRESULT WINAPI BindStatusCallback_OnStopBinding(IBindStatusCallback *ifac This->binding = NULL; } + if(This->mon) { + IMoniker_Release(This->mon); + This->mon = NULL; + } + list_remove(&This->entry); list_init(&This->entry); This->window = NULL; @@ -367,15 +377,15 @@ static HRESULT WINAPI BindStatusCallback_GetBindInfo(IBindStatusCallback *iface, memset(pbindinfo, 0, size); pbindinfo->cbSize = size; - pbindinfo->cbstgmedData = This->post_data_len; + pbindinfo->cbstgmedData = This->request_data.post_data_len; pbindinfo->dwCodePage = CP_UTF8; pbindinfo->dwOptions = 0x80000; - if(This->post_data) { + if(This->request_data.post_data_len) { pbindinfo->dwBindVerb = BINDVERB_POST; pbindinfo->stgmedData.tymed = TYMED_HGLOBAL; - pbindinfo->stgmedData.u.hGlobal = This->post_data; + pbindinfo->stgmedData.u.hGlobal = This->request_data.post_data; pbindinfo->stgmedData.pUnkForRelease = (IUnknown*)&This->IBindStatusCallback_iface; IBindStatusCallback_AddRef(&This->IBindStatusCallback_iface); } @@ -454,14 +464,14 @@ static HRESULT WINAPI HttpNegotiate_BeginningTransaction(IHttpNegotiate2 *iface, if(hres != S_FALSE) return hres; - if(This->headers) { + if(This->request_data.headers) { DWORD size; - size = (strlenW(This->headers)+1)*sizeof(WCHAR); + size = (strlenW(This->request_data.headers)+1)*sizeof(WCHAR); *pszAdditionalHeaders = CoTaskMemAlloc(size); if(!*pszAdditionalHeaders) return E_OUTOFMEMORY; - memcpy(*pszAdditionalHeaders, This->headers, size); + memcpy(*pszAdditionalHeaders, This->request_data.headers, size); } return S_OK; @@ -799,9 +809,6 @@ HRESULT start_binding(HTMLInnerWindow *inner_window, BSCallback *bscallback, IBi if(str) IStream_Release(str); - IMoniker_Release(bscallback->mon); - bscallback->mon = NULL; - return S_OK; } @@ -975,7 +982,8 @@ HRESULT bind_mon_to_wstr(HTMLInnerWindow *window, IMoniker *mon, WCHAR **ret) return S_OK; } -static HRESULT read_post_data_stream(nsChannelBSC *This, nsChannel *nschannel) +static HRESULT read_post_data_stream(nsIInputStream *stream, BOOL contains_headers, struct list *headers_list, + request_data_t *request_data) { UINT64 available = 0; UINT32 data_len = 0; @@ -983,24 +991,24 @@ static HRESULT read_post_data_stream(nsChannelBSC *This, nsChannel *nschannel) nsresult nsres; HRESULT hres = S_OK; - if(!nschannel->post_data_stream) + if(!stream) return S_OK; - nsres = nsIInputStream_Available(nschannel->post_data_stream, &available); + nsres = nsIInputStream_Available(stream, &available); if(NS_FAILED(nsres)) return E_FAIL; - post_data = data = GlobalAlloc(0, available); + post_data = data = GlobalAlloc(0, available+1); if(!data) return E_OUTOFMEMORY; - nsres = nsIInputStream_Read(nschannel->post_data_stream, data, available, &data_len); + nsres = nsIInputStream_Read(stream, data, available, &data_len); if(NS_FAILED(nsres)) { GlobalFree(data); return E_FAIL; } - if(nschannel->post_data_contains_headers) { + if(contains_headers) { if(data_len >= 2 && data[0] == '\r' && data[1] == '\n') { post_data = data+2; data_len -= 2; @@ -1012,21 +1020,23 @@ static HRESULT read_post_data_stream(nsChannelBSC *This, nsChannel *nschannel) post_data += data_len; for(ptr = data; ptr+4 < data+data_len; ptr++) { if(!memcmp(ptr, "\r\n\r\n", 4)) { - post_data = ptr+4; + ptr += 2; + post_data = ptr+2; break; } } data_len -= post_data-data; - size = MultiByteToWideChar(CP_ACP, 0, data, post_data-data, NULL, 0); + size = MultiByteToWideChar(CP_ACP, 0, data, ptr-data, NULL, 0); headers = heap_alloc((size+1)*sizeof(WCHAR)); if(headers) { - MultiByteToWideChar(CP_ACP, 0, data, post_data-data, headers, size); + MultiByteToWideChar(CP_ACP, 0, data, ptr-data, headers, size); headers[size] = 0; - hres = parse_headers(headers , &nschannel->request_headers); + if(headers_list) + hres = parse_headers(headers, headers_list); if(SUCCEEDED(hres)) - This->bsc.headers = headers; + request_data->headers = headers; else heap_free(headers); }else { @@ -1046,7 +1056,7 @@ static HRESULT read_post_data_stream(nsChannelBSC *This, nsChannel *nschannel) }else if(post_data != data) { char *new_data; - new_data = GlobalAlloc(0, data_len); + new_data = GlobalAlloc(0, data_len+1); if(new_data) memcpy(new_data, post_data, data_len); GlobalFree(data); @@ -1055,9 +1065,10 @@ static HRESULT read_post_data_stream(nsChannelBSC *This, nsChannel *nschannel) post_data = new_data; } - This->bsc.post_data = post_data; - This->bsc.post_data_len = data_len; - TRACE("post_data = %s\n", debugstr_a(This->bsc.post_data)); + post_data[data_len] = 0; + request_data->post_data = post_data; + request_data->post_data_len = data_len; + TRACE("post_data = %s\n", debugstr_an(request_data->post_data, request_data->post_data_len)); return S_OK; } @@ -1135,6 +1146,9 @@ static HRESULT read_stream_data(nsChannelBSC *This, IStream *stream) } } + if(!This->nschannel) + return S_OK; + if(!This->nslistener) { BYTE buf[1024]; @@ -1370,10 +1384,12 @@ static HRESULT nsChannelBSC_start_binding(BSCallback *bsc) static HRESULT nsChannelBSC_init_bindinfo(BSCallback *bsc) { nsChannelBSC *This = nsChannelBSC_from_BSCallback(bsc); + nsChannel *nschannel = This->nschannel; HRESULT hres; - if(This->nschannel && This->nschannel->post_data_stream) { - hres = read_post_data_stream(This, This->nschannel); + if(nschannel && nschannel->post_data_stream) { + hres = read_post_data_stream(nschannel->post_data_stream, nschannel->post_data_contains_headers, + &nschannel->request_headers, &This->bsc.request_data); if(FAILED(hres)) return hres; } @@ -1518,7 +1534,7 @@ static HRESULT nsChannelBSC_stop_binding(BSCallback *bsc, HRESULT result) if(result != E_ABORT) { if(FAILED(result)) handle_navigation_error(This, result); - else if(This->is_doc_channel) { + else if(This->is_doc_channel && This->nschannel) { result = async_stop_request(This); if(SUCCEEDED(result)) return S_OK; @@ -1578,12 +1594,121 @@ static HRESULT handle_redirect(nsChannelBSC *This, const WCHAR *new_url) return hres; } +static BOOL is_supported_doc_mime(const WCHAR *mime) +{ + char *nscat, *mimea; + BOOL ret; + + mimea = heap_strdupWtoA(mime); + if(!mimea) + return FALSE; + + nscat = get_nscategory_entry("Gecko-Content-Viewers", mimea); + + ret = nscat != NULL && !strcmp(nscat, "@mozilla.org/content/document-loader-factory;1"); + + heap_free(mimea); + nsfree(nscat); + return ret; +} + +static IUri *get_moniker_uri(IMoniker *mon) +{ + IUriContainer *uri_container; + IUri *ret = NULL; + HRESULT hres; + + hres = IMoniker_QueryInterface(mon, &IID_IUriContainer, (void**)&uri_container); + if(SUCCEEDED(hres)) { + hres = IUriContainer_GetIUri(uri_container, &ret); + IUriContainer_Release(uri_container); + if(FAILED(hres)) + return NULL; + }else { + FIXME("No IUriContainer\n"); + } + + return ret; +} + +static void handle_extern_mime_navigation(nsChannelBSC *This) +{ + IWebBrowserPriv2IE9 *webbrowser_priv; + IOleCommandTarget *cmdtrg; + HTMLDocumentObj *doc_obj; + IBindCtx *bind_ctx; + IUri *uri; + VARIANT flags; + HRESULT hres; + + if(!This->bsc.window || !This->bsc.window->base.outer_window || !This->bsc.window->base.outer_window->doc_obj) + return; + + doc_obj = This->bsc.window->base.outer_window->doc_obj; + + hres = IOleClientSite_QueryInterface(doc_obj->client, &IID_IOleCommandTarget, (void**)&cmdtrg); + if(SUCCEEDED(hres)) { + IOleCommandTarget_Exec(cmdtrg, &CGID_ShellDocView, 62, 0, NULL, NULL); + IOleCommandTarget_Release(cmdtrg); + } + + set_document_navigation(doc_obj, FALSE); + + if(!doc_obj->webbrowser) { + FIXME("unimplemented in non-webbrowser mode\n"); + return; + } + + uri = get_moniker_uri(This->bsc.mon); + if(!uri) + return; + + hres = CreateBindCtx(0, &bind_ctx); + if(FAILED(hres)) { + IUri_Release(uri); + return; + } + + V_VT(&flags) = VT_I4; + V_I4(&flags) = navHyperlink; + + hres = IUnknown_QueryInterface(doc_obj->webbrowser, &IID_IWebBrowserPriv2IE8, (void**)&webbrowser_priv); + if(SUCCEEDED(hres)) { + hres = IWebBrowserPriv2IE9_NavigateWithBindCtx2(webbrowser_priv, uri, &flags, NULL, NULL, NULL, bind_ctx, NULL, 0); + IWebBrowserPriv2IE9_Release(webbrowser_priv); + }else { + IWebBrowserPriv *webbrowser_priv_old; + VARIANT uriv; + + hres = IUnknown_QueryInterface(doc_obj->webbrowser, &IID_IWebBrowserPriv, (void**)&webbrowser_priv_old); + if(SUCCEEDED(hres)) { + V_VT(&uriv) = VT_BSTR; + IUri_GetDisplayUri(uri, &V_BSTR(&uriv)); + + hres = IWebBrowserPriv_NavigateWithBindCtx(webbrowser_priv_old, &uriv, &flags, NULL, NULL, NULL, bind_ctx, NULL); + + SysFreeString(V_BSTR(&uriv)); + IWebBrowserPriv_Release(webbrowser_priv_old); + } + } + + IUri_Release(uri); +} + static HRESULT nsChannelBSC_on_progress(BSCallback *bsc, ULONG status_code, LPCWSTR status_text) { nsChannelBSC *This = nsChannelBSC_from_BSCallback(bsc); switch(status_code) { case BINDSTATUS_MIMETYPEAVAILABLE: + if(This->is_doc_channel && !is_supported_doc_mime(status_text)) { + FIXME("External MIME: %s\n", debugstr_w(status_text)); + + handle_extern_mime_navigation(This); + + This->nschannel = NULL; + } + if(!This->nschannel) return S_OK; @@ -1707,32 +1832,38 @@ HRESULT create_channelbsc(IMoniker *mon, const WCHAR *headers, BYTE *post_data, BOOL is_doc_binding, nsChannelBSC **retval) { nsChannelBSC *ret; + DWORD bindf; ret = heap_alloc_zero(sizeof(*ret)); if(!ret) return E_OUTOFMEMORY; - init_bscallback(&ret->bsc, &nsChannelBSCVtbl, mon, BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA); + bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA; + if(post_data_size) + bindf |= BINDF_FORMS_SUBMIT | BINDF_PRAGMA_NO_CACHE | BINDF_HYPERLINK | BINDF_GETNEWESTVERSION; + + init_bscallback(&ret->bsc, &nsChannelBSCVtbl, mon, bindf); ret->is_doc_channel = is_doc_binding; if(headers) { - ret->bsc.headers = heap_strdupW(headers); - if(!ret->bsc.headers) { + ret->bsc.request_data.headers = heap_strdupW(headers); + if(!ret->bsc.request_data.headers) { IBindStatusCallback_Release(&ret->bsc.IBindStatusCallback_iface); return E_OUTOFMEMORY; } } if(post_data) { - ret->bsc.post_data = GlobalAlloc(0, post_data_size); - if(!ret->bsc.post_data) { - heap_free(ret->bsc.headers); + ret->bsc.request_data.post_data = GlobalAlloc(0, post_data_size+1); + if(!ret->bsc.request_data.post_data) { + release_request_data(&ret->bsc.request_data); IBindStatusCallback_Release(&ret->bsc.IBindStatusCallback_iface); return E_OUTOFMEMORY; } - memcpy(ret->bsc.post_data, post_data, post_data_size); - ret->bsc.post_data_len = post_data_size; + memcpy(ret->bsc.request_data.post_data, post_data, post_data_size); + ((BYTE*)ret->bsc.request_data.post_data)[post_data_size] = 0; + ret->bsc.request_data.post_data_len = post_data_size; } TRACE("created %p\n", ret); @@ -1815,7 +1946,7 @@ void abort_window_bindings(HTMLInnerWindow *window) } } -HRESULT channelbsc_load_stream(HTMLInnerWindow *pending_window, IStream *stream) +HRESULT channelbsc_load_stream(HTMLInnerWindow *pending_window, IMoniker *mon, IStream *stream) { nsChannelBSC *bscallback = pending_window->bscallback; HRESULT hres = S_OK; @@ -1829,6 +1960,8 @@ HRESULT channelbsc_load_stream(HTMLInnerWindow *pending_window, IStream *stream) if(!bscallback->nschannel->content_type) return E_OUTOFMEMORY; + set_current_mon(pending_window->base.outer_window, mon, 0); + bscallback->bsc.window = pending_window; if(stream) hres = read_stream_data(bscallback, stream); @@ -1854,12 +1987,12 @@ void channelbsc_set_channel(nsChannelBSC *This, nsChannel *channel, nsIStreamLis This->nscontext = context; } - if(This->bsc.headers) { + if(This->bsc.request_data.headers) { HRESULT hres; - hres = parse_headers(This->bsc.headers, &channel->request_headers); - heap_free(This->bsc.headers); - This->bsc.headers = NULL; + hres = parse_headers(This->bsc.request_data.headers, &channel->request_headers); + heap_free(This->bsc.request_data.headers); + This->bsc.request_data.headers = NULL; if(FAILED(hres)) WARN("parse_headers failed: %08x\n", hres); } @@ -2053,7 +2186,7 @@ HRESULT super_navigate(HTMLOuterWindow *window, IUri *uri, DWORD flags, const WC } } - if(!(flags & BINDING_REFRESH) && window->uri_nofrag && !post_data_size) { + if(!(flags & BINDING_NOFRAG) && window->uri_nofrag && !post_data_size) { BOOL eq; hres = IUri_IsEqual(uri_nofrag, window->uri_nofrag, &eq); @@ -2081,7 +2214,32 @@ HRESULT super_navigate(HTMLOuterWindow *window, IUri *uri, DWORD flags, const WC prepare_for_binding(&window->doc_obj->basedoc, mon, flags); hres = IUri_GetScheme(uri, &scheme); - if(SUCCEEDED(hres) && scheme != URL_SCHEME_JAVASCRIPT) { + if(SUCCEEDED(hres) && scheme == URL_SCHEME_JAVASCRIPT) { + navigate_javascript_task_t *task; + + IBindStatusCallback_Release(&bsc->bsc.IBindStatusCallback_iface); + IMoniker_Release(mon); + + task = heap_alloc(sizeof(*task)); + if(!task) + return E_OUTOFMEMORY; + + /* Why silently? */ + window->readystate = READYSTATE_COMPLETE; + if(!(flags & BINDING_FROMHIST)) + call_docview_84(window->doc_obj); + + IUri_AddRef(uri); + task->window = window; + task->uri = uri; + hres = push_task(&task->header, navigate_javascript_proc, navigate_javascript_task_destr, window->task_magic); + }else if(flags & BINDING_SUBMIT) { + hres = set_moniker(window, mon, uri, NULL, bsc, TRUE); + if(SUCCEEDED(hres)) + hres = start_binding(window->pending_window, &bsc->bsc, NULL); + IBindStatusCallback_Release(&bsc->bsc.IBindStatusCallback_iface); + IMoniker_Release(mon); + }else { navigate_task_t *task; task = heap_alloc(sizeof(*task)); @@ -2104,25 +2262,6 @@ HRESULT super_navigate(HTMLOuterWindow *window, IUri *uri, DWORD flags, const WC IUri_AddRef(uri); task->uri = uri; hres = push_task(&task->header, navigate_proc, navigate_task_destr, window->task_magic); - }else { - navigate_javascript_task_t *task; - - IBindStatusCallback_Release(&bsc->bsc.IBindStatusCallback_iface); - IMoniker_Release(mon); - - task = heap_alloc(sizeof(*task)); - if(!task) - return E_OUTOFMEMORY; - - /* Why silently? */ - window->readystate = READYSTATE_COMPLETE; - if(!(flags & BINDING_FROMHIST)) - call_docview_84(window->doc_obj); - - IUri_AddRef(uri); - task->window = window; - task->uri = uri; - hres = push_task(&task->header, navigate_javascript_proc, navigate_javascript_task_destr, window->task_magic); } return hres; @@ -2207,7 +2346,8 @@ HRESULT hlink_frame_navigate(HTMLDocument *doc, LPCWSTR url, nsChannel *nschanne } if(nschannel) - read_post_data_stream(callback, nschannel); + read_post_data_stream(nschannel->post_data_stream, nschannel->post_data_contains_headers, + &nschannel->request_headers, &callback->bsc.request_data); hres = CreateAsyncBindCtx(0, &callback->bsc.IBindStatusCallback_iface, NULL, &bindctx); if(SUCCEEDED(hres)) @@ -2238,7 +2378,8 @@ HRESULT hlink_frame_navigate(HTMLDocument *doc, LPCWSTR url, nsChannel *nschanne return hres; } -static HRESULT navigate_uri(HTMLOuterWindow *window, IUri *uri, const WCHAR *display_uri, DWORD flags) +static HRESULT navigate_uri(HTMLOuterWindow *window, IUri *uri, const WCHAR *display_uri, const request_data_t *request_data, + DWORD flags) { nsWineURI *nsuri; HRESULT hres; @@ -2246,18 +2387,22 @@ static HRESULT navigate_uri(HTMLOuterWindow *window, IUri *uri, const WCHAR *dis TRACE("%s\n", debugstr_w(display_uri)); if(window->doc_obj && window->doc_obj->webbrowser && window == window->doc_obj->basedoc.window) { + DWORD post_data_len = request_data ? request_data->post_data_len : 0; + void *post_data = post_data_len ? request_data->post_data : NULL; + const WCHAR *headers = request_data ? request_data->headers : NULL; + if(!(flags & BINDING_REFRESH)) { BOOL cancel = FALSE; hres = IDocObjectService_FireBeforeNavigate2(window->doc_obj->doc_object_service, NULL, display_uri, 0x40, - NULL, NULL, 0, NULL, TRUE, &cancel); + NULL, post_data, post_data_len ? post_data_len+1 : 0, headers, TRUE, &cancel); if(SUCCEEDED(hres) && cancel) { TRACE("Navigation canceled\n"); return S_OK; } } - return super_navigate(window, uri, flags, NULL, NULL, 0); + return super_navigate(window, uri, flags, headers, post_data, post_data_len); } if(window->doc_obj && window == window->doc_obj->basedoc.window) { @@ -2291,31 +2436,21 @@ HRESULT load_uri(HTMLOuterWindow *window, IUri *uri, DWORD flags) if(FAILED(hres)) return hres; - hres = navigate_uri(window, uri, display_uri, flags); + hres = navigate_uri(window, uri, display_uri, NULL, flags); SysFreeString(display_uri); return hres; } -HRESULT navigate_url(HTMLOuterWindow *window, const WCHAR *new_url, IUri *base_uri, DWORD flags) +static HRESULT translate_uri(HTMLOuterWindow *window, IUri *orig_uri, BSTR *ret_display_uri, IUri **ret_uri) { + IUri *uri = NULL; BSTR display_uri; - IUri *uri; HRESULT hres; - if(new_url && base_uri) - hres = CoInternetCombineUrlEx(base_uri, new_url, URL_ESCAPE_SPACES_ONLY|URL_DONT_ESCAPE_EXTRA_INFO, - &uri, 0); - else - hres = create_uri(new_url, 0, &uri); + hres = IUri_GetDisplayUri(orig_uri, &display_uri); if(FAILED(hres)) return hres; - hres = IUri_GetDisplayUri(uri, &display_uri); - if(FAILED(hres)) { - IUri_Release(uri); - return hres; - } - if(window->doc_obj && window->doc_obj->hostui) { OLECHAR *translated_url = NULL; @@ -2324,7 +2459,6 @@ HRESULT navigate_url(HTMLOuterWindow *window, const WCHAR *new_url, IUri *base_u if(hres == S_OK) { TRACE("%08x %s -> %s\n", hres, debugstr_w(display_uri), debugstr_w(translated_url)); SysFreeString(display_uri); - IUri_Release(uri); hres = create_uri(translated_url, 0, &uri); CoTaskMemFree(translated_url); if(FAILED(hres)) @@ -2338,8 +2472,57 @@ HRESULT navigate_url(HTMLOuterWindow *window, const WCHAR *new_url, IUri *base_u } } - hres = navigate_uri(window, uri, display_uri, flags); + if(!uri) { + IUri_AddRef(orig_uri); + uri = orig_uri; + } + *ret_display_uri = display_uri; + *ret_uri = uri; + return S_OK; +} + +HRESULT submit_form(HTMLOuterWindow *window, IUri *submit_uri, nsIInputStream *post_stream) +{ + request_data_t request_data = {NULL}; + BSTR display_uri; + IUri *uri; + HRESULT hres; + + hres = read_post_data_stream(post_stream, TRUE, NULL, &request_data); + if(FAILED(hres)) + return hres; + + hres = translate_uri(window, submit_uri, &display_uri, &uri); + if(SUCCEEDED(hres)) { + hres = navigate_uri(window, uri, display_uri, &request_data, BINDING_NAVIGATED|BINDING_SUBMIT); + IUri_Release(uri); + SysFreeString(display_uri); + } + release_request_data(&request_data); + return hres; +} + +HRESULT navigate_url(HTMLOuterWindow *window, const WCHAR *new_url, IUri *base_uri, DWORD flags) +{ + IUri *uri, *nav_uri; + BSTR display_uri; + HRESULT hres; + + if(new_url && base_uri) + hres = CoInternetCombineUrlEx(base_uri, new_url, URL_ESCAPE_SPACES_ONLY|URL_DONT_ESCAPE_EXTRA_INFO, + &nav_uri, 0); + else + hres = create_uri(new_url, 0, &nav_uri); + if(FAILED(hres)) + return hres; + + hres = translate_uri(window, nav_uri, &display_uri, &uri); + IUri_Release(nav_uri); + if(FAILED(hres)) + return hres; + + hres = navigate_uri(window, uri, display_uri, NULL, flags); IUri_Release(uri); SysFreeString(display_uri); return hres; diff --git a/dll/win32/mshtml/npplugin.c b/dll/win32/mshtml/npplugin.c index e4c777a70ce..5e7a16b88c9 100644 --- a/dll/win32/mshtml/npplugin.c +++ b/dll/win32/mshtml/npplugin.c @@ -292,7 +292,7 @@ static BOOL get_elem_clsid(nsIDOMElement *elem, CLSID *clsid) ERR("GetAttribute failed: %08x\n", nsres); } - nsAString_Finish(&attr_str); + nsAString_Finish(&val_str); return ret; } @@ -540,7 +540,7 @@ static void check_codebase(HTMLInnerWindow *window, nsIDOMElement *nselem) ERR("GetAttribute failed: %08x\n", nsres); } - nsAString_Finish(&attr_str); + nsAString_Finish(&val_str); if(!uri) return; @@ -618,6 +618,7 @@ static IUnknown *create_activex_object(HTMLInnerWindow *window, nsIDOMElement *n } hres = IClassFactory_CreateInstance(cf, NULL, &IID_IUnknown, (void**)&obj); + IClassFactory_Release(cf); if(FAILED(hres)) return NULL; @@ -654,7 +655,6 @@ static NPError CDECL NPP_New(NPMIMEType pluginType, NPP instance, UINT16 mode, I HRESULT hres; hres = create_plugin_host(window->doc, nselem, obj, &clsid, &host); - nsIDOMElement_Release(nselem); IUnknown_Release(obj); if(SUCCEEDED(hres)) instance->pdata = host; diff --git a/dll/win32/mshtml/nsembed.c b/dll/win32/mshtml/nsembed.c index f9652e9118e..b8de1a4caa7 100644 --- a/dll/win32/mshtml/nsembed.c +++ b/dll/win32/mshtml/nsembed.c @@ -31,6 +31,7 @@ WINE_DECLARE_DEBUG_CHANNEL(gecko); #define NS_EDITORCONTROLLER_CONTRACTID "@mozilla.org/editor/editorcontroller;1" #define NS_PREFERENCES_CONTRACTID "@mozilla.org/preferences;1" #define NS_VARIANT_CONTRACTID "@mozilla.org/variant;1" +#define NS_CATEGORYMANAGER_CONTRACTID "@mozilla.org/categorymanager;1" #define PR_UINT32_MAX 0xffffffff @@ -56,6 +57,7 @@ static HINSTANCE xul_handle = NULL; static nsIServiceManager *pServMgr = NULL; static nsIComponentManager *pCompMgr = NULL; +static nsICategoryManager *cat_mgr; static nsIMemory *nsmem = NULL; static nsIFile *profile_directory, *plugin_directory; @@ -471,7 +473,7 @@ static BOOL load_xul(const PRUnichar *gre_path) } #define NS_DLSYM(func) \ - func = (void *)GetProcAddress(xul_handle, #func "_P"); \ + func = (void *)GetProcAddress(xul_handle, #func); \ if(!func) \ ERR("Could not GetProcAddress(" #func ") failed\n") @@ -710,6 +712,11 @@ static BOOL init_xpcom(const PRUnichar *gre_path) if(NS_FAILED(nsres)) ERR("Could not get nsIMemory: %08x\n", nsres); + nsres = nsIServiceManager_GetServiceByContractID(pServMgr, NS_CATEGORYMANAGER_CONTRACTID, + &IID_nsICategoryManager, (void**)&cat_mgr); + if(NS_FAILED(nsres)) + ERR("Could not get category manager service: %08x\n", nsres); + if(registrar) { register_nsservice(registrar, pServMgr); nsIComponentRegistrar_Release(registrar); @@ -890,6 +897,15 @@ nsIWritableVariant *create_nsvariant(void) return ret; } +char *get_nscategory_entry(const char *category, const char *entry) +{ + char *ret = NULL; + nsresult nsres; + + nsres = nsICategoryManager_GetCategoryEntry(cat_mgr, category, entry, &ret); + return NS_SUCCEEDED(nsres) ? ret : NULL; +} + nsresult get_nsinterface(nsISupports *iface, REFIID riid, void **ppv) { nsIInterfaceRequestor *iface_req; @@ -1082,6 +1098,9 @@ void close_gecko(void) if(pServMgr) nsIServiceManager_Release(pServMgr); + if(cat_mgr) + nsICategoryManager_Release(cat_mgr); + if(nsmem) nsIMemory_Release(nsmem); diff --git a/dll/win32/mshtml/nsiface.idl b/dll/win32/mshtml/nsiface.idl index fcdf6f16cfb..c0959f52768 100644 --- a/dll/win32/mshtml/nsiface.idl +++ b/dll/win32/mshtml/nsiface.idl @@ -23,7 +23,7 @@ * compatible with XPCOM, usable in C code. */ -cpp_quote("#define GECKO_VERSION \"2.21\"") +cpp_quote("#define GECKO_VERSION \"2.24\"") cpp_quote("#define GECKO_VERSION_STRING \"Wine Gecko \" GECKO_VERSION") import "wtypes.idl"; @@ -86,6 +86,7 @@ typedef nsStringContainer nsAString; interface nsIWebBrowserChrome; interface nsILoadGroup; interface nsIDOMNode; +interface nsIDOMAttr; interface nsIDOMDocument; interface nsIDOMEvent; interface nsIEditor; @@ -124,7 +125,6 @@ interface nsISupports /* Currently we don't need a full declaration of these interfaces */ typedef nsISupports nsISHistory; typedef nsISupports nsIWidget; -typedef nsISupports nsIDOMBarProp; typedef nsISupports nsIPrompt; typedef nsISupports nsIAuthPrompt; typedef nsISupports nsIDOMDocumentType; @@ -622,7 +622,7 @@ interface nsIHttpChannel : nsIChannel [ object, - uuid(74d13d41-85cd-490f-9942-300d0c01c726), + uuid(2cd7f6a6-63f3-4bd6-a0f5-6e3d6dcff81b), local ] interface nsIHttpChannelInternal : nsISupports @@ -831,24 +831,24 @@ interface nsIDOMHTMLCollection : nsISupports [ object, - uuid(a6cf907b-15b3-11d2-932e-00805f8add32), + uuid(cb5564cd-26ec-418f-a6d6-1d57cd2c971c), local ] -interface nsIDOMNamedNodeMap : nsISupports +interface nsIDOMMozNamedAttrMap : nsISupports { - nsresult GetNamedItem(const nsAString *name, nsIDOMNode **_retval); - nsresult SetNamedItem(nsIDOMNode *arg, nsIDOMNode **_retval); - nsresult RemoveNamedItem(const nsAString *name, nsIDOMNode **_retval); - nsresult Item(uint32_t index, nsIDOMNode **_retval); + nsresult GetNamedItem(const nsAString *name, nsIDOMAttr **_retval); + nsresult SetNamedItem(nsIDOMAttr *arg, nsIDOMAttr **_retval); + nsresult RemoveNamedItem(const nsAString *name, nsIDOMAttr **_retval); + nsresult Item(uint32_t index, nsIDOMAttr **_retval); nsresult GetLength(uint32_t *aLength); - nsresult GetNamedItemNS(const nsAString *namespaceURI, const nsAString *localName, nsIDOMNode **_retval); - nsresult SetNamedItemNS(nsIDOMNode *arg, nsIDOMNode **_retval); - nsresult RemoveNamedItemNS(const nsAString *namespaceURI, const nsAString *localName, nsIDOMNode **_retval); + nsresult GetNamedItemNS(const nsAString *namespaceURI, const nsAString *localName, nsIDOMAttr **_retval); + nsresult SetNamedItemNS(nsIDOMAttr *arg, nsIDOMAttr **_retval); + nsresult RemoveNamedItemNS(const nsAString *namespaceURI, const nsAString *localName, nsIDOMAttr **_retval); } [ object, - uuid(5e9bcec9-5928-4f77-8a9c-424ef01c20e1), + uuid(56545150-a001-484e-9ed4-cb319eebd7b3), local ] interface nsIDOMNode : nsISupports @@ -888,7 +888,6 @@ interface nsIDOMNode : nsISupports nsresult GetLastChild(nsIDOMNode **aLastChild); nsresult GetPreviousSibling(nsIDOMNode **aPreviousSibling); nsresult GetNextSibling(nsIDOMNode **aNextSibling); - nsresult GetAttributes(nsIDOMNamedNodeMap **aAttributes); nsresult GetOwnerDocument(nsIDOMDocument **aOwnerDocument); nsresult InsertBefore(nsIDOMNode *newChild, nsIDOMNode *refChild, nsIDOMNode **_retval); nsresult ReplaceChild(nsIDOMNode *newChild, nsIDOMNode *oldChild, nsIDOMNode **_retval); @@ -897,7 +896,6 @@ interface nsIDOMNode : nsISupports nsresult HasChildNodes(bool *_retval); nsresult CloneNode(bool deep, uint8_t _argc, nsIDOMNode **_retval); nsresult Normalize(); - nsresult IsSupported(const nsAString *feature, const nsAString *version, bool *_retval); nsresult GetNamespaceURI(nsAString *aNamespaceURI); nsresult GetPrefix(nsAString *aPrefix); nsresult GetLocalName(nsAString *aLocalName); @@ -920,7 +918,7 @@ interface nsIDOMNode : nsISupports [ object, - uuid(03da4bc9-1b9a-41dc-a1a4-32414d48d704), + uuid(a974a4d3-2ff1-445b-8b8e-0aada5d4eedc), local ] interface nsIDOMAttr : nsIDOMNode @@ -950,13 +948,14 @@ interface nsIDOMClientRect : nsISupports [ object, - uuid(8f972a47-1f20-4906-b59d-19310349a2c2), + uuid(43d985da-b7ee-4d1f-a26f-348ccd9506f3), local ] interface nsIDOMElement : nsIDOMNode { nsresult GetTagName(nsAString *aTagName); nsresult GetClassList(nsISupports **aClassList); + nsresult GetAttributes(nsIDOMMozNamedAttrMap **aAttributes); nsresult GetAttribute(const nsAString *name, nsAString *_retval); nsresult GetAttributeNS(const nsAString *namespaceURI, const nsAString *localName, nsAString *_retval); nsresult SetAttribute(const nsAString *name, const nsAString *value); @@ -979,6 +978,7 @@ interface nsIDOMElement : nsIDOMNode nsresult GetPreviousElementSibling(nsIDOMElement **aPreviousElementSibling); nsresult GetNextElementSibling(nsIDOMElement **aNextElementSibling); nsresult GetChildElementCount(uint32_t *aChildElementCount); + nsresult Remove(); nsresult GetOnmouseenter(JSContext *cx, jsval *aOnmouseenter); nsresult SetOnmouseenter(JSContext *cx, const jsval *aOnmouseenter); nsresult GetOnmouseleave(JSContext *cx, jsval *aOnmouseleave); @@ -1018,7 +1018,7 @@ cpp_quote("#undef GetClassName") [ object, - uuid(9a677a5b-e6f7-4e2e-9ef9-22c2ac9967b3), + uuid(e29ddc73-ac40-40fe-8bbd-14bf2d52c53a), local ] interface nsIDOMHTMLElement : nsIDOMElement @@ -1080,7 +1080,7 @@ interface nsIDOMHTMLElement : nsIDOMElement [ object, - uuid(8b38545f-7fa5-47d5-a902-c8ea8e78fb0d), + uuid(889602bb-4681-4b01-8582-4fad1fbb8325), local ] interface nsIDOMHTMLHeadElement : nsIDOMHTMLElement @@ -1089,7 +1089,7 @@ interface nsIDOMHTMLHeadElement : nsIDOMHTMLElement [ object, - uuid(cb75c251-afc7-444f-b2d6-b9635555f3ed), + uuid(84f72a38-1873-46f8-937c-1df22d7e7cae), local ] interface nsIDOMCharacterData : nsIDOMNode @@ -1102,11 +1102,12 @@ interface nsIDOMCharacterData : nsIDOMNode nsresult InsertData(uint32_t offset, const nsAString *arg); nsresult DeleteData(uint32_t offset, uint32_t count); nsresult ReplaceData(uint32_t offset, uint32_t count, const nsAString *arg); + nsresult Remove(); } [ object, - uuid(437ed60c-febd-4bd0-892f-cf358adc3c96), + uuid(d14d13b4-21d5-49e2-8d59-76a24156db54), local ] interface nsIDOMText : nsIDOMCharacterData @@ -1117,7 +1118,7 @@ interface nsIDOMText : nsIDOMCharacterData [ object, - uuid(cea49a35-dac9-4c4d-9830-4660abb3b6bc), + uuid(e702a5d2-3aa8-4788-b048-2d3b3e6d16f2), local ] interface nsIDOMComment : nsIDOMCharacterData @@ -1126,7 +1127,7 @@ interface nsIDOMComment : nsIDOMCharacterData [ object, - uuid(4a15eb0c-d5bc-4902-9d50-21b12cab47e7), + uuid(33127aed-9d6a-4b0d-95aa-0529f51bcb9c), local ] interface nsIDOMDocumentFragment : nsIDOMNode @@ -1135,7 +1136,7 @@ interface nsIDOMDocumentFragment : nsIDOMNode [ object, - uuid(9b93f82b-9691-4021-8f45-1bf505db77ba), + uuid(75996de6-6b0f-43e5-ae79-c98fa669da9a), local ] interface nsIDOMDocument : nsIDOMNode @@ -1215,7 +1216,7 @@ interface nsIDOMDocument : nsIDOMNode [ object, - uuid(3f8666a9-76f0-4733-ae11-4aea8753062d), + uuid(fd76e045-8d97-4a97-ad75-eac5ae2f3ea4), local ] interface nsIDOMHTMLDocument : nsIDOMDocument @@ -1359,7 +1360,7 @@ interface nsIDOMWindowCollection : nsISupports [ object, - uuid(39cb59d4-fba9-48a9-b70b-570a7ec2ebfa), + uuid(be62660a-e3f6-409c-a4a9-378364a9526f), local ] interface nsIDOMWindow : nsISupports @@ -1371,12 +1372,12 @@ interface nsIDOMWindow : nsISupports nsresult SetName(const nsAString *aName); nsresult GetLocation(nsIDOMLocation **aLocation); nsresult GetHistory(nsIDOMHistory **aHistory); - nsresult GetLocationbar(nsIDOMBarProp **aLocationbar); - nsresult GetMenubar(nsIDOMBarProp **aMenubar); - nsresult GetPersonalbar(nsIDOMBarProp **aPersonalbar); - nsresult GetScrollbars(nsIDOMBarProp **aScrollbars); - nsresult GetStatusbar(nsIDOMBarProp **aStatusbar); - nsresult GetToolbar(nsIDOMBarProp **aToolbar); + nsresult GetLocationbar(nsISupports **aLocationbar); + nsresult GetMenubar(nsISupports **aMenubar); + nsresult GetPersonalbar(nsISupports **aPersonalbar); + nsresult GetScrollbars(nsISupports **aScrollbars); + nsresult GetStatusbar(nsISupports **aStatusbar); + nsresult GetToolbar(nsISupports **aToolbar); nsresult GetStatus(nsAString *aStatus); nsresult SetStatus(const nsAString *aStatus); nsresult Close(); @@ -1398,7 +1399,7 @@ interface nsIDOMWindow : nsISupports nsresult Confirm(const nsAString *text, bool *_retval); nsresult Prompt(const nsAString *aMessage, const nsAString *aInitial, nsAString *_retval); nsresult Print(); - nsresult ShowModalDialog(const nsAString *aURI, nsIVariant *aArgs, const nsAString *aOptions, nsIVariant **_retval); + nsresult ShowModalDialog(const nsAString *aURI, nsIVariant *aArgs, const nsAString *aOptions, uint8_t _argc, nsIVariant **_retval); nsresult PostMessageMoz(const long /*jsval*/ *message, const nsAString *targetOrigin, const /*JS::Value*/ void *transfer, JSContext *cx); nsresult Atob(const nsAString *aAsciiString, nsAString *_retval); nsresult Btoa(const nsAString *aBase64Data, nsAString *_retval); @@ -1441,8 +1442,6 @@ interface nsIDOMWindow : nsISupports nsresult GetCrypto(nsIDOMCrypto **aCrypto); nsresult GetPkcs11(nsIDOMPkcs11 **aPkcs11); nsresult GetControllers(nsIControllers **aControllers); - nsresult GetDefaultStatus(nsAString *aDefaultStatus); - nsresult SetDefaultStatus(const nsAString *aDefaultStatus); nsresult GetMozInnerScreenX(float *aMozInnerScreenX); nsresult GetMozInnerScreenY(float *aMozInnerScreenY); nsresult GetDevicePixelRatio(float *aDevicePixelRatio); @@ -1465,8 +1464,10 @@ interface nsIDOMWindow : nsISupports bool searchInFrames, bool showDialog, bool *_retval); nsresult GetMozPaintCount(uint64_t *aMozPaintCount); nsresult MozRequestAnimationFrame(nsIFrameRequestCallback *aCallback, int32_t *_retval); + nsresult RequestAnimationFrame(void /*const JS::Value*/ *aCallback, JSContext* cx, int32_t *_retval); nsresult MozCancelAnimationFrame(int32_t aHandle); nsresult MozCancelRequestAnimationFrame(int32_t aHandle); + nsresult CancelAnimationFrame(int32_t aHandle); nsresult GetMozAnimationStartTime(int64_t *aMozAnimationStartTime); nsresult GetOnafterprint(JSContext *cx, jsval *aOnafterprint); nsresult SetOnafterprint(JSContext *cx, const jsval *aOnafterprint); @@ -1510,7 +1511,7 @@ interface nsIDOMWindow : nsISupports [ object, - uuid(d8f00c8b-d317-4df2-a9bf-4a1e6f19f945), + uuid(8b29a62f-b448-49f3-9242-241d5cf94ea9), local ] interface nsIDOMHTMLBodyElement : nsIDOMHTMLElement @@ -1555,7 +1556,7 @@ interface nsIDOMHTMLBodyElement : nsIDOMHTMLElement [ object, - uuid(59c0dc07-d784-410b-8b5e-c26baf7cb8a6), + uuid(5e49bff8-fb61-41e3-b6a9-2017865a6d74), local ] interface nsIDOMHTMLFormElement : nsIDOMHTMLElement @@ -1583,11 +1584,12 @@ interface nsIDOMHTMLFormElement : nsIDOMHTMLElement nsresult Submit(); nsresult Reset(); nsresult CheckValidity(bool *_retval); + nsresult GetFormData(nsIDOMHTMLElement *aOriginatingElement, nsAString *aActionURI, nsIInputStream **aPostDataStream); } [ object, - uuid(83984fd0-b0b2-11e1-afa6-0800200c9a66), + uuid(d57537ed-39d0-46ea-8516-0ce0a5bfb805), local ] interface nsIDOMHTMLInputElement : nsIDOMHTMLElement @@ -1622,8 +1624,8 @@ interface nsIDOMHTMLInputElement : nsIDOMHTMLElement nsresult SetHeight(uint32_t aHeight); nsresult GetIndeterminate(bool *aIndeterminate); nsresult SetIndeterminate(bool aIndeterminate); - nsresult GetInputmode(nsAString *aInputmode); - nsresult SetInputmode(const nsAString *aInputmode); + nsresult GetInputMode(nsAString *aInputMode); + nsresult SetInputMode(const nsAString *aInputMode); nsresult GetList(nsIDOMHTMLElement **aList); nsresult GetMax(nsAString *aMax); nsresult SetMax(const nsAString *aMax); @@ -1661,8 +1663,6 @@ interface nsIDOMHTMLInputElement : nsIDOMHTMLElement nsresult SetValue(const nsAString *aValue); nsresult GetValueAsNumber(double *aValueAsNumber); nsresult SetValueAsNumber(double aValueAsNumber); - nsresult GetValueAsDate(JSContext* cx, /*JS::Value*/ void *aValueAsDate); - nsresult SetValueAsDate(JSContext* cx, const /*JS::Value*/ void *aValueAsDate); nsresult StepDown(int32_t n, uint8_t _argc); nsresult StepUp(int32_t n, uint8_t _argc); nsresult GetWillValidate(bool *aWillValidate); @@ -1689,7 +1689,7 @@ interface nsIDOMHTMLInputElement : nsIDOMHTMLElement [ object, - uuid(68a5d794-39bf-4b00-aefe-754b9e8f7ec6), + uuid(09017cf4-0004-4c27-a340-7f5d2fe282e3), local ] interface nsIDOMHTMLOptionElement : nsIDOMHTMLElement @@ -1712,7 +1712,7 @@ interface nsIDOMHTMLOptionElement : nsIDOMHTMLElement [ object, - uuid(8e40d4d7-c204-4192-802a-0b5602e9c669), + uuid(5564816e-2ab5-46ee-95a4-8f4688bdb449), local ] interface nsIDOMHTMLButtonElement : nsIDOMHTMLElement @@ -1768,7 +1768,7 @@ interface nsIDOMHTMLOptionsCollection : nsISupports [ object, - uuid(e85194cf-56e6-44a6-92d9-0096c9d2536e), + uuid(8af2123f-c83a-430a-a739-d103a8eaba52), local ] interface nsIDOMHTMLSelectElement : nsIDOMHTMLElement @@ -1807,7 +1807,7 @@ interface nsIDOMHTMLSelectElement : nsIDOMHTMLElement [ object, - uuid(2a395065-2d92-48c1-ac00-643de9ca681b), + uuid(b7e1b86f-c98e-4658-81ce-ac29962f854a), local ] interface nsIDOMHTMLTextAreaElement : nsIDOMHTMLElement @@ -1857,7 +1857,7 @@ interface nsIDOMHTMLTextAreaElement : nsIDOMHTMLElement [ object, - uuid(e2f548f6-9955-4820-a9e6-3a9fd43c7111), + uuid(8783371a-6185-4176-9ed9-f781c75bf48a), local ] interface nsIDOMHTMLScriptElement : nsIDOMHTMLElement @@ -1884,7 +1884,7 @@ interface nsIDOMHTMLScriptElement : nsIDOMHTMLElement [ object, - uuid(76cf0381-19fd-442d-bb18-c794fd8b5c25), + uuid(98c38ca0-5e3a-4c71-90a4-69d12a3c8d16), local ] interface nsIDOMHTMLImageElement : nsIDOMHTMLElement @@ -1926,7 +1926,7 @@ interface nsIDOMHTMLImageElement : nsIDOMHTMLElement [ object, - uuid(1339c36e-23ad-4047-a04c-1702e27c7c83), + uuid(76ec122a-db6d-4b3f-8a24-15faf117f695), local ] interface nsIDOMHTMLAnchorElement : nsIDOMHTMLElement @@ -1976,7 +1976,7 @@ interface nsIDOMHTMLAnchorElement : nsIDOMHTMLElement [ object, - uuid(5b639ece-7b49-4507-9d38-550beb71955b), + uuid(ad43cb9b-3253-446d-8ba9-50ee50ff017e), local ] interface nsIDOMHTMLLinkElement : nsIDOMHTMLElement @@ -2005,7 +2005,7 @@ interface nsIDOMHTMLLinkElement : nsIDOMHTMLElement [ object, - uuid(ae50de74-bc26-402e-85dc-a980f506b655), + uuid(1a7bf1f1-5d6c-4200-9ceb-455874322315), local ] interface nsIDOMHTMLTableElement : nsIDOMHTMLElement @@ -2048,7 +2048,7 @@ interface nsIDOMHTMLTableElement : nsIDOMHTMLElement [ object, - uuid(0ac4a382-4f97-4143-a3b3-de0a54978c67), + uuid(02094366-0d3d-47e3-949c-89113a9bcc15), local ] interface nsIDOMHTMLTableRowElement : nsIDOMHTMLElement @@ -2072,7 +2072,7 @@ interface nsIDOMHTMLTableRowElement : nsIDOMHTMLElement [ object, - uuid(a7bd1e34-3969-47ae-8c1d-2970132ba925), + uuid(21ffbe98-51f5-499e-8d6f-612ae798c1e1), local ] interface nsIDOMHTMLIFrameElement : nsIDOMHTMLElement @@ -2101,13 +2101,13 @@ interface nsIDOMHTMLIFrameElement : nsIDOMHTMLElement nsresult GetContentWindow(nsIDOMWindow **aContentWindow); nsresult GetSandbox(nsAString *aSandbox); nsresult SetSandbox(const nsAString *aSandbox); - nsresult GetAllowFullScreen(bool *aAllowFullScreen); - nsresult SetAllowFullScreen(bool aAllowFullScreen); + nsresult GetAllowFullscreen(bool *aAllowFullscreen); + nsresult SetAllowFullscreen(bool aAllowFullscreen); } [ object, - uuid(2aa7855a-0667-47c3-af1e-9101002816c1), + uuid(1a79af54-dbbb-4532-be48-944f3995e7e9), local ] interface nsIDOMHTMLFrameElement : nsIDOMHTMLElement @@ -2134,7 +2134,7 @@ interface nsIDOMHTMLFrameElement : nsIDOMHTMLElement [ object, - uuid(a70595dd-68a5-41f5-ab52-73a47d98bd78), + uuid(bed8f222-c4dd-41ba-9ec6-dfae0ec8def8), local ] interface nsIDOMHTMLObjectElement : nsIDOMHTMLElement @@ -2182,7 +2182,7 @@ interface nsIDOMHTMLObjectElement : nsIDOMHTMLElement [ object, - uuid(1fbec0f8-c7cF-4dc8-84be-247985a65e07), + uuid(f85e1b05-6dc4-442d-bea8-7cf551f9bc9f), local ] interface nsIDOMHTMLParamElement : nsIDOMHTMLElement @@ -2199,7 +2199,7 @@ interface nsIDOMHTMLParamElement : nsIDOMHTMLElement [ object, - uuid(f9db1001-faae-46e1-b85f-0a0afb80c5b2), + uuid(e81273e1-d440-4dd3-9073-8199f7a9525e), local ] interface nsIDOMHTMLStyleElement : nsIDOMHTMLElement @@ -2368,7 +2368,7 @@ interface nsIWebNavigation : nsISupports [ object, - uuid(570f39d0-efd0-11d3-b093-00a024ffc08c), + uuid(1c3437b0-9e2c-11e2-9e96-0800200c9a66), local ] interface nsIWebProgress : nsISupports @@ -2376,12 +2376,14 @@ interface nsIWebProgress : nsISupports nsresult AddProgressListener(nsIWebProgressListener *aListener, uint32_t aNotifyMask); nsresult RemoveProgressListener(nsIWebProgressListener *aListener); nsresult GetDOMWindow(nsIDOMWindow **aDOMWindow); + nsresult GetDOMWindowID(uint64_t *aDOMWindowID); + nsresult GetIsTopLevel(bool *aIsTopLevel); nsresult GetIsLoadingDocument(bool *aIsLoadingDocument); } [ object, - uuid(a65cfa37-b381-4fe9-81b7-db08853f54ad), + uuid(1bcfc611-8941-4c39-9e06-7116e564a1ce), local ] interface nsIPrintSettings : nsISupports @@ -2502,6 +2504,10 @@ interface nsIPrintSettings : nsISupports nsresult SetOutputFormat(int16_t aOutputFormat); nsresult GetPrintPageDelay(int32_t *aPrintPageDelay); nsresult SetPrintPageDelay(int32_t aPrintPageDelay); + nsresult GetResolution(int32_t *aResolution) = 0; + nsresult SetResolution(int32_t aResolution) = 0; + nsresult GetDuplex(int32_t *aDuplex); + nsresult SetDuplex(int32_t aDuplex); nsresult GetIsInitializedFromPrinter(bool *aIsInitializedFromPrinter); nsresult SetIsInitializedFromPrinter(bool aIsInitializedFromPrinter); nsresult GetIsInitializedFromPrefs(bool *aIsInitializedFromPrefs); @@ -2833,7 +2839,7 @@ interface nsIDOMEventListener : nsISupports [ object, - uuid(8e375931-298d-4d0a-9cb4-5668f0cdc5a8), + uuid(31e92e56-4d23-4a4a-9cfe-a6d12cf434bc), local ] interface nsIDOMEventTarget : nsISupports @@ -2849,7 +2855,7 @@ interface nsIDOMEventTarget : nsISupports [ object, - uuid(c939eab8-1345-4344-875b-e0f2d8d89171), + uuid(02d54f52-a1f5-4ad2-b560-36f14012935e), local ] interface nsIDOMEvent : nsISupports @@ -2868,8 +2874,6 @@ interface nsIDOMEvent : nsISupports nsresult StopImmediatePropagation(); nsresult GetOriginalTarget(nsIDOMEventTarget **aOriginalTarget); nsresult GetExplicitOriginalTarget(nsIDOMEventTarget * *aExplicitOriginalTarget); - nsresult PreventBubble(); - nsresult PreventCapture(); nsresult GetPreventDefault(bool *_retval); nsresult GetIsTrusted(bool *aIsTrusted); nsresult DuplicatePrivateData(); @@ -2879,11 +2883,13 @@ interface nsIDOMEvent : nsISupports void SetTrusted(bool aTrusted); void Serialize(/*IPC::Message*/ void *aMsg, bool aSerializeInterfaceType); bool Deserialize(const /*IPC::Message*/ void *aMsg, void **aIter); + void SetOwner(void /*mozilla::dom::EventTarget*/ *aOwner); + void /*nsDOMEvent*/ *InternalDOMEvent(); } [ object, - uuid(16b3bdcc-75d4-11e2-8a20-aaff78957a39), + uuid(cbe333d7-5b2c-4a9b-b99b-e6e388afa62b), local ] interface nsIDOMWindowUtils : nsISupports @@ -2903,6 +2909,7 @@ interface nsIDOMWindowUtils : nsISupports nsresult GetResolution(float *aXResolution, float *aYResolution); nsresult GetIsFirstPaint(bool *aIsFirstPaint); nsresult SetIsFirstPaint(bool aIsFirstPaint); + nsresult GetPresShellId(uint32_t *aPresShellId); nsresult SendMouseEvent(const nsAString *aType, float aX, float aY, int32_t aButton, int32_t aClickCount, int32_t aModifiers, bool aIgnoreRootScrollFrame, float aPressure, uint16_t aInputSourceArg, bool *_retval); nsresult SendTouchEvent(const nsAString *aType, uint32_t *aIdentifiers, int32_t *aXs, int32_t *aYs, @@ -2937,7 +2944,8 @@ interface nsIDOMWindowUtils : nsISupports nsresult ClearMozAfterPaintEvents(); nsresult DisableNonTestMouseEvents(bool aDisable); nsresult GetScrollXY(bool aFlushLayout, int32_t *aScrollX, int32_t *aScrollY); - nsresult GetScrollbarWidth(bool aFlushLayout, int32_t *_retval); + nsresult GetScrollbarSize(bool aFlushLayout, int32_t *aWidth, int32_t *aHeight); + nsresult GetBoundsWithoutFlushing(nsIDOMElement *aElement, nsIDOMClientRect **_retval); nsresult GetRootBounds(nsIDOMClientRect **_retval); nsresult GetIMEIsOpen(bool *aIMEIsOpen); nsresult GetIMEStatus(uint32_t *aIMEStatus); @@ -2971,6 +2979,7 @@ interface nsIDOMWindowUtils : nsISupports nsresult SuspendTimeouts(); nsresult ResumeTimeouts(); nsresult GetLayerManagerType(nsAString *aLayerManagerType); + nsresult GetLayerManagerRemote(bool *aLayerManagerRemote); nsresult StartFrameTimeRecording(uint32_t *startIndex); nsresult StopFrameTimeRecording(uint32_t startIndex, float **paintTimes, uint32_t *frameCount, float **frameIntervals); nsresult BeginTabSwitch(); @@ -2980,6 +2989,7 @@ interface nsIDOMWindowUtils : nsISupports void /*gfxContext*/ *aThebesContext); nsresult AdvanceTimeAndRefresh(int64_t aMilliseconds); nsresult RestoreNormalRefresh(); + nsresult GetIsTestControllingRefreshes(bool *aIsTestControllingRefreshes); nsresult ComputeAnimationDistance(nsIDOMElement *element, const nsAString *property, const nsAString *value1, const nsAString *value2, double *_retval); nsresult WrapDOMFile(nsIFile *aFile, nsIDOMFile **_retval); @@ -3005,12 +3015,19 @@ interface nsIDOMWindowUtils : nsISupports nsresult GetPaintingSuppressed(bool *aPaintingSuppressed); nsresult GetPlugins(JSContext *cx, /*JS::Value*/ void *aPlugins); nsresult SetScrollPositionClampingScrollPortSize(float aWidth, float aHeight); + nsresult SetContentDocumentFixedPositionMargins(float aTop, float aRight, float aBottom, float aLeft); nsresult PreventFurtherDialogs(); nsresult LoadSheet(nsIURI *sheetURI, uint32_t type); nsresult RemoveSheet(nsIURI *sheetURI, uint32_t type); nsresult GetIsHandlingUserInput(bool *aIsHandlingUserInput); nsresult AllowScriptsToClose(); + nsresult GetIsParentWindowMainWidgetVisible(bool *aIsParentWindowMainWidgetVisible); nsresult IsNodeDisabledForEvents(nsIDOMNode *aNode, bool *_retval); + nsresult GetPaintFlashing(bool *aPaintFlashing); + nsresult SetPaintFlashing(bool aPaintFlashing); + nsresult RunInStableState(nsIRunnable *runnable); + nsresult RunBeforeNextEvent(nsIRunnable *runnable); + nsresult GetOMTAOrComputedStyle(nsIDOMNode *aNode, const nsAString *aProperty, nsAString *_retval); } cpp_quote("#define CONTEXT_NONE 0x00") @@ -3091,7 +3108,7 @@ interface nsIDOMMouseEvent : nsIDOMUIEvent [ object, - uuid(ffbe684c-ca90-4b58-aa8c-9727f997f86d), + uuid(91a3d7f2-223b-4e09-a566-634e7ee0a31d), local ] interface nsIDOMKeyEvent : nsIDOMUIEvent @@ -3108,6 +3125,7 @@ interface nsIDOMKeyEvent : nsIDOMUIEvent uint32_t charCodeArg); nsresult GetModifierState(const nsAString *keyArg, bool *_retval); nsresult GetLocation(uint32_t *aLocation); + nsresult GetKey(nsAString *aKey); } [ @@ -3261,6 +3279,22 @@ interface nsICommandManager : nsISupports nsIDOMWindow *aTargetWindow); } +[ + object, + uuid(3275b2cd-af6d-429a-80d7-f0c5120342ac), + local +] +interface nsICategoryManager : nsISupports +{ + nsresult GetCategoryEntry(const char *aCategory, const char *aEntry, char **_retval); + nsresult AddCategoryEntry(const char *aCategory, const char *aEntry, const char *aValue, bool aPersist, + bool aReplace, char **_retval); + nsresult DeleteCategoryEntry(const char *aCategory, const char *aEntry, bool aPersist); + nsresult DeleteCategory(const char *aCategory); + nsresult EnumerateCategory(const char *aCategory, nsISimpleEnumerator **_retval); + nsresult EnumerateCategories(nsISimpleEnumerator **_retval); +} + [ object, uuid(47b82b60-a36f-4167-8072-6f421151ed50), @@ -3297,7 +3331,7 @@ interface nsIContent : nsISupports [ object, - uuid(4e6f7d97-091e-4eda-b7d6-feb0b8012a93), + uuid(62cca591-a030-4117-9b80-dcd366bbb509), local ] interface nsIDocument : nsISupports @@ -3503,13 +3537,13 @@ interface nsIDocShellTreeNode : nsISupports [ object, - uuid(09b54ec1-d98a-49a9-bc95-3219e8b55089), + uuid(e35bbb39-985b-4d62-81da-73c330222e5f), local ] interface nsIDocShellTreeItem : nsIDocShellTreeNode { - nsresult GetName(PRUnichar **aName); - nsresult SetName(const PRUnichar *aName); + nsresult GetName(nsAString *aName); + nsresult SetName(const nsAString *aName); nsresult NameEquals(const PRUnichar *name, bool *_retval); nsresult GetItemType(int32_t *aItemType); nsresult SetItemType(int32_t aItemType); @@ -3524,7 +3558,7 @@ interface nsIDocShellTreeItem : nsIDocShellTreeNode [ object, - uuid(e8f6f3e5-8cee-4be3-8d56-5ed617305bf8), + uuid(f453d2ee-bac7-46f9-a553-df918f0cc0d0), local ] interface nsIDocShell : nsIDocShellTreeItem @@ -3558,6 +3592,8 @@ interface nsIDocShell : nsIDocShellTreeItem nsresult SetAllowSubframes(bool aAllowSubframes); nsresult GetAllowImages(bool *aAllowImages); nsresult SetAllowImages(bool aAllowImages); + nsresult GetAllowMedia(bool *aAllowMedia); + nsresult SetAllowMedia(bool aAllowMedia); nsresult GetAllowDNSPrefetch(bool *aAllowDNSPrefetch); nsresult SetAllowDNSPrefetch(bool aAllowDNSPrefetch); nsresult GetAllowWindowControl(bool *aAllowWindowControl); @@ -3597,8 +3633,6 @@ interface nsIDocShell : nsIDocShellTreeItem nsresult GetSessionStorageForPrincipal(nsIPrincipal *principal, const nsAString *documentURI, bool create, nsIDOMStorage **_retval); nsresult AddSessionStorage(nsIPrincipal *principal, nsIDOMStorage *storage); - nsresult CloneSessionStoragesTo(nsIDocShell *docShell); - nsresult ClearSessionStorages(); nsresult GetCurrentDocumentChannel(nsIChannel **aCurrentDocumentChannel); nsresult SetChildOffset(uint32_t offset); nsresult GetIsInUnload(bool *aIsInUnload); @@ -3620,6 +3654,7 @@ interface nsIDocShell : nsIDocShellTreeItem nsresult CreateAboutBlankContentViewer(nsIPrincipal *aPrincipal); nsresult GetCharset(char **aCharset); nsresult SetCharset(const char * aCharset); + nsresult GatherCharsetMenuTelemetry(); nsresult GetForcedCharset(nsIAtom **aForcedCharset); nsresult SetForcedCharset(nsIAtom *aForcedCharset); nsresult GetParentCharset(nsIAtom **aParentCharset); @@ -3627,6 +3662,9 @@ interface nsIDocShell : nsIDocShellTreeItem nsresult GetParentCharsetSource(int32_t *aParentCharsetSource); nsresult SetParentCharsetSource(int32_t aParentCharsetSource); nsresult AddWeakPrivacyTransitionObserver(nsIPrivacyTransitionObserver *obs); + nsresult AddWeakReflowObserver(nsISupports /*nsIReflowObserver*/ *obs); + nsresult RemoveWeakReflowObserver(nsISupports /*nsIReflowObserver*/ *obs); + nsresult NotifyReflowObservers(bool interruptible, int /*DOMHighResTimeStamp*/ start, int /*DOMHighResTimeStamp*/ end); nsresult GetIsBrowserElement(bool *aIsBrowserElement); nsresult GetIsApp(bool *aIsApp); nsresult GetIsBrowserOrApp(bool *aIsBrowserOrApp); @@ -3653,6 +3691,55 @@ interface nsIDocShell : nsIDocShellTreeItem nsresult GetEditable(bool *aEditable); nsresult GetHasEditingSession(bool *aHasEditingSession); nsresult MakeEditable(bool inWaitForUriLoad); + nsresult GetChildSHEntry(int32_t aChildOffset, nsISHEntry **_retval); + nsresult AddChildSHEntry(nsISHEntry *aCloneReference, nsISHEntry *aHistoryEntry, int32_t aChildOffset, uint32_t aLoadType, bool aCloneChildren); + nsresult GetUseGlobalHistory(bool *aUseGlobalHistory); + nsresult SetUseGlobalHistory(bool aUseGlobalHistory); + nsresult RemoveFromSessionHistory(); + nsresult GetCreatedDynamically(bool *aCreatedDynamically); + nsresult SetCreatedDynamically(bool aCreatedDynamically); + nsresult GetCurrentSHEntry(nsISHEntry **aEntry, bool *_retval); +} + +[ + object, + uuid(02d37b31-e654-4b74-9bc3-14dfe0020bb3), + local +] +interface nsIMarkupDocumentViewer : nsISupports +{ + nsresult ScrollToNode(nsIDOMNode *node); + nsresult GetTextZoom(float *aTextZoom); + nsresult SetTextZoom(float aTextZoom); + nsresult GetFullZoom(float *aFullZoom); + nsresult SetFullZoom(float aFullZoom); + nsresult GetAuthorStyleDisabled(bool *aAuthorStyleDisabled); + nsresult SetAuthorStyleDisabled(bool aAuthorStyleDisabled); + nsresult GetDefaultCharacterSet(nsACString *aDefaultCharacterSet); + nsresult SetDefaultCharacterSet(const nsACString *aDefaultCharacterSet); + nsresult GetForceCharacterSet(nsACString *aForceCharacterSet); + nsresult SetForceCharacterSet(const nsACString *aForceCharacterSet); + nsresult GetHintCharacterSet(nsACString *aHintCharacterSet); + nsresult SetHintCharacterSet(const nsACString *aHintCharacterSet); + nsresult GetHintCharacterSetSource(int32_t *aHintCharacterSetSource); + nsresult SetHintCharacterSetSource(int32_t aHintCharacterSetSource); + nsresult GetPrevDocCharacterSet(nsACString *aPrevDocCharacterSet); + nsresult SetPrevDocCharacterSet(const nsACString *aPrevDocCharacterSet); + nsresult GetContentSize(int32_t *width, int32_t *height); + nsresult GetBidiTextDirection(uint8_t *aBidiTextDirection); + nsresult SetBidiTextDirection(uint8_t aBidiTextDirection); + nsresult GetBidiTextType(uint8_t *aBidiTextType); + nsresult SetBidiTextType(uint8_t aBidiTextType); + nsresult GetBidiNumeral(uint8_t *aBidiNumeral); + nsresult SetBidiNumeral(uint8_t aBidiNumeral); + nsresult GetBidiSupport(uint8_t *aBidiSupport); + nsresult SetBidiSupport(uint8_t aBidiSupport); + nsresult GetBidiOptions(uint32_t *aBidiOptions); + nsresult SetBidiOptions(uint32_t aBidiOptions); + nsresult GetMinFontSize(int32_t *aMinFontSize); + nsresult SetMinFontSize(int32_t aMinFontSize); + nsresult AppendSubtree(void /* nsTArray> */ *array); + nsresult ChangeMaxLineBoxWidth(int32_t maxLineBoxWidth); } [ diff --git a/dll/win32/mshtml/nsio.c b/dll/win32/mshtml/nsio.c index b035037a817..e507aec74be 100644 --- a/dll/win32/mshtml/nsio.c +++ b/dll/win32/mshtml/nsio.c @@ -120,6 +120,23 @@ static BOOL compare_ignoring_frag(IUri *uri1, IUri *uri2) return ret; } +static HRESULT combine_url(IUri *base_uri, const WCHAR *rel_url, IUri **ret) +{ + IUri *uri_nofrag; + HRESULT hres; + + uri_nofrag = get_uri_nofrag(base_uri); + if(!uri_nofrag) + return E_FAIL; + + hres = CoInternetCombineUrlEx(uri_nofrag, rel_url, URL_ESCAPE_SPACES_ONLY|URL_DONT_ESCAPE_EXTRA_INFO, + ret, 0); + IUri_Release(uri_nofrag); + if(FAILED(hres)) + WARN("CoInternetCombineUrlEx failed: %08x\n", hres); + return hres; +} + static nsresult create_nsuri(IUri*,HTMLOuterWindow*,NSContainer*,const char*,nsWineURI**); static const char *debugstr_nsacstr(const nsACString *nsstr) @@ -1480,9 +1497,6 @@ static nsresult NSAPI nsUploadChannel_SetUploadStream(nsIUploadChannel *iface, } } - if(This->post_data_stream) - nsIInputStream_Release(This->post_data_stream); - if(aContentLength != -1) FIXME("Unsupported acontentLength = %s\n", wine_dbgstr_longlong(aContentLength)); @@ -2386,12 +2400,10 @@ static nsresult NSAPI nsURI_Resolve(nsIFileURL *iface, const nsACString *aRelati if(!path) return NS_ERROR_OUT_OF_MEMORY; - hres = CoInternetCombineUrlEx(This->uri, path, URL_ESCAPE_SPACES_ONLY|URL_DONT_ESCAPE_EXTRA_INFO, &new_uri, 0); + hres = combine_url(This->uri, path, &new_uri); heap_free(path); - if(FAILED(hres)) { - ERR("CoIntenetCombineUrlEx failed: %08x\n", hres); + if(FAILED(hres)) return NS_ERROR_FAILURE; - } hres = IUri_GetDisplayUri(new_uri, &ret); IUri_Release(new_uri); @@ -3296,10 +3308,7 @@ static nsresult NSAPI nsIOService_NewURI(nsIIOService *iface, const nsACString * MultiByteToWideChar(CP_ACP, 0, spec, -1, new_spec, sizeof(new_spec)/sizeof(WCHAR)); if(base_wine_uri) { - hres = CoInternetCombineUrlEx(base_wine_uri->uri, new_spec, URL_ESCAPE_SPACES_ONLY|URL_DONT_ESCAPE_EXTRA_INFO, - &urlmon_uri, 0); - if(FAILED(hres)) - WARN("CoInternetCombineUrlEx failed: %08x\n", hres); + hres = combine_url(base_wine_uri->uri, new_spec, &urlmon_uri); }else { hres = create_uri(new_spec, 0, &urlmon_uri); if(FAILED(hres)) diff --git a/dll/win32/mshtml/olecmd.c b/dll/win32/mshtml/olecmd.c index 0a409c862d2..97a50c408cc 100644 --- a/dll/win32/mshtml/olecmd.c +++ b/dll/win32/mshtml/olecmd.c @@ -388,7 +388,7 @@ static void refresh_proc(task_t *_task) IOleCommandTarget_Exec(window->doc_obj->client_cmdtrg, &CGID_ShellDocView, 37, 0, &var, NULL); } - load_uri(task->window, task->window->uri, BINDING_REFRESH); + load_uri(task->window, task->window->uri, BINDING_REFRESH|BINDING_NOFRAG); } static void refresh_destr(task_t *_task) diff --git a/dll/win32/mshtml/oleobj.c b/dll/win32/mshtml/oleobj.c index 5851abdcde4..23b3784c6bd 100644 --- a/dll/win32/mshtml/oleobj.c +++ b/dll/win32/mshtml/oleobj.c @@ -190,6 +190,68 @@ void call_docview_84(HTMLDocumentObj *doc) FIXME("handle result\n"); } +void set_document_navigation(HTMLDocumentObj *doc, BOOL doc_can_navigate) +{ + VARIANT var; + + if(!doc->client_cmdtrg) + return; + + if(doc_can_navigate) { + V_VT(&var) = VT_UNKNOWN; + V_UNKNOWN(&var) = (IUnknown*)&doc->basedoc.window->base.IHTMLWindow2_iface; + } + + IOleCommandTarget_Exec(doc->client_cmdtrg, &CGID_DocHostCmdPriv, DOCHOST_DOCCANNAVIGATE, 0, + doc_can_navigate ? &var : NULL, NULL); +} + +static void load_settings(HTMLDocumentObj *doc) +{ + nsIMarkupDocumentViewer *markup_document_viewer; + nsIContentViewer *content_viewer; + nsIDocShell *doc_shell; + HKEY settings_key; + DWORD val, size; + LONG res; + nsresult nsres; + + static const WCHAR ie_keyW[] = { + 'S','O','F','T','W','A','R','E','\\', + 'M','i','c','r','o','s','o','f','t','\\', + 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r',0}; + static const WCHAR zoomW[] = {'Z','o','o','m',0}; + static const WCHAR zoom_factorW[] = {'Z','o','o','m','F','a','c','t','o','r',0}; + + res = RegOpenKeyW(HKEY_CURRENT_USER, ie_keyW, &settings_key); + if(res != ERROR_SUCCESS) + return; + + size = sizeof(val); + res = RegGetValueW(settings_key, zoomW, zoom_factorW, RRF_RT_REG_DWORD, NULL, &val, &size); + RegCloseKey(settings_key); + if(res != ERROR_SUCCESS) + return; + + TRACE("Setting ZoomFactor to %u\n", val); + + nsres = get_nsinterface((nsISupports*)doc->nscontainer->navigation, &IID_nsIDocShell, (void**)&doc_shell); + assert(nsres == NS_OK); + + nsres = nsIDocShell_GetContentViewer(doc_shell, &content_viewer); + assert(nsres == NS_OK && content_viewer); + + nsres = nsISupports_QueryInterface(content_viewer, &IID_nsIMarkupDocumentViewer, (void**)&markup_document_viewer); + nsISupports_Release(content_viewer); + assert(nsres == NS_OK); + + nsres = nsIMarkupDocumentViewer_SetFullZoom(markup_document_viewer, (float)val/100000); + if(NS_FAILED(nsres)) + ERR("SetFullZoom failed: %08x\n", nsres); + + nsIDocShell_Release(doc_shell); +} + static HRESULT WINAPI OleObject_SetClientSite(IOleObject *iface, IOleClientSite *pClientSite) { HTMLDocument *This = impl_from_IOleObject(iface); @@ -283,7 +345,7 @@ static HRESULT WINAPI OleObject_SetClientSite(IOleObject *iface, IOleClientSite if(hres == S_OK && key_path) { if(key_path[0]) { /* FIXME: use key_path */ - TRACE("key_path = %s\n", debugstr_w(key_path)); + FIXME("key_path = %s\n", debugstr_w(key_path)); } CoTaskMemFree(key_path); } @@ -295,7 +357,7 @@ static HRESULT WINAPI OleObject_SetClientSite(IOleObject *iface, IOleClientSite if(hres == S_OK && override_key_path && override_key_path[0]) { if(override_key_path[0]) { /*FIXME: use override_key_path */ - TRACE("override_key_path = %s\n", debugstr_w(override_key_path)); + FIXME("override_key_path = %s\n", debugstr_w(override_key_path)); } CoTaskMemFree(override_key_path); } @@ -306,6 +368,8 @@ static HRESULT WINAPI OleObject_SetClientSite(IOleObject *iface, IOleClientSite } } + load_settings(This->doc_obj); + /* Native calls here GetWindow. What is it for? * We don't have anything to do with it here (yet). */ hres = IOleClientSite_QueryInterface(pClientSite, &IID_IOleWindow, (void**)&ole_window); @@ -339,9 +403,7 @@ static HRESULT WINAPI OleObject_SetClientSite(IOleObject *iface, IOleClientSite IDocObjectService *doc_object_service; IWebBrowser2 *wb; - V_VT(&var) = VT_UNKNOWN; - V_UNKNOWN(&var) = (IUnknown*)&This->window->base.IHTMLWindow2_iface; - IOleCommandTarget_Exec(cmdtrg, &CGID_DocHostCmdPriv, DOCHOST_DOCCANNAVIGATE, 0, &var, NULL); + set_document_navigation(This->doc_obj, TRUE); if(browser_service) { hres = IBrowserService_QueryInterface(browser_service, diff --git a/dll/win32/mshtml/persist.c b/dll/win32/mshtml/persist.c index df918243984..fa4f3075053 100644 --- a/dll/win32/mshtml/persist.c +++ b/dll/win32/mshtml/persist.c @@ -411,9 +411,9 @@ HRESULT set_moniker(HTMLOuterWindow *window, IMoniker *mon, IUri *nav_uri, IBind return S_OK; } -void set_ready_state(HTMLOuterWindow *window, READYSTATE readystate) +static void notif_readystate(HTMLOuterWindow *window) { - window->readystate = readystate; + window->readystate_pending = FALSE; if(window->doc_obj && window->doc_obj->basedoc.window == window) call_property_onchanged(&window->doc_obj->basedoc.cp_container, DISPID_READYSTATE); @@ -426,6 +426,52 @@ void set_ready_state(HTMLOuterWindow *window, READYSTATE readystate) TRUE, window->frame_element->element.node.nsnode, NULL, NULL); } +typedef struct { + task_t header; + HTMLOuterWindow *window; +} readystate_task_t; + +static void notif_readystate_proc(task_t *_task) +{ + readystate_task_t *task = (readystate_task_t*)_task; + notif_readystate(task->window); +} + +static void notif_readystate_destr(task_t *_task) +{ + readystate_task_t *task = (readystate_task_t*)_task; + IHTMLWindow2_Release(&task->window->base.IHTMLWindow2_iface); +} + +void set_ready_state(HTMLOuterWindow *window, READYSTATE readystate) +{ + READYSTATE prev_state = window->readystate; + + window->readystate = readystate; + + if(window->readystate_locked) { + readystate_task_t *task; + HRESULT hres; + + if(window->readystate_pending || prev_state == readystate) + return; + + task = heap_alloc(sizeof(*task)); + if(!task) + return; + + IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface); + task->window = window; + + hres = push_task(&task->header, notif_readystate_proc, notif_readystate_destr, window->task_magic); + if(SUCCEEDED(hres)) + window->readystate_pending = TRUE; + return; + } + + notif_readystate(window); +} + static HRESULT get_doc_string(HTMLDocumentNode *This, char **str) { nsIDOMNode *nsnode; @@ -817,11 +863,12 @@ static HRESULT WINAPI PersistStreamInit_Load(IPersistStreamInit *iface, LPSTREAM prepare_for_binding(This, mon, FALSE); hres = set_moniker(This->window, mon, NULL, NULL, NULL, TRUE); - IMoniker_Release(mon); if(FAILED(hres)) return hres; - return channelbsc_load_stream(This->window->pending_window, pStm); + hres = channelbsc_load_stream(This->window->pending_window, mon, pStm); + IMoniker_Release(mon); + return hres; } static HRESULT WINAPI PersistStreamInit_Save(IPersistStreamInit *iface, LPSTREAM pStm, @@ -874,11 +921,12 @@ static HRESULT WINAPI PersistStreamInit_InitNew(IPersistStreamInit *iface) prepare_for_binding(This, mon, FALSE); hres = set_moniker(This->window, mon, NULL, NULL, NULL, FALSE); - IMoniker_Release(mon); if(FAILED(hres)) return hres; - return channelbsc_load_stream(This->window->pending_window, NULL); + hres = channelbsc_load_stream(This->window->pending_window, mon, NULL); + IMoniker_Release(mon); + return hres; } static const IPersistStreamInitVtbl PersistStreamInitVtbl = { diff --git a/dll/win32/mshtml/pluginhost.c b/dll/win32/mshtml/pluginhost.c index 02838ce1e3f..86a51c118c1 100644 --- a/dll/win32/mshtml/pluginhost.c +++ b/dll/win32/mshtml/pluginhost.c @@ -874,6 +874,29 @@ static ULONG WINAPI PHClientSite_AddRef(IOleClientSite *iface) return ref; } +static void release_plugin_ifaces(PluginHost *This) +{ + if(This->disp) { + IDispatch_Release(This->disp); + This->disp = NULL; + } + + if(This->ip_object) { + IOleInPlaceObject_Release(This->ip_object); + This->ip_object = NULL; + } + + if(This->plugin_unk) { + IUnknown *unk = This->plugin_unk; + LONG ref; + + This->plugin_unk = NULL; + ref = IUnknown_Release(unk); + + TRACE("plugin ref = %d\n", ref); + } +} + static ULONG WINAPI PHClientSite_Release(IOleClientSite *iface) { PluginHost *This = impl_from_IOleClientSite(iface); @@ -882,10 +905,7 @@ static ULONG WINAPI PHClientSite_Release(IOleClientSite *iface) TRACE("(%p) ref=%d\n", This, ref); if(!ref) { - if(This->disp) - IDispatch_Release(This->disp); - if(This->ip_object) - IOleInPlaceObject_Release(This->ip_object); + release_plugin_ifaces(This); if(This->sink) { This->sink->host = NULL; IDispatch_Release(&This->sink->IDispatch_iface); @@ -894,8 +914,6 @@ static ULONG WINAPI PHClientSite_Release(IOleClientSite *iface) list_remove(&This->entry); if(This->element) This->element->plugin_host = NULL; - if(This->plugin_unk) - IUnknown_Release(This->plugin_unk); heap_free(This); } @@ -1668,6 +1686,8 @@ void detach_plugin_host(PluginHost *host) host->sink = NULL; } + release_plugin_ifaces(host); + if(host->element) { host->element->plugin_host = NULL; host->element = NULL; diff --git a/dll/win32/mshtml/script.c b/dll/win32/mshtml/script.c index 7df602b0c8b..0a92def95ce 100644 --- a/dll/win32/mshtml/script.c +++ b/dll/win32/mshtml/script.c @@ -796,11 +796,13 @@ static BOOL get_guid_from_type(LPCWSTR type, GUID *guid) { const WCHAR text_javascriptW[] = {'t','e','x','t','/','j','a','v','a','s','c','r','i','p','t',0}; + const WCHAR text_jscriptW[] = + {'t','e','x','t','/','j','s','c','r','i','p','t',0}; const WCHAR text_vbscriptW[] = {'t','e','x','t','/','v','b','s','c','r','i','p','t',0}; /* FIXME: Handle more types */ - if(!strcmpiW(type, text_javascriptW)) { + if(!strcmpiW(type, text_javascriptW) || !strcmpiW(type, text_jscriptW)) { *guid = CLSID_JScript; }else if(!strcmpiW(type, text_vbscriptW)) { *guid = CLSID_VBScript; @@ -1026,11 +1028,12 @@ IDispatch *get_script_disp(ScriptHost *script_host) return disp; } -static HTMLElement *find_event_target(HTMLDocumentNode *doc, HTMLScriptElement *script_elem) +static event_target_t **find_event_target(HTMLDocumentNode *doc, HTMLScriptElement *script_elem, HTMLDOMNode **ret_target_node) { + HTMLDOMNode *target_node = NULL; + event_target_t **target = NULL; const PRUnichar *target_id; nsAString target_id_str; - HTMLElement *elem; nsresult nsres; HRESULT hres; @@ -1043,17 +1046,27 @@ static HTMLElement *find_event_target(HTMLDocumentNode *doc, HTMLScriptElement * } nsAString_GetData(&target_id_str, &target_id); - if(!*target_id || !strcmpW(target_id, documentW) || !strcmpW(target_id, windowW)) { - FIXME("for %s not supported\n", debugstr_w(target_id)); - elem = NULL; + if(!*target_id) { + FIXME("Empty for attribute\n"); + }else if(!strcmpW(target_id, documentW)) { + target = &doc->node.event_target; + target_node = &doc->node; + IHTMLDOMNode_AddRef(&target_node->IHTMLDOMNode_iface); + }else if(!strcmpW(target_id, windowW)) { + target = &doc->body_event_target; }else { - hres = get_doc_elem_by_id(doc, target_id, &elem); - if(FAILED(hres)) - elem = NULL; + HTMLElement *target_elem; + + hres = get_doc_elem_by_id(doc, target_id, &target_elem); + if(SUCCEEDED(hres) && target_elem) { + target_node = &target_elem->node; + target = &target_elem->node.event_target; + } } nsAString_Finish(&target_id_str); - return elem; + *ret_target_node = target_node; + return target; } static BOOL parse_event_str(WCHAR *event, const WCHAR **args) @@ -1148,8 +1161,9 @@ void bind_event_scripts(HTMLDocumentNode *doc) HTMLPluginContainer *plugin_container; nsIDOMHTMLScriptElement *nsscript; HTMLScriptElement *script_elem; - HTMLElement *event_target; + event_target_t **event_target; nsIDOMNodeList *node_list; + HTMLDOMNode *target_node; nsIDOMNode *script_node; nsAString selector_str; IDispatch *event_disp; @@ -1196,17 +1210,21 @@ void bind_event_scripts(HTMLDocumentNode *doc) event_disp = parse_event_elem(doc, script_elem, &event); if(event_disp) { - event_target = find_event_target(doc, script_elem); + event_target = find_event_target(doc, script_elem, &target_node); if(event_target) { - hres = IHTMLElement_QueryInterface(&event_target->IHTMLElement_iface, &IID_HTMLPluginContainer, - (void**)&plugin_container); + if(target_node) + hres = IHTMLDOMNode_QueryInterface(&target_node->IHTMLDOMNode_iface, &IID_HTMLPluginContainer, + (void**)&plugin_container); + else + hres = E_NOINTERFACE; if(SUCCEEDED(hres)) bind_activex_event(doc, plugin_container, event, event_disp); else - bind_elem_event(doc, event_target, event, event_disp); + bind_node_event(doc, event_target, target_node, event, event_disp); - IHTMLElement_Release(&event_target->IHTMLElement_iface); + if(target_node) + IHTMLDOMNode_Release(&target_node->IHTMLDOMNode_iface); } heap_free(event); diff --git a/dll/win32/msimtf/msimtf.idl b/dll/win32/msimtf/msimtf.idl index 388222e9222..77517d37e31 100644 --- a/dll/win32/msimtf/msimtf.idl +++ b/dll/win32/msimtf/msimtf.idl @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma makedep register + [ helpstring("CActiveIMMApp"), threading(apartment), diff --git a/dll/win32/msrle32/msrle32.c b/dll/win32/msrle32/msrle32.c index 16daa80644a..146f7e7d534 100644 --- a/dll/win32/msrle32/msrle32.c +++ b/dll/win32/msrle32/msrle32.c @@ -39,7 +39,6 @@ static HINSTANCE MSRLE32_hModule = 0; #define ABS(a) ((a) < 0 ? -(a) : (a)) #define SQR(a) ((a) * (a)) -#define QUALITY_to_DIST(q) (ICQUALITY_HIGH - q) static inline WORD ColorCmp(WORD clr1, WORD clr2) { UINT a = clr1 - clr2; @@ -257,7 +256,7 @@ static LONG MSRLE32_GetMaxCompressedSize(LPCBITMAPINFOHEADER lpbi) } size = (2 + a * (2 + ((a + 2) & ~2)) + b * (2 + ((b + 2) & ~2))); - return size * lpbi->biHeight; + return size * lpbi->biHeight + 2; } /* lpP => current pos in previous frame @@ -457,8 +456,7 @@ static INT MSRLE32_CompressRLE4Line(const CodecInfo *pi, const WORD *lpP, static INT MSRLE32_CompressRLE8Line(const CodecInfo *pi, const WORD *lpP, const WORD *lpC, LPCBITMAPINFOHEADER lpbi, - const BYTE *lpIn, LONG lDist, - INT x, LPBYTE *ppOut, + const BYTE *lpIn, INT x, LPBYTE *ppOut, DWORD *lpSizeImage) { LPBYTE lpOut = *ppOut; @@ -472,13 +470,13 @@ static INT MSRLE32_CompressRLE8Line(const CodecInfo *pi, const WORD *lpP, pos = x; clr = lpC[pos++]; for (count = 1; pos < lpbi->biWidth; count++) { - if (ColorCmp(clr, lpC[pos++]) > lDist) + if (ColorCmp(clr, lpC[pos++]) > 0) break; } if (count < 2) { /* add some more pixels for absoluting if possible */ - count += countDiffRLE8(lpP, lpC - 1, lpC, pos-1, lDist, lpbi->biWidth); + count += countDiffRLE8(lpP, lpC - 1, lpC, pos-1, 0, lpbi->biWidth); assert(count > 0); @@ -547,7 +545,7 @@ LRESULT MSRLE32_CompressRLE4(const CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, LPBYTE lpOut, BOOL isKey) { LPWORD lpC; - LONG lLine, lInLine, lDist; + LONG lLine, lInLine; LPBYTE lpOutStart = lpOut; /* pre-conditions */ @@ -556,7 +554,6 @@ LRESULT MSRLE32_CompressRLE4(const CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, assert(pi->pCurFrame != NULL); lpC = pi->pCurFrame; - lDist = QUALITY_to_DIST(pi->dwQuality); lInLine = DIBWIDTHBYTES(*lpbiIn); lLine = WIDTHBYTES(lpbiOut->biWidth * 16) / 2; @@ -569,7 +566,7 @@ LRESULT MSRLE32_CompressRLE4(const CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, x = 0; do { - x = MSRLE32_CompressRLE4Line(pi, NULL, lpC, lpbiIn, lpIn, lDist, x, + x = MSRLE32_CompressRLE4Line(pi, NULL, lpC, lpbiIn, lpIn, 0, x, &lpOut, &lpbiOut->biSizeImage); } while (x < lpbiOut->biWidth); @@ -603,7 +600,7 @@ LRESULT MSRLE32_CompressRLE4(const CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, if (jumpx == -1) jumpx = x; for (count = 0, pos = x; pos < lpbiOut->biWidth; pos++, count++) { - if (ColorCmp(lpP[pos], lpC[pos]) > lDist) + if (ColorCmp(lpP[pos], lpC[pos]) > 0) break; } @@ -663,7 +660,7 @@ LRESULT MSRLE32_CompressRLE4(const CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, if (x < lpbiOut->biWidth) { /* skipped the 'same' things corresponding to previous frame */ - x = MSRLE32_CompressRLE4Line(pi, lpP, lpC, lpbiIn, lpIn, lDist, x, + x = MSRLE32_CompressRLE4Line(pi, lpP, lpC, lpbiIn, lpIn, 0, x, &lpOut, &lpbiOut->biSizeImage); } } while (x < lpbiOut->biWidth); @@ -701,7 +698,7 @@ LRESULT MSRLE32_CompressRLE8(const CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, LPBYTE lpOut, BOOL isKey) { LPWORD lpC; - LONG lDist, lInLine, lLine; + LONG lInLine, lLine; LPBYTE lpOutStart = lpOut; assert(pi != NULL && lpbiOut != NULL); @@ -709,7 +706,6 @@ LRESULT MSRLE32_CompressRLE8(const CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, assert(pi->pCurFrame != NULL); lpC = pi->pCurFrame; - lDist = QUALITY_to_DIST(pi->dwQuality); lInLine = DIBWIDTHBYTES(*lpbiIn); lLine = WIDTHBYTES(lpbiOut->biWidth * 16) / 2; @@ -722,7 +718,7 @@ LRESULT MSRLE32_CompressRLE8(const CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, x = 0; do { - x = MSRLE32_CompressRLE8Line(pi, NULL, lpC, lpbiIn, lpIn, lDist, x, + x = MSRLE32_CompressRLE8Line(pi, NULL, lpC, lpbiIn, lpIn, x, &lpOut, &lpbiOut->biSizeImage); assert(lpOut == (lpOutStart + lpbiOut->biSizeImage)); } while (x < lpbiOut->biWidth); @@ -757,7 +753,7 @@ LRESULT MSRLE32_CompressRLE8(const CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, if (jumpx == -1) jumpx = x; for (count = 0, pos = x; pos < lpbiOut->biWidth; pos++, count++) { - if (ColorCmp(lpP[pos], lpC[pos]) > lDist) + if (ColorCmp(lpP[pos], lpC[pos]) > 0) break; } @@ -804,7 +800,7 @@ LRESULT MSRLE32_CompressRLE8(const CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, if (x < lpbiOut->biWidth) { /* skip the 'same' things corresponding to previous frame */ - x = MSRLE32_CompressRLE8Line(pi, lpP, lpC, lpbiIn, lpIn, lDist, x, + x = MSRLE32_CompressRLE8Line(pi, lpP, lpC, lpbiIn, lpIn, x, &lpOut, &lpbiOut->biSizeImage); assert(lpOut == (lpOutStart + lpbiOut->biSizeImage)); } @@ -823,14 +819,16 @@ LRESULT MSRLE32_CompressRLE8(const CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, } } - /* add EOL -- will be changed to EOI */ + /* add EOL */ lpbiOut->biSizeImage += 2; *((LPWORD)lpOut) = 0; lpOut += sizeof(WORD); } - /* change EOL to EOI -- end of image */ - lpOut[-1] = 1; + /* add EOI -- end of image */ + lpbiOut->biSizeImage += 2; + *lpOut++ = 0; + *lpOut++ = 1; assert(lpOut == (lpOutStart + lpbiOut->biSizeImage)); return ICERR_OK; @@ -1144,7 +1142,6 @@ static CodecInfo* Open(LPICOPEN icinfo) pi->fccHandler = icinfo->fccHandler; pi->bCompress = FALSE; - pi->dwQuality = MSRLE32_DEFAULTQUALITY; pi->nPrevFrame = -1; pi->pPrevFrame = pi->pCurFrame = NULL; @@ -1195,21 +1192,6 @@ static LRESULT GetInfo(const CodecInfo *pi, ICINFO *icinfo, DWORD dwSize) return sizeof(ICINFO); } -static LRESULT SetQuality(CodecInfo *pi, LONG lQuality) -{ - /* pre-condition */ - assert(pi != NULL); - - if (lQuality == -1) - lQuality = MSRLE32_DEFAULTQUALITY; - else if (ICQUALITY_LOW > lQuality || lQuality > ICQUALITY_HIGH) - return ICERR_BADPARAM; - - pi->dwQuality = (DWORD)lQuality; - - return ICERR_OK; -} - static LRESULT Configure(const CodecInfo *pi, HWND hWnd) { /* pre-condition */ @@ -1438,6 +1420,7 @@ static LRESULT CompressBegin(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, static LRESULT Compress(CodecInfo *pi, ICCOMPRESS* lpic, DWORD dwSize) { + BOOL is_key; int i; TRACE("(%p,%p,%u)\n",pi,lpic,dwSize); @@ -1486,24 +1469,22 @@ static LRESULT Compress(CodecInfo *pi, ICCOMPRESS* lpic, DWORD dwSize) computeInternalFrame(pi, lpic->lpbiPrev, lpic->lpPrev); /* swap buffers for current and previous frame */ - /* Don't free and alloc new -- costs to much time and they are of equal size ! */ + /* Don't free and alloc new -- costs too much time and they are of equal size ! */ pTmp = pi->pPrevFrame; pi->pPrevFrame = pi->pCurFrame; pi->pCurFrame = pTmp; pi->nPrevFrame = lpic->lFrameNum; } - for (i = 0; i < 3; i++) { - SetQuality(pi, lpic->dwQuality); + is_key = (lpic->dwFlags & ICCOMPRESS_KEYFRAME) != 0; + for (i = 0; i < 3; i++) { lpic->lpbiOutput->biSizeImage = 0; if (lpic->lpbiOutput->biBitCount == 4) - MSRLE32_CompressRLE4(pi, lpic->lpbiInput, lpic->lpInput, - lpic->lpbiOutput, lpic->lpOutput, (lpic->dwFlags & ICCOMPRESS_KEYFRAME) != 0); + MSRLE32_CompressRLE4(pi, lpic->lpbiInput, lpic->lpInput, lpic->lpbiOutput, lpic->lpOutput, is_key); else - MSRLE32_CompressRLE8(pi, lpic->lpbiInput, lpic->lpInput, - lpic->lpbiOutput, lpic->lpOutput, (lpic->dwFlags & ICCOMPRESS_KEYFRAME) != 0); + MSRLE32_CompressRLE8(pi, lpic->lpbiInput, lpic->lpInput, lpic->lpbiOutput, lpic->lpOutput, is_key); if (lpic->dwFrameSize == 0 || lpic->lpbiOutput->biSizeImage < lpic->dwFrameSize) @@ -1520,7 +1501,7 @@ static LRESULT Compress(CodecInfo *pi, ICCOMPRESS* lpic, DWORD dwSize) if (lpic->dwFrameSize == 0 || lpic->lpbiOutput->biSizeImage < lpic->dwFrameSize) { WARN("switched to keyframe, was small enough!\n"); - *lpic->lpdwFlags |= ICCOMPRESS_KEYFRAME; + is_key = TRUE; *lpic->lpckid = MAKEAVICKID(cktypeDIBbits, StreamFromFOURCC(*lpic->lpckid)); break; @@ -1534,7 +1515,7 @@ static LRESULT Compress(CodecInfo *pi, ICCOMPRESS* lpic, DWORD dwSize) } { /* swap buffer for current and previous frame */ - /* Don't free and alloc new -- costs to much time and they are of equal size ! */ + /* Don't free and alloc new -- costs too much time and they are of equal size ! */ LPWORD pTmp = pi->pPrevFrame; pi->pPrevFrame = pi->pCurFrame; @@ -1542,6 +1523,8 @@ static LRESULT Compress(CodecInfo *pi, ICCOMPRESS* lpic, DWORD dwSize) pi->nPrevFrame = lpic->lFrameNum; } + /* FIXME: What is AVIIF_TWOCC? */ + *lpic->lpdwFlags |= AVIIF_TWOCC | (is_key ? AVIIF_KEYFRAME : 0); return ICERR_OK; } @@ -1850,14 +1833,6 @@ LRESULT CALLBACK MSRLE32_DriverProc(DWORD_PTR dwDrvID, HDRVR hDrv, UINT uMsg, return ICERR_OK; } break; - case ICM_GETQUALITY: - if ((LPVOID)lParam1 != NULL) { - *((LPDWORD)lParam1) = pi->dwQuality; - return ICERR_OK; - } - break; - case ICM_SETQUALITY: - return SetQuality(pi, *(LPLONG)lParam1); case ICM_COMPRESS_GET_FORMAT: return CompressGetFormat(pi, (LPCBITMAPINFOHEADER)lParam1, (LPBITMAPINFOHEADER)lParam2); diff --git a/dll/win32/msrle32/msrle_private.h b/dll/win32/msrle32/msrle_private.h index 58bb7b4a78a..88b90740261 100644 --- a/dll/win32/msrle32/msrle_private.h +++ b/dll/win32/msrle32/msrle_private.h @@ -38,7 +38,7 @@ #define IDS_DESCRIPTION 101 #define IDS_ABOUT 102 -#define MSRLE32_DEFAULTQUALITY (75 * ICQUALITY_HIGH) / 100 +#define MSRLE32_DEFAULTQUALITY (85 * ICQUALITY_HIGH) / 100 #define FOURCC_RLE mmioFOURCC('R','L','E',' ') #define FOURCC_RLE4 mmioFOURCC('R','L','E','4') @@ -50,7 +50,6 @@ typedef struct _CodecInfo { FOURCC fccHandler; - DWORD dwQuality; BOOL bCompress; LONG nPrevFrame; diff --git a/dll/win32/mstask/mstask_local.idl b/dll/win32/mstask/mstask_local.idl index b1a044ab338..98e060c4684 100644 --- a/dll/win32/mstask/mstask_local.idl +++ b/dll/win32/mstask/mstask_local.idl @@ -16,4 +16,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma makedep ident +#pragma makedep register + #include "mstask.idl" diff --git a/dll/win32/msxml/msxml_tlb.idl b/dll/win32/msxml/msxml_tlb.idl index 8ad22a2fc71..3afa64c86e5 100644 --- a/dll/win32/msxml/msxml_tlb.idl +++ b/dll/win32/msxml/msxml_tlb.idl @@ -16,4 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma makedep regtypelib + #include "msxml.idl" diff --git a/dll/win32/msxml2/msxml2_tlb.idl b/dll/win32/msxml2/msxml2_tlb.idl index 9826496d25e..c06a9379619 100644 --- a/dll/win32/msxml2/msxml2_tlb.idl +++ b/dll/win32/msxml2/msxml2_tlb.idl @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma makedep regtypelib + #include #include diff --git a/dll/win32/msxml4/msxml4_tlb.idl b/dll/win32/msxml4/msxml4_tlb.idl index 4f6b4de64d2..a2d3785e4c3 100644 --- a/dll/win32/msxml4/msxml4_tlb.idl +++ b/dll/win32/msxml4/msxml4_tlb.idl @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma makedep regtypelib + #include #include diff --git a/dll/win32/msxml6/msxml6_tlb.idl b/dll/win32/msxml6/msxml6_tlb.idl index 1a2ddbd462d..88c78babd28 100644 --- a/dll/win32/msxml6/msxml6_tlb.idl +++ b/dll/win32/msxml6/msxml6_tlb.idl @@ -16,4 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma makedep regtypelib + #include "msxml6.idl" diff --git a/dll/win32/netapi32/nbcmdqueue.h b/dll/win32/netapi32/nbcmdqueue.h index 8bd45b1e0be..debe7832daa 100644 --- a/dll/win32/netapi32/nbcmdqueue.h +++ b/dll/win32/netapi32/nbcmdqueue.h @@ -25,12 +25,12 @@ struct NBCmdQueue; /* Allocates a new command queue from heap. */ -struct NBCmdQueue *NBCmdQueueCreate(HANDLE heap); +struct NBCmdQueue *NBCmdQueueCreate(HANDLE heap) DECLSPEC_HIDDEN; /* Adds ncb to queue. Assumes queue is not NULL, and ncb is not already in the * queue. If ncb is already in the queue, returns NRC_TOOMANY. */ -UCHAR NBCmdQueueAdd(struct NBCmdQueue *queue, PNCB ncb); +UCHAR NBCmdQueueAdd(struct NBCmdQueue *queue, PNCB ncb) DECLSPEC_HIDDEN; /* Cancels the given ncb. Blocks until the command completes. Implicitly * removes ncb from the queue. Assumes queue and ncb are not NULL, and that @@ -39,23 +39,23 @@ UCHAR NBCmdQueueAdd(struct NBCmdQueue *queue, PNCB ncb); * completed before it could be cancelled, and various other return values for * different failures. */ -UCHAR NBCmdQueueCancel(struct NBCmdQueue *queue, PNCB ncb); +UCHAR NBCmdQueueCancel(struct NBCmdQueue *queue, PNCB ncb) DECLSPEC_HIDDEN; /* Sets the return code of the given ncb, and implicitly removes the command * from the queue. Assumes queue and ncb are not NULL, and that ncb has been * added to queue previously. * Returns NRC_GOODRET on success. */ -UCHAR NBCmdQueueComplete(struct NBCmdQueue *queue, PNCB ncb, UCHAR retcode); +UCHAR NBCmdQueueComplete(struct NBCmdQueue *queue, PNCB ncb, UCHAR retcode) DECLSPEC_HIDDEN; /* Cancels all pending commands in the queue (useful for a RESET or a shutdown). * Returns when all commands have been completed. */ -UCHAR NBCmdQueueCancelAll(struct NBCmdQueue *queue); +UCHAR NBCmdQueueCancelAll(struct NBCmdQueue *queue) DECLSPEC_HIDDEN; /* Frees all memory associated with the queue. Blocks until all commands * pending in the queue have been completed. */ -void NBCmdQueueDestroy(struct NBCmdQueue *queue); +void NBCmdQueueDestroy(struct NBCmdQueue *queue) DECLSPEC_HIDDEN; #endif /* __NBCMDQUEUE_H__ */ diff --git a/dll/win32/netapi32/nbnamecache.h b/dll/win32/netapi32/nbnamecache.h index bfdbb33abbe..3a36953f770 100644 --- a/dll/win32/netapi32/nbnamecache.h +++ b/dll/win32/netapi32/nbnamecache.h @@ -45,7 +45,7 @@ typedef struct _NBNameCacheEntry /* Allocates a new name cache from heap, and sets the expire time on new * entries to entryExpireTimeMS after a cache entry is added. */ -struct NBNameCache *NBNameCacheCreate(HANDLE heap, DWORD entryExpireTimeMS); +struct NBNameCache *NBNameCacheCreate(HANDLE heap, DWORD entryExpireTimeMS) DECLSPEC_HIDDEN; /* Adds an entry to the cache. The entry is assumed to have been allocated * from the same heap as the name cache; the name cache will own the entry @@ -54,14 +54,14 @@ struct NBNameCache *NBNameCacheCreate(HANDLE heap, DWORD entryExpireTimeMS); * same name was in the cache, the entry is replaced. Returns TRUE on success * or FALSE on failure. */ -BOOL NBNameCacheAddEntry(struct NBNameCache *cache, NBNameCacheEntry *entry); +BOOL NBNameCacheAddEntry(struct NBNameCache *cache, NBNameCacheEntry *entry) DECLSPEC_HIDDEN; /* Finds the entry with name name in the cache and returns a pointer to it, or * NULL if it isn't found. */ const NBNameCacheEntry *NBNameCacheFindEntry(struct NBNameCache *cache, - const UCHAR name[NCBNAMSZ]); + const UCHAR name[NCBNAMSZ]) DECLSPEC_HIDDEN; -void NBNameCacheDestroy(struct NBNameCache *cache); +void NBNameCacheDestroy(struct NBNameCache *cache) DECLSPEC_HIDDEN; #endif /* ndef __WINE_NBNAMECACHE_H */ diff --git a/dll/win32/netapi32/nbt.c b/dll/win32/netapi32/nbt.c index d0ae2853b49..ba68e7206da 100644 --- a/dll/win32/netapi32/nbt.c +++ b/dll/win32/netapi32/nbt.c @@ -289,7 +289,7 @@ static UCHAR NetBTWaitForNameResponse(const NetBTAdapter *adapter, SOCKET fd, if (fd == INVALID_SOCKET) return NRC_BADDR; if (!answerCallback) return NRC_BADDR; - while (!found && ret == NRC_GOODRET && (now = GetTickCount()) < waitUntil) + while (!found && ret == NRC_GOODRET && (int)((now = GetTickCount()) - waitUntil) < 0) { DWORD msToWait = waitUntil - now; struct fd_set fds; @@ -399,9 +399,8 @@ static BOOL NetBTFindNameAnswerCallback(void *pVoid, WORD answerCount, { if (queryData->cacheEntry == NULL) { - queryData->cacheEntry = HeapAlloc( - GetProcessHeap(), 0, sizeof(NBNameCacheEntry) + - (answerCount - 1) * sizeof(DWORD)); + queryData->cacheEntry = HeapAlloc(GetProcessHeap(), 0, + FIELD_OFFSET(NBNameCacheEntry, addresses[answerCount])); if (queryData->cacheEntry) queryData->cacheEntry->numAddresses = 0; else @@ -533,8 +532,8 @@ static UCHAR NetBTinetResolve(const UCHAR name[NCBNAMSZ], if (addr != INADDR_NONE) { - *cacheEntry = HeapAlloc(GetProcessHeap(), - 0, sizeof(NBNameCacheEntry)); + *cacheEntry = HeapAlloc(GetProcessHeap(), 0, + FIELD_OFFSET(NBNameCacheEntry, addresses[1])); if (*cacheEntry) { memcpy((*cacheEntry)->name, name, NCBNAMSZ); @@ -558,9 +557,8 @@ static UCHAR NetBTinetResolve(const UCHAR name[NCBNAMSZ], ; if (host->h_addr_list && host->h_addr_list[0]) { - *cacheEntry = HeapAlloc( - GetProcessHeap(), 0, sizeof(NBNameCacheEntry) + - (i - 1) * sizeof(DWORD)); + *cacheEntry = HeapAlloc(GetProcessHeap(), 0, + FIELD_OFFSET(NBNameCacheEntry, addresses[i])); if (*cacheEntry) { memcpy((*cacheEntry)->name, name, NCBNAMSZ); @@ -569,7 +567,7 @@ static UCHAR NetBTinetResolve(const UCHAR name[NCBNAMSZ], (*cacheEntry)->numAddresses = i; for (i = 0; i < (*cacheEntry)->numAddresses; i++) (*cacheEntry)->addresses[i] = - (DWORD)host->h_addr_list[i]; + *(DWORD*)host->h_addr_list[i]; } else ret = NRC_OSRESNOTAV; @@ -995,7 +993,7 @@ static UCHAR NetBTCall(void *adapt, PNCB ncb, void **sess) setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout)); } - if (ncb->ncb_rto > 0) + if (ncb->ncb_sto > 0) { timeout = ncb->ncb_sto * 500; setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, @@ -1489,13 +1487,17 @@ void NetBTInit(void) NetBTNameEncode */ char *ptr, *lenPtr; - for (ptr = gScopeID + 1; ptr - gScopeID < sizeof(gScopeID) && *ptr; ) + for (ptr = gScopeID + 1, lenPtr = gScopeID; ptr - gScopeID < sizeof(gScopeID) && *ptr; ++ptr) { - for (lenPtr = ptr - 1, *lenPtr = 0; - ptr - gScopeID < sizeof(gScopeID) && *ptr && *ptr != '.'; - ptr++) - *lenPtr += 1; - ptr++; + if (*ptr == '.') + { + lenPtr = ptr; + *lenPtr = 0; + } + else + { + ++*lenPtr; + } } } if (RegQueryValueExW(hKey, CacheTimeoutW, NULL, NULL, diff --git a/dll/win32/netapi32/netapi32.c b/dll/win32/netapi32/netapi32.c index d81953d4a97..5c0b947803c 100644 --- a/dll/win32/netapi32/netapi32.c +++ b/dll/win32/netapi32/netapi32.c @@ -20,9 +20,7 @@ #include -WINE_DEFAULT_DEBUG_CHANNEL(netbios); - -static HMODULE NETAPI32_hModule; +WINE_DEFAULT_DEBUG_CHANNEL(netapi32); BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { @@ -30,18 +28,14 @@ BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) switch (fdwReason) { case DLL_PROCESS_ATTACH: - { DisableThreadLibraryCalls(hinstDLL); - NETAPI32_hModule = hinstDLL; NetBIOSInit(); NetBTInit(); break; - } case DLL_PROCESS_DETACH: - { + if (lpvReserved) break; NetBIOSShutdown(); break; - } } return TRUE; @@ -83,10 +77,28 @@ NET_API_STATUS WINAPI NetServerEnumEx( LMCSTR domain, LMCSTR FirstNameToReturn) { - FIXME("Stub (%s %d %p %d %p %p %d %s %p)\n", debugstr_w(ServerName), - Level, Bufptr, PrefMaxlen, EntriesRead, totalentries, servertype, - debugstr_w(domain), debugstr_w(FirstNameToReturn)); - + FIXME("Stub (%s %d %p %d %p %p %d %s %s)\n", + debugstr_w(ServerName), Level, Bufptr, PrefMaxlen, EntriesRead, totalentries, + servertype, debugstr_w(domain), debugstr_w(FirstNameToReturn)); + + return ERROR_NO_BROWSER_SERVERS_FOUND; +} + +/************************************************************ + * NetServerDiskEnum (NETAPI32.@) + */ +NET_API_STATUS WINAPI NetServerDiskEnum( + LMSTR ServerName, + DWORD Level, + LPBYTE *Bufptr, + DWORD PrefMaxlen, + LPDWORD EntriesRead, + LPDWORD totalentries, + LPDWORD Resume_Handle) +{ + FIXME("Stub (%s %d %p %d %p %p %p)\n", debugstr_w(ServerName), + Level, Bufptr, PrefMaxlen, EntriesRead, totalentries, Resume_Handle); + return ERROR_NO_BROWSER_SERVERS_FOUND; } @@ -162,51 +174,6 @@ NET_API_STATUS WINAPI NetStatisticsGet(LMSTR server, LMSTR service, return NERR_InternalError; } -DWORD WINAPI NetpNetBiosStatusToApiStatus(DWORD nrc) -{ - DWORD ret; - - switch (nrc) - { - case NRC_GOODRET: - ret = NO_ERROR; - break; - case NRC_NORES: - ret = NERR_NoNetworkResource; - break; - case NRC_DUPNAME: - ret = NERR_AlreadyExists; - break; - case NRC_NAMTFUL: - ret = NERR_TooManyNames; - break; - case NRC_ACTSES: - ret = NERR_DeleteLater; - break; - case NRC_REMTFUL: - ret = ERROR_REM_NOT_LIST; - break; - case NRC_NOCALL: - ret = NERR_NameNotFound; - break; - case NRC_NOWILD: - ret = ERROR_INVALID_PARAMETER; - break; - case NRC_INUSE: - ret = NERR_DuplicateName; - break; - case NRC_NAMERR: - ret = ERROR_INVALID_PARAMETER; - break; - case NRC_NAMCONF: - ret = NERR_DuplicateName; - break; - default: - ret = NERR_NetworkError; - } - return ret; -} - NET_API_STATUS WINAPI NetpNtStatusToApiStatus(NTSTATUS Status) @@ -242,3 +209,31 @@ NET_API_STATUS WINAPI NetUseEnum(LMSTR server, DWORD level, LPBYTE* bufptr, DWOR entriesread, totalentries, resumehandle); return ERROR_NOT_SUPPORTED; } + +NET_API_STATUS WINAPI NetScheduleJobAdd(LPCWSTR server, LPBYTE bufptr, LPDWORD jobid) +{ + FIXME("stub (%s, %p, %p)\n", debugstr_w(server), bufptr, jobid); + return NERR_Success; +} + +NET_API_STATUS WINAPI NetScheduleJobDel(LPCWSTR server, DWORD minjobid, DWORD maxjobid) +{ + FIXME("stub (%s, %d, %d)\n", debugstr_w(server), minjobid, maxjobid); + return NERR_Success; +} + +NET_API_STATUS WINAPI NetScheduleJobEnum(LPCWSTR server, LPBYTE* bufptr, DWORD prefmaxsize, LPDWORD entriesread, + LPDWORD totalentries, LPDWORD resumehandle) +{ + FIXME("stub (%s, %p, %d, %p, %p, %p)\n", debugstr_w(server), bufptr, prefmaxsize, entriesread, totalentries, resumehandle); + *entriesread = 0; + *totalentries = 0; + return NERR_Success; +} + +NET_API_STATUS WINAPI NetUseGetInfo(LMSTR server, LMSTR name, DWORD level, LPBYTE *bufptr) +{ + FIXME("stub (%p, %p, %d, %p)\n", server, name, level, bufptr); + return ERROR_NOT_SUPPORTED; + +} diff --git a/dll/win32/netapi32/netapi32.h b/dll/win32/netapi32/netapi32.h index c33f9336eb0..722e333e911 100644 --- a/dll/win32/netapi32/netapi32.h +++ b/dll/win32/netapi32/netapi32.h @@ -19,6 +19,7 @@ #include #include +#include #define NTOS_MODE_USER #include diff --git a/dll/win32/netapi32/netapi32.spec b/dll/win32/netapi32/netapi32.spec index 66f9a5d0e16..f9556c5b48b 100644 --- a/dll/win32/netapi32/netapi32.spec +++ b/dll/win32/netapi32/netapi32.spec @@ -201,13 +201,13 @@ @ stub NetReplImportDirLock @ stub NetReplImportDirUnlock @ stub NetReplSetInfo -@ stub NetScheduleJobAdd -@ stub NetScheduleJobDel -@ stub NetScheduleJobEnum +@ stdcall NetScheduleJobAdd(wstr ptr ptr) +@ stdcall NetScheduleJobDel(wstr long long) +@ stdcall NetScheduleJobEnum(wstr ptr long ptr ptr ptr) @ stub NetScheduleJobGetInfo @ stub NetServerComputerNameAdd @ stub NetServerComputerNameDel -@ stub NetServerDiskEnum +@ stdcall NetServerDiskEnum(wstr long ptr long ptr ptr ptr) @ stdcall NetServerEnum(wstr long ptr long ptr ptr long wstr ptr) @ stdcall NetServerEnumEx(wstr long ptr long ptr ptr long wstr wstr) @ stdcall NetServerGetInfo(wstr long ptr) @@ -238,7 +238,7 @@ @ stdcall NetUseAdd(wstr long ptr ptr) @ stub NetUseDel @ stdcall NetUseEnum(wstr long ptr long ptr ptr ptr) -@ stub NetUseGetInfo +@ stdcall NetUseGetInfo(ptr ptr long ptr) @ stdcall NetUserAdd(wstr long ptr ptr) @ stdcall NetUserChangePassword(wstr wstr wstr wstr) @ stdcall NetUserDel(wstr wstr) diff --git a/dll/win32/netapi32/netbios.c b/dll/win32/netapi32/netbios.c index 8cb1e63c1ea..5bfe4476061 100644 --- a/dll/win32/netapi32/netbios.c +++ b/dll/win32/netapi32/netbios.c @@ -49,7 +49,7 @@ typedef struct _NetBIOSSession * is not NULL, the adapter is considered valid. (transport is a pointer to * an entry in a NetBIOSTransportTableEntry.) data has data for the callers of * NetBIOSEnumAdapters to be able to see. The lana is repeated there, even - * though I don't use it internally--it's for transports to use reenabling + * though I don't use it internally--it's for transports to use re-enabling * adapters using NetBIOSEnableAdapter. */ typedef struct _NetBIOSAdapter @@ -858,3 +858,48 @@ UCHAR WINAPI Netbios(PNCB ncb) TRACE("returning 0x%02x\n", ret); return ret; } + +DWORD WINAPI NetpNetBiosStatusToApiStatus(DWORD nrc) +{ + DWORD ret; + + switch (nrc) + { + case NRC_GOODRET: + ret = NO_ERROR; + break; + case NRC_NORES: + ret = NERR_NoNetworkResource; + break; + case NRC_DUPNAME: + ret = NERR_AlreadyExists; + break; + case NRC_NAMTFUL: + ret = NERR_TooManyNames; + break; + case NRC_ACTSES: + ret = NERR_DeleteLater; + break; + case NRC_REMTFUL: + ret = ERROR_REM_NOT_LIST; + break; + case NRC_NOCALL: + ret = NERR_NameNotFound; + break; + case NRC_NOWILD: + ret = ERROR_INVALID_PARAMETER; + break; + case NRC_INUSE: + ret = NERR_DuplicateName; + break; + case NRC_NAMERR: + ret = ERROR_INVALID_PARAMETER; + break; + case NRC_NAMCONF: + ret = NERR_DuplicateName; + break; + default: + ret = NERR_NetworkError; + } + return ret; +} diff --git a/dll/win32/netapi32/netbios.h b/dll/win32/netapi32/netbios.h index b211af28b10..76499848ad7 100644 --- a/dll/win32/netapi32/netbios.h +++ b/dll/win32/netapi32/netbios.h @@ -26,8 +26,8 @@ * Public functions */ -void NetBIOSInit(void); -void NetBIOSShutdown(void); +void NetBIOSInit(void) DECLSPEC_HIDDEN; +void NetBIOSShutdown(void) DECLSPEC_HIDDEN; struct _NetBIOSTransport; @@ -35,7 +35,7 @@ struct _NetBIOSTransport; * a unique id (the transport_id of ACTION_HEADER, for example) and an * implementation. Returns TRUE on success, and FALSE on failure. */ -BOOL NetBIOSRegisterTransport(ULONG id, struct _NetBIOSTransport *transport); +BOOL NetBIOSRegisterTransport(ULONG id, struct _NetBIOSTransport *transport) DECLSPEC_HIDDEN; /* Registers an adapter with the given transport and ifIndex with NetBIOS. * ifIndex is an interface index usable by the IpHlpApi. ifIndex is not @@ -45,21 +45,21 @@ BOOL NetBIOSRegisterTransport(ULONG id, struct _NetBIOSTransport *transport); * FIXME: need functions for retrieving the name and hardware index, rather * than assuming a correlation with IpHlpApi. */ -BOOL NetBIOSRegisterAdapter(ULONG transport, DWORD ifIndex, void *adapter); +BOOL NetBIOSRegisterAdapter(ULONG transport, DWORD ifIndex, void *adapter) DECLSPEC_HIDDEN; /* During enumeration, all adapters from your transport are disabled - * internally. If an adapter is still valid, reenable it with this function. + * internally. If an adapter is still valid, re-enable it with this function. * Adapters you don't enable will have their transport's NetBIOSCleanupAdapter * function (see below) called on them, and will be removed from the table. * (This is to deal with lack of plug-and-play--sorry.) */ -void NetBIOSEnableAdapter(UCHAR lana); +void NetBIOSEnableAdapter(UCHAR lana) DECLSPEC_HIDDEN; /* Gets a quick count of the number of NetBIOS adapters. Not guaranteed not * to change from one call to the next, depending on what's been enumerated * lately. See also NetBIOSEnumAdapters. */ -UCHAR NetBIOSNumAdapters(void); +UCHAR NetBIOSNumAdapters(void) DECLSPEC_HIDDEN; typedef struct _NetBIOSAdapterImpl { UCHAR lana; @@ -78,7 +78,7 @@ typedef BOOL (*NetBIOSEnumAdaptersCallback)(UCHAR totalLANAs, UCHAR lanaIndex, * Your callback should return FALSE if it no longer wishes to be called. */ void NetBIOSEnumAdapters(ULONG transport, NetBIOSEnumAdaptersCallback cb, - void *closure); + void *closure) DECLSPEC_HIDDEN; /* Hangs up the session identified in the NCB; the NCB need not be a NCBHANGUP. * Will result in the transport's hangup function being called, so release any @@ -86,7 +86,7 @@ void NetBIOSEnumAdapters(ULONG transport, NetBIOSEnumAdaptersCallback cb, * This function is intended for use by a transport, if the session is closed * by some error in the transport layer. */ -void NetBIOSHangupSession(const NCB *ncb); +void NetBIOSHangupSession(const NCB *ncb) DECLSPEC_HIDDEN; /** * Functions a transport implementation must implement @@ -172,6 +172,6 @@ typedef struct _NetBIOSTransport /* Not defined by MS, so make my own private define: */ #define TRANSPORT_NBT "MNBT" -void NetBTInit(void); +void NetBTInit(void) DECLSPEC_HIDDEN; #endif /* ndef __WINE_NETBIOS_H__ */ diff --git a/dll/win32/netapi32/wksta.c b/dll/win32/netapi32/wksta.c index 4cef46cd02e..4e5d8d6e128 100644 --- a/dll/win32/netapi32/wksta.c +++ b/dll/win32/netapi32/wksta.c @@ -30,29 +30,17 @@ WINE_DEFAULT_DEBUG_CHANNEL(netapi32); * * Checks whether the server name indicates local machine. */ -BOOL NETAPI_IsLocalComputer(LMCSTR ServerName) +DECLSPEC_HIDDEN BOOL NETAPI_IsLocalComputer( LMCSTR name ) { - if (!ServerName) - { - return TRUE; - } - else if (ServerName[0] == '\0') - return TRUE; - else - { - DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1; - BOOL Result; - LPWSTR buf; + WCHAR buf[MAX_COMPUTERNAME_LENGTH + 1]; + DWORD size = sizeof(buf) / sizeof(buf[0]); + BOOL ret; - NetApiBufferAllocate(dwSize * sizeof(WCHAR), (LPVOID *) &buf); - Result = GetComputerNameW(buf, &dwSize); - if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\')) - ServerName += 2; - Result = Result && !lstrcmpW(ServerName, buf); - NetApiBufferFree(buf); + if (!name || !name[0]) return TRUE; - return Result; - } + ret = GetComputerNameW( buf, &size ); + if (ret && name[0] == '\\' && name[1] == '\\') name += 2; + return ret && !strcmpiW( name, buf ); } static void wprint_mac(WCHAR* buffer, int len, const MIB_IFROW *ifRow) diff --git a/dll/win32/netcfgx/tcpipconf_notify.c b/dll/win32/netcfgx/tcpipconf_notify.c index 7f53c298f5f..1ba4eeb122e 100644 --- a/dll/win32/netcfgx/tcpipconf_notify.c +++ b/dll/win32/netcfgx/tcpipconf_notify.c @@ -3141,7 +3141,7 @@ INetCfgComponentControl_fnApplyRegistryChanges( //MessageBoxW(NULL, L"INetCfgComponentControl_fnApplyRegistryChanges", NULL, MB_OK); - if (RegCreateKeyExW(hKey, L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS) + if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS) { if (pCurrentConfig->pDNS) { diff --git a/dll/win32/objsel/objsel_classes.idl b/dll/win32/objsel/objsel_classes.idl index 0bd05bbf9bb..20926947305 100644 --- a/dll/win32/objsel/objsel_classes.idl +++ b/dll/win32/objsel/objsel_classes.idl @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma makedep register + [ threading(both), uuid(17d6ccd8-3b7b-11d2-b9e0-00c04fd8dbf7) diff --git a/dll/win32/propsys/propstore.c b/dll/win32/propsys/propstore.c index a7387715bba..9669fef0b4d 100644 --- a/dll/win32/propsys/propstore.c +++ b/dll/win32/propsys/propstore.c @@ -190,7 +190,7 @@ static HRESULT WINAPI PropertyStore_GetAt(IPropertyStoreCache *iface, } static HRESULT PropertyStore_LookupValue(PropertyStore *This, REFPROPERTYKEY key, - int insert, propstore_value **result) + BOOL insert, propstore_value **result) { propstore_format *format=NULL, *format_candidate; propstore_value *value=NULL, *value_candidate; @@ -268,7 +268,7 @@ static HRESULT WINAPI PropertyStore_GetValue(IPropertyStoreCache *iface, EnterCriticalSection(&This->lock); - hr = PropertyStore_LookupValue(This, key, 0, &value); + hr = PropertyStore_LookupValue(This, key, FALSE, &value); if (SUCCEEDED(hr)) hr = PropVariantCopy(pv, &value->propvar); @@ -295,7 +295,7 @@ static HRESULT WINAPI PropertyStore_SetValue(IPropertyStoreCache *iface, EnterCriticalSection(&This->lock); - hr = PropertyStore_LookupValue(This, key, 1, &value); + hr = PropertyStore_LookupValue(This, key, TRUE, &value); if (SUCCEEDED(hr)) hr = PropVariantCopy(&temp, propvar); @@ -328,7 +328,7 @@ static HRESULT WINAPI PropertyStore_GetState(IPropertyStoreCache *iface, EnterCriticalSection(&This->lock); - hr = PropertyStore_LookupValue(This, key, 0, &value); + hr = PropertyStore_LookupValue(This, key, FALSE, &value); if (SUCCEEDED(hr)) *pstate = value->state; @@ -352,7 +352,7 @@ static HRESULT WINAPI PropertyStore_GetValueAndState(IPropertyStoreCache *iface, EnterCriticalSection(&This->lock); - hr = PropertyStore_LookupValue(This, key, 0, &value); + hr = PropertyStore_LookupValue(This, key, FALSE, &value); if (SUCCEEDED(hr)) hr = PropVariantCopy(ppropvar, &value->propvar); @@ -382,7 +382,7 @@ static HRESULT WINAPI PropertyStore_SetState(IPropertyStoreCache *iface, EnterCriticalSection(&This->lock); - hr = PropertyStore_LookupValue(This, key, 0, &value); + hr = PropertyStore_LookupValue(This, key, FALSE, &value); if (SUCCEEDED(hr)) value->state = pstate; @@ -404,7 +404,7 @@ static HRESULT WINAPI PropertyStore_SetValueAndState(IPropertyStoreCache *iface, EnterCriticalSection(&This->lock); - hr = PropertyStore_LookupValue(This, key, 1, &value); + hr = PropertyStore_LookupValue(This, key, TRUE, &value); if (SUCCEEDED(hr)) hr = PropVariantCopy(&temp, ppropvar); diff --git a/dll/win32/propsys/propsys.spec b/dll/win32/propsys/propsys.spec index 26bdc0b4768..bd1daa15c7f 100644 --- a/dll/win32/propsys/propsys.spec +++ b/dll/win32/propsys/propsys.spec @@ -82,7 +82,7 @@ @ stub PSGetNamedPropertyFromPropertyStorage @ stdcall PSGetPropertyDescription(ptr ptr ptr) @ stub PSGetPropertyDescriptionByName -@ stub PSGetPropertyDescriptionListFromString +@ stdcall PSGetPropertyDescriptionListFromString(ptr ptr ptr) @ stub PSGetPropertyFromPropertyStorage @ stub PSGetPropertyKeyFromName @ stub PSGetPropertySystem diff --git a/dll/win32/propsys/propsys_classes.idl b/dll/win32/propsys/propsys_classes.idl index 28c23f22cf8..02555a37d26 100644 --- a/dll/win32/propsys/propsys_classes.idl +++ b/dll/win32/propsys/propsys_classes.idl @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma makedep register + [ helpstring("Packed Property Storage Object"), threading(both), diff --git a/dll/win32/propsys/propsys_main.c b/dll/win32/propsys/propsys_main.c index 7a4cd612809..48f7f440795 100644 --- a/dll/win32/propsys/propsys_main.c +++ b/dll/win32/propsys/propsys_main.c @@ -146,6 +146,12 @@ HRESULT WINAPI PSGetPropertyDescription(REFPROPERTYKEY propkey, REFIID riid, voi return E_NOTIMPL; } +HRESULT WINAPI PSGetPropertyDescriptionListFromString(LPCWSTR proplist, REFIID riid, void **ppv) +{ + FIXME("%s, %p, %p\n", debugstr_w(proplist), riid, ppv); + return E_NOTIMPL; +} + HRESULT WINAPI PSRefreshPropertySchema(void) { FIXME("\n"); @@ -302,7 +308,7 @@ static BOOL string_to_guid(LPCWSTR s, LPGUID id) HRESULT WINAPI PSPropertyKeyFromString(LPCWSTR pszString, PROPERTYKEY *pkey) { - int has_minus = 0, has_comma = 0; + BOOL has_minus = FALSE, has_comma = FALSE; TRACE("(%s, %p)\n", debugstr_w(pszString), pkey); @@ -328,7 +334,7 @@ HRESULT WINAPI PSPropertyKeyFromString(LPCWSTR pszString, PROPERTYKEY *pkey) if (has_comma) return S_OK; else - has_comma = 1; + has_comma = TRUE; } pszString++; } @@ -344,7 +350,7 @@ HRESULT WINAPI PSPropertyKeyFromString(LPCWSTR pszString, PROPERTYKEY *pkey) { if (*pszString == '-') { - has_minus = 1; + has_minus = TRUE; pszString++; } } @@ -359,7 +365,7 @@ HRESULT WINAPI PSPropertyKeyFromString(LPCWSTR pszString, PROPERTYKEY *pkey) if (*pszString == '-') { - has_minus = 1; + has_minus = TRUE; pszString++; } diff --git a/dll/win32/propsys/propvar.c b/dll/win32/propsys/propvar.c index 2a9a69c2faf..0af26f313b0 100644 --- a/dll/win32/propsys/propvar.c +++ b/dll/win32/propsys/propvar.c @@ -58,46 +58,46 @@ static HRESULT PROPVAR_ConvertFILETIME(PROPVARIANT *ppropvarDest, } static HRESULT PROPVAR_ConvertNumber(REFPROPVARIANT pv, int dest_bits, - int dest_signed, LONGLONG *res) + BOOL dest_signed, LONGLONG *res) { - int src_signed; + BOOL src_signed; switch (pv->vt) { case VT_I1: - src_signed = 1; + src_signed = TRUE; *res = pv->u.cVal; break; case VT_UI1: - src_signed = 0; + src_signed = FALSE; *res = pv->u.bVal; break; case VT_I2: - src_signed = 1; + src_signed = TRUE; *res = pv->u.iVal; break; case VT_UI2: - src_signed = 0; + src_signed = FALSE; *res = pv->u.uiVal; break; case VT_I4: - src_signed = 1; + src_signed = TRUE; *res = pv->u.lVal; break; case VT_UI4: - src_signed = 0; + src_signed = FALSE; *res = pv->u.ulVal; break; case VT_I8: - src_signed = 1; + src_signed = TRUE; *res = pv->u.hVal.QuadPart; break; case VT_UI8: - src_signed = 0; + src_signed = FALSE; *res = pv->u.uhVal.QuadPart; break; case VT_EMPTY: - src_signed = 0; + src_signed = FALSE; *res = 0; break; default: @@ -133,7 +133,7 @@ HRESULT WINAPI PropVariantToInt16(REFPROPVARIANT propvarIn, SHORT *ret) TRACE("%p,%p\n", propvarIn, ret); - hr = PROPVAR_ConvertNumber(propvarIn, 16, 1, &res); + hr = PROPVAR_ConvertNumber(propvarIn, 16, TRUE, &res); if (SUCCEEDED(hr)) *ret = (SHORT)res; return hr; } @@ -145,7 +145,7 @@ HRESULT WINAPI PropVariantToInt32(REFPROPVARIANT propvarIn, LONG *ret) TRACE("%p,%p\n", propvarIn, ret); - hr = PROPVAR_ConvertNumber(propvarIn, 32, 1, &res); + hr = PROPVAR_ConvertNumber(propvarIn, 32, TRUE, &res); if (SUCCEEDED(hr)) *ret = (LONG)res; return hr; } @@ -157,7 +157,7 @@ HRESULT WINAPI PropVariantToInt64(REFPROPVARIANT propvarIn, LONGLONG *ret) TRACE("%p,%p\n", propvarIn, ret); - hr = PROPVAR_ConvertNumber(propvarIn, 64, 1, &res); + hr = PROPVAR_ConvertNumber(propvarIn, 64, TRUE, &res); if (SUCCEEDED(hr)) *ret = (LONGLONG)res; return hr; } @@ -169,7 +169,7 @@ HRESULT WINAPI PropVariantToUInt16(REFPROPVARIANT propvarIn, USHORT *ret) TRACE("%p,%p\n", propvarIn, ret); - hr = PROPVAR_ConvertNumber(propvarIn, 16, 0, &res); + hr = PROPVAR_ConvertNumber(propvarIn, 16, FALSE, &res); if (SUCCEEDED(hr)) *ret = (USHORT)res; return hr; } @@ -181,7 +181,7 @@ HRESULT WINAPI PropVariantToUInt32(REFPROPVARIANT propvarIn, ULONG *ret) TRACE("%p,%p\n", propvarIn, ret); - hr = PROPVAR_ConvertNumber(propvarIn, 32, 0, &res); + hr = PROPVAR_ConvertNumber(propvarIn, 32, FALSE, &res); if (SUCCEEDED(hr)) *ret = (ULONG)res; return hr; } @@ -193,7 +193,7 @@ HRESULT WINAPI PropVariantToUInt64(REFPROPVARIANT propvarIn, ULONGLONG *ret) TRACE("%p,%p\n", propvarIn, ret); - hr = PROPVAR_ConvertNumber(propvarIn, 64, 0, &res); + hr = PROPVAR_ConvertNumber(propvarIn, 64, FALSE, &res); if (SUCCEEDED(hr)) *ret = (ULONGLONG)res; return hr; } @@ -486,10 +486,10 @@ HRESULT WINAPI VariantToGUID(const VARIANT *pvar, GUID *guid) } } -static int isemptyornull(const PROPVARIANT *propvar) +static BOOL isemptyornull(const PROPVARIANT *propvar) { if (propvar->vt == VT_EMPTY || propvar->vt == VT_NULL) - return 1; + return TRUE; if ((propvar->vt & VT_ARRAY) == VT_ARRAY) { int i; @@ -501,7 +501,7 @@ static int isemptyornull(const PROPVARIANT *propvar) return i == propvar->u.parray->cDims; } /* FIXME: vectors, byrefs, errors? */ - return 0; + return FALSE; } INT WINAPI PropVariantCompareEx(REFPROPVARIANT propvar1, REFPROPVARIANT propvar2, diff --git a/dll/win32/psapi/psapi.c b/dll/win32/psapi/psapi.c index bd0f0db0661..3971eec7a8b 100644 --- a/dll/win32/psapi/psapi.c +++ b/dll/win32/psapi/psapi.c @@ -1381,7 +1381,7 @@ EnumPageFilesW(PENUM_PAGE_FILE_CALLBACKW pCallbackRoutine, if (Colon != 0 && Colon != PageFileInfo->PageFileName.Buffer) { /* We can call the user callback routine with the colon */ - Colon -= sizeof(WCHAR); + --Colon; pCallbackRoutine(lpContext, &Information, Colon); } diff --git a/dll/win32/pstorec/pstorec_tlb.idl b/dll/win32/pstorec/pstorec_tlb.idl index dff2e9fcb3b..13d77501f71 100644 --- a/dll/win32/pstorec/pstorec_tlb.idl +++ b/dll/win32/pstorec/pstorec_tlb.idl @@ -18,4 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma makedep regtypelib + #include "pstore.idl" diff --git a/dll/win32/qmgr/CMakeLists.txt b/dll/win32/qmgr/CMakeLists.txt index e3cdc684526..c1695c288b9 100644 --- a/dll/win32/qmgr/CMakeLists.txt +++ b/dll/win32/qmgr/CMakeLists.txt @@ -21,7 +21,7 @@ add_library(qmgr SHARED rsrc.rc ${CMAKE_CURRENT_BINARY_DIR}/qmgr.def) -set_source_files_properties(rsrc.rc PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/qmgr.inf) +set_source_files_properties(rsrc.rc PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/qmgr.rgs) add_idl_headers(qmgr_idlheader qmgr_local.idl) set_module_type(qmgr win32dll) target_link_libraries(qmgr uuid wine) diff --git a/dll/win32/qmgr/enum_files.c b/dll/win32/qmgr/enum_files.c index 8b01fd301de..c7648a7db9a 100644 --- a/dll/win32/qmgr/enum_files.c +++ b/dll/win32/qmgr/enum_files.c @@ -34,10 +34,12 @@ static inline EnumBackgroundCopyFilesImpl *impl_from_IEnumBackgroundCopyFiles(IE return CONTAINING_RECORD(iface, EnumBackgroundCopyFilesImpl, IEnumBackgroundCopyFiles_iface); } -static HRESULT WINAPI BITS_IEnumBackgroundCopyFiles_QueryInterface(IEnumBackgroundCopyFiles *iface, +static HRESULT WINAPI EnumBackgroundCopyFiles_QueryInterface(IEnumBackgroundCopyFiles *iface, REFIID riid, void **ppv) { - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv); + EnumBackgroundCopyFilesImpl *This = impl_from_IEnumBackgroundCopyFiles(iface); + + TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv); if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IEnumBackgroundCopyFiles)) { @@ -50,21 +52,23 @@ static HRESULT WINAPI BITS_IEnumBackgroundCopyFiles_QueryInterface(IEnumBackgrou return E_NOINTERFACE; } -static ULONG WINAPI BITS_IEnumBackgroundCopyFiles_AddRef(IEnumBackgroundCopyFiles *iface) +static ULONG WINAPI EnumBackgroundCopyFiles_AddRef(IEnumBackgroundCopyFiles *iface) { EnumBackgroundCopyFilesImpl *This = impl_from_IEnumBackgroundCopyFiles(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) ref=%d\n", This, ref); + TRACE("(%p)->(%d)\n", This, ref); return ref; } -static ULONG WINAPI BITS_IEnumBackgroundCopyFiles_Release(IEnumBackgroundCopyFiles *iface) +static ULONG WINAPI EnumBackgroundCopyFiles_Release(IEnumBackgroundCopyFiles *iface) { EnumBackgroundCopyFilesImpl *This = impl_from_IEnumBackgroundCopyFiles(iface); ULONG ref = InterlockedDecrement(&This->ref); ULONG i; + TRACE("(%p)->(%d)\n", This, ref); + if (ref == 0) { for(i = 0; i < This->numFiles; i++) @@ -77,7 +81,7 @@ static ULONG WINAPI BITS_IEnumBackgroundCopyFiles_Release(IEnumBackgroundCopyFil } /* Return reference to one or more files in the file enumerator */ -static HRESULT WINAPI BITS_IEnumBackgroundCopyFiles_Next(IEnumBackgroundCopyFiles *iface, +static HRESULT WINAPI EnumBackgroundCopyFiles_Next(IEnumBackgroundCopyFiles *iface, ULONG celt, IBackgroundCopyFile **rgelt, ULONG *pceltFetched) { EnumBackgroundCopyFilesImpl *This = impl_from_IEnumBackgroundCopyFiles(iface); @@ -85,6 +89,8 @@ static HRESULT WINAPI BITS_IEnumBackgroundCopyFiles_Next(IEnumBackgroundCopyFile ULONG i; IBackgroundCopyFile *file; + TRACE("(%p)->(%d %p %p)\n", This, celt, rgelt, pceltFetched); + /* Despite documented behavior, Windows (tested on XP) is not verifying that the caller set pceltFetched to zero. No check here. */ @@ -115,11 +121,13 @@ static HRESULT WINAPI BITS_IEnumBackgroundCopyFiles_Next(IEnumBackgroundCopyFile } /* Skip over one or more files in the file enumerator */ -static HRESULT WINAPI BITS_IEnumBackgroundCopyFiles_Skip(IEnumBackgroundCopyFiles *iface, +static HRESULT WINAPI EnumBackgroundCopyFiles_Skip(IEnumBackgroundCopyFiles *iface, ULONG celt) { EnumBackgroundCopyFilesImpl *This = impl_from_IEnumBackgroundCopyFiles(iface); + TRACE("(%p)->(%d)\n", This, celt); + if (celt > This->numFiles - This->indexFiles) { This->indexFiles = This->numFiles; @@ -130,38 +138,43 @@ static HRESULT WINAPI BITS_IEnumBackgroundCopyFiles_Skip(IEnumBackgroundCopyFile return S_OK; } -static HRESULT WINAPI BITS_IEnumBackgroundCopyFiles_Reset(IEnumBackgroundCopyFiles *iface) +static HRESULT WINAPI EnumBackgroundCopyFiles_Reset(IEnumBackgroundCopyFiles *iface) { EnumBackgroundCopyFilesImpl *This = impl_from_IEnumBackgroundCopyFiles(iface); + + TRACE("(%p)\n", This); + This->indexFiles = 0; return S_OK; } -static HRESULT WINAPI BITS_IEnumBackgroundCopyFiles_Clone(IEnumBackgroundCopyFiles *iface, +static HRESULT WINAPI EnumBackgroundCopyFiles_Clone(IEnumBackgroundCopyFiles *iface, IEnumBackgroundCopyFiles **ppenum) { - FIXME("Not implemented\n"); + EnumBackgroundCopyFilesImpl *This = impl_from_IEnumBackgroundCopyFiles(iface); + FIXME("(%p)->(%p): stub\n", This, ppenum); return E_NOTIMPL; } -static HRESULT WINAPI BITS_IEnumBackgroundCopyFiles_GetCount(IEnumBackgroundCopyFiles *iface, +static HRESULT WINAPI EnumBackgroundCopyFiles_GetCount(IEnumBackgroundCopyFiles *iface, ULONG *puCount) { EnumBackgroundCopyFilesImpl *This = impl_from_IEnumBackgroundCopyFiles(iface); + TRACE("(%p)->(%p)\n", This, puCount); *puCount = This->numFiles; return S_OK; } -static const IEnumBackgroundCopyFilesVtbl BITS_IEnumBackgroundCopyFiles_Vtbl = +static const IEnumBackgroundCopyFilesVtbl EnumBackgroundCopyFilesVtbl = { - BITS_IEnumBackgroundCopyFiles_QueryInterface, - BITS_IEnumBackgroundCopyFiles_AddRef, - BITS_IEnumBackgroundCopyFiles_Release, - BITS_IEnumBackgroundCopyFiles_Next, - BITS_IEnumBackgroundCopyFiles_Skip, - BITS_IEnumBackgroundCopyFiles_Reset, - BITS_IEnumBackgroundCopyFiles_Clone, - BITS_IEnumBackgroundCopyFiles_GetCount + EnumBackgroundCopyFiles_QueryInterface, + EnumBackgroundCopyFiles_AddRef, + EnumBackgroundCopyFiles_Release, + EnumBackgroundCopyFiles_Next, + EnumBackgroundCopyFiles_Skip, + EnumBackgroundCopyFiles_Reset, + EnumBackgroundCopyFiles_Clone, + EnumBackgroundCopyFiles_GetCount }; HRESULT EnumBackgroundCopyFilesConstructor(BackgroundCopyJobImpl *job, IEnumBackgroundCopyFiles **enum_files) @@ -176,7 +189,7 @@ HRESULT EnumBackgroundCopyFilesConstructor(BackgroundCopyJobImpl *job, IEnumBack if (!This) return E_OUTOFMEMORY; - This->IEnumBackgroundCopyFiles_iface.lpVtbl = &BITS_IEnumBackgroundCopyFiles_Vtbl; + This->IEnumBackgroundCopyFiles_iface.lpVtbl = &EnumBackgroundCopyFilesVtbl; This->ref = 1; /* Create array of files */ diff --git a/dll/win32/qmgr/enum_jobs.c b/dll/win32/qmgr/enum_jobs.c index 6af19be5b97..5dd5d3b083d 100644 --- a/dll/win32/qmgr/enum_jobs.c +++ b/dll/win32/qmgr/enum_jobs.c @@ -34,10 +34,12 @@ static inline EnumBackgroundCopyJobsImpl *impl_from_IEnumBackgroundCopyJobs(IEnu return CONTAINING_RECORD(iface, EnumBackgroundCopyJobsImpl, IEnumBackgroundCopyJobs_iface); } -static HRESULT WINAPI BITS_IEnumBackgroundCopyJobs_QueryInterface(IEnumBackgroundCopyJobs *iface, +static HRESULT WINAPI EnumBackgroundCopyJobs_QueryInterface(IEnumBackgroundCopyJobs *iface, REFIID riid, void **ppv) { - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv); + EnumBackgroundCopyJobsImpl *This = impl_from_IEnumBackgroundCopyJobs(iface); + + TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv); if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IEnumBackgroundCopyJobs)) { @@ -50,23 +52,23 @@ static HRESULT WINAPI BITS_IEnumBackgroundCopyJobs_QueryInterface(IEnumBackgroun return E_NOINTERFACE; } -static ULONG WINAPI BITS_IEnumBackgroundCopyJobs_AddRef(IEnumBackgroundCopyJobs *iface) +static ULONG WINAPI EnumBackgroundCopyJobs_AddRef(IEnumBackgroundCopyJobs *iface) { EnumBackgroundCopyJobsImpl *This = impl_from_IEnumBackgroundCopyJobs(iface); ULONG ref = InterlockedIncrement(&This->ref); - TRACE("(%p) ref=%d\n", This, ref); + TRACE("(%p)->(%d)\n", This, ref); return ref; } -static ULONG WINAPI BITS_IEnumBackgroundCopyJobs_Release(IEnumBackgroundCopyJobs *iface) +static ULONG WINAPI EnumBackgroundCopyJobs_Release(IEnumBackgroundCopyJobs *iface) { EnumBackgroundCopyJobsImpl *This = impl_from_IEnumBackgroundCopyJobs(iface); ULONG ref = InterlockedDecrement(&This->ref); ULONG i; - TRACE("(%p) ref=%d\n", This, ref); + TRACE("(%p)->(%d)\n", This, ref); if (ref == 0) { for(i = 0; i < This->numJobs; i++) @@ -78,7 +80,7 @@ static ULONG WINAPI BITS_IEnumBackgroundCopyJobs_Release(IEnumBackgroundCopyJobs return ref; } -static HRESULT WINAPI BITS_IEnumBackgroundCopyJobs_Next(IEnumBackgroundCopyJobs *iface, ULONG celt, +static HRESULT WINAPI EnumBackgroundCopyJobs_Next(IEnumBackgroundCopyJobs *iface, ULONG celt, IBackgroundCopyJob **rgelt, ULONG *pceltFetched) { EnumBackgroundCopyJobsImpl *This = impl_from_IEnumBackgroundCopyJobs(iface); @@ -86,6 +88,8 @@ static HRESULT WINAPI BITS_IEnumBackgroundCopyJobs_Next(IEnumBackgroundCopyJobs ULONG i; IBackgroundCopyJob *job; + TRACE("(%p)->(%d %p %p)\n", This, celt, rgelt, pceltFetched); + fetched = min(celt, This->numJobs - This->indexJobs); if (pceltFetched) *pceltFetched = fetched; @@ -112,10 +116,12 @@ static HRESULT WINAPI BITS_IEnumBackgroundCopyJobs_Next(IEnumBackgroundCopyJobs return fetched == celt ? S_OK : S_FALSE; } -static HRESULT WINAPI BITS_IEnumBackgroundCopyJobs_Skip(IEnumBackgroundCopyJobs *iface, ULONG celt) +static HRESULT WINAPI EnumBackgroundCopyJobs_Skip(IEnumBackgroundCopyJobs *iface, ULONG celt) { EnumBackgroundCopyJobsImpl *This = impl_from_IEnumBackgroundCopyJobs(iface); + TRACE("(%p)->(%d)\n", This, celt); + if (This->numJobs - This->indexJobs < celt) { This->indexJobs = This->numJobs; @@ -126,38 +132,45 @@ static HRESULT WINAPI BITS_IEnumBackgroundCopyJobs_Skip(IEnumBackgroundCopyJobs return S_OK; } -static HRESULT WINAPI BITS_IEnumBackgroundCopyJobs_Reset(IEnumBackgroundCopyJobs *iface) +static HRESULT WINAPI EnumBackgroundCopyJobs_Reset(IEnumBackgroundCopyJobs *iface) { EnumBackgroundCopyJobsImpl *This = impl_from_IEnumBackgroundCopyJobs(iface); + + TRACE("(%p)\n", This); + This->indexJobs = 0; return S_OK; } -static HRESULT WINAPI BITS_IEnumBackgroundCopyJobs_Clone(IEnumBackgroundCopyJobs *iface, +static HRESULT WINAPI EnumBackgroundCopyJobs_Clone(IEnumBackgroundCopyJobs *iface, IEnumBackgroundCopyJobs **ppenum) { - FIXME("Not implemented\n"); + EnumBackgroundCopyJobsImpl *This = impl_from_IEnumBackgroundCopyJobs(iface); + FIXME("(%p)->(%p): stub\n", This, ppenum); return E_NOTIMPL; } -static HRESULT WINAPI BITS_IEnumBackgroundCopyJobs_GetCount(IEnumBackgroundCopyJobs *iface, +static HRESULT WINAPI EnumBackgroundCopyJobs_GetCount(IEnumBackgroundCopyJobs *iface, ULONG *puCount) { EnumBackgroundCopyJobsImpl *This = impl_from_IEnumBackgroundCopyJobs(iface); + + TRACE("(%p)->(%p)\n", This, puCount); + *puCount = This->numJobs; return S_OK; } -static const IEnumBackgroundCopyJobsVtbl BITS_IEnumBackgroundCopyJobs_Vtbl = +static const IEnumBackgroundCopyJobsVtbl EnumBackgroundCopyJobsVtbl = { - BITS_IEnumBackgroundCopyJobs_QueryInterface, - BITS_IEnumBackgroundCopyJobs_AddRef, - BITS_IEnumBackgroundCopyJobs_Release, - BITS_IEnumBackgroundCopyJobs_Next, - BITS_IEnumBackgroundCopyJobs_Skip, - BITS_IEnumBackgroundCopyJobs_Reset, - BITS_IEnumBackgroundCopyJobs_Clone, - BITS_IEnumBackgroundCopyJobs_GetCount + EnumBackgroundCopyJobs_QueryInterface, + EnumBackgroundCopyJobs_AddRef, + EnumBackgroundCopyJobs_Release, + EnumBackgroundCopyJobs_Next, + EnumBackgroundCopyJobs_Skip, + EnumBackgroundCopyJobs_Reset, + EnumBackgroundCopyJobs_Clone, + EnumBackgroundCopyJobs_GetCount }; HRESULT enum_copy_job_create(BackgroundCopyManagerImpl *qmgr, IEnumBackgroundCopyJobs **enumjob) @@ -171,7 +184,7 @@ HRESULT enum_copy_job_create(BackgroundCopyManagerImpl *qmgr, IEnumBackgroundCop This = HeapAlloc(GetProcessHeap(), 0, sizeof *This); if (!This) return E_OUTOFMEMORY; - This->IEnumBackgroundCopyJobs_iface.lpVtbl = &BITS_IEnumBackgroundCopyJobs_Vtbl; + This->IEnumBackgroundCopyJobs_iface.lpVtbl = &EnumBackgroundCopyJobsVtbl; This->ref = 1; /* Create array of jobs */ diff --git a/dll/win32/qmgr/factory.c b/dll/win32/qmgr/factory.c index 7a069f3e92e..69e6d98d6c3 100644 --- a/dll/win32/qmgr/factory.c +++ b/dll/win32/qmgr/factory.c @@ -57,7 +57,7 @@ BITS_IClassFactory_CreateInstance(IClassFactory *iface, IUnknown *pUnkOuter, REF if (pUnkOuter) return CLASS_E_NOAGGREGATION; - res = BackgroundCopyManagerConstructor(pUnkOuter, (LPVOID*) &punk); + res = BackgroundCopyManagerConstructor((LPVOID*) &punk); if (FAILED(res)) return res; diff --git a/dll/win32/qmgr/file.c b/dll/win32/qmgr/file.c index 6ba493ae142..1aee9b8700b 100644 --- a/dll/win32/qmgr/file.c +++ b/dll/win32/qmgr/file.c @@ -28,7 +28,7 @@ static inline BackgroundCopyFileImpl *impl_from_IBackgroundCopyFile(IBackgroundC return CONTAINING_RECORD(iface, BackgroundCopyFileImpl, IBackgroundCopyFile_iface); } -static HRESULT WINAPI BITS_IBackgroundCopyFile_QueryInterface( +static HRESULT WINAPI BackgroundCopyFile_QueryInterface( IBackgroundCopyFile* iface, REFIID riid, void **obj) @@ -49,7 +49,7 @@ static HRESULT WINAPI BITS_IBackgroundCopyFile_QueryInterface( return E_NOINTERFACE; } -static ULONG WINAPI BITS_IBackgroundCopyFile_AddRef(IBackgroundCopyFile* iface) +static ULONG WINAPI BackgroundCopyFile_AddRef(IBackgroundCopyFile* iface) { BackgroundCopyFileImpl *This = impl_from_IBackgroundCopyFile(iface); ULONG ref = InterlockedIncrement(&This->ref); @@ -57,7 +57,7 @@ static ULONG WINAPI BITS_IBackgroundCopyFile_AddRef(IBackgroundCopyFile* iface) return ref; } -static ULONG WINAPI BITS_IBackgroundCopyFile_Release( +static ULONG WINAPI BackgroundCopyFile_Release( IBackgroundCopyFile* iface) { BackgroundCopyFileImpl *This = impl_from_IBackgroundCopyFile(iface); @@ -77,42 +77,36 @@ static ULONG WINAPI BITS_IBackgroundCopyFile_Release( } /* Get the remote name of a background copy file */ -static HRESULT WINAPI BITS_IBackgroundCopyFile_GetRemoteName( +static HRESULT WINAPI BackgroundCopyFile_GetRemoteName( IBackgroundCopyFile* iface, LPWSTR *pVal) { BackgroundCopyFileImpl *This = impl_from_IBackgroundCopyFile(iface); - int n = (lstrlenW(This->info.RemoteName) + 1) * sizeof(WCHAR); - *pVal = CoTaskMemAlloc(n); - if (!*pVal) - return E_OUTOFMEMORY; + TRACE("(%p)->(%p)\n", This, pVal); - memcpy(*pVal, This->info.RemoteName, n); - return S_OK; + return return_strval(This->info.RemoteName, pVal); } -static HRESULT WINAPI BITS_IBackgroundCopyFile_GetLocalName( +static HRESULT WINAPI BackgroundCopyFile_GetLocalName( IBackgroundCopyFile* iface, LPWSTR *pVal) { BackgroundCopyFileImpl *This = impl_from_IBackgroundCopyFile(iface); - int n = (lstrlenW(This->info.LocalName) + 1) * sizeof(WCHAR); - *pVal = CoTaskMemAlloc(n); - if (!*pVal) - return E_OUTOFMEMORY; + TRACE("(%p)->(%p)\n", This, pVal); - memcpy(*pVal, This->info.LocalName, n); - return S_OK; + return return_strval(This->info.LocalName, pVal); } -static HRESULT WINAPI BITS_IBackgroundCopyFile_GetProgress( +static HRESULT WINAPI BackgroundCopyFile_GetProgress( IBackgroundCopyFile* iface, BG_FILE_PROGRESS *pVal) { BackgroundCopyFileImpl *This = impl_from_IBackgroundCopyFile(iface); + TRACE("(%p)->(%p)\n", This, pVal); + EnterCriticalSection(&This->owner->cs); pVal->BytesTotal = This->fileProgress.BytesTotal; pVal->BytesTransferred = This->fileProgress.BytesTransferred; @@ -122,14 +116,14 @@ static HRESULT WINAPI BITS_IBackgroundCopyFile_GetProgress( return S_OK; } -static const IBackgroundCopyFileVtbl BITS_IBackgroundCopyFile_Vtbl = +static const IBackgroundCopyFileVtbl BackgroundCopyFileVtbl = { - BITS_IBackgroundCopyFile_QueryInterface, - BITS_IBackgroundCopyFile_AddRef, - BITS_IBackgroundCopyFile_Release, - BITS_IBackgroundCopyFile_GetRemoteName, - BITS_IBackgroundCopyFile_GetLocalName, - BITS_IBackgroundCopyFile_GetProgress + BackgroundCopyFile_QueryInterface, + BackgroundCopyFile_AddRef, + BackgroundCopyFile_Release, + BackgroundCopyFile_GetRemoteName, + BackgroundCopyFile_GetLocalName, + BackgroundCopyFile_GetProgress }; HRESULT BackgroundCopyFileConstructor(BackgroundCopyJobImpl *owner, @@ -164,7 +158,7 @@ HRESULT BackgroundCopyFileConstructor(BackgroundCopyJobImpl *owner, } memcpy(This->info.LocalName, localName, n); - This->IBackgroundCopyFile_iface.lpVtbl = &BITS_IBackgroundCopyFile_Vtbl; + This->IBackgroundCopyFile_iface.lpVtbl = &BackgroundCopyFileVtbl; This->ref = 1; This->fileProgress.BytesTotal = BG_SIZE_UNKNOWN; @@ -217,6 +211,25 @@ static inline DLBindStatusCallback *impl_from_IBindStatusCallback(IBindStatusCal return CONTAINING_RECORD(iface, DLBindStatusCallback, IBindStatusCallback_iface); } +static HRESULT WINAPI DLBindStatusCallback_QueryInterface( + IBindStatusCallback *iface, + REFIID riid, + void **ppvObject) +{ + DLBindStatusCallback *This = impl_from_IBindStatusCallback(iface); + + if (IsEqualGUID(riid, &IID_IUnknown) + || IsEqualGUID(riid, &IID_IBindStatusCallback)) + { + *ppvObject = &This->IBindStatusCallback_iface; + IBindStatusCallback_AddRef(iface); + return S_OK; + } + + *ppvObject = NULL; + return E_NOINTERFACE; +} + static ULONG WINAPI DLBindStatusCallback_AddRef(IBindStatusCallback *iface) { DLBindStatusCallback *This = impl_from_IBindStatusCallback(iface); @@ -237,25 +250,6 @@ static ULONG WINAPI DLBindStatusCallback_Release(IBindStatusCallback *iface) return ref; } -static HRESULT WINAPI DLBindStatusCallback_QueryInterface( - IBindStatusCallback *iface, - REFIID riid, - void **ppvObject) -{ - DLBindStatusCallback *This = impl_from_IBindStatusCallback(iface); - - if (IsEqualGUID(riid, &IID_IUnknown) - || IsEqualGUID(riid, &IID_IBindStatusCallback)) - { - *ppvObject = &This->IBindStatusCallback_iface; - DLBindStatusCallback_AddRef(iface); - return S_OK; - } - - *ppvObject = NULL; - return E_NOINTERFACE; -} - static HRESULT WINAPI DLBindStatusCallback_GetBindInfo( IBindStatusCallback *iface, DWORD *grfBINDF, diff --git a/dll/win32/qmgr/job.c b/dll/win32/qmgr/job.c index c4a2325e7ce..911def76657 100644 --- a/dll/win32/qmgr/job.c +++ b/dll/win32/qmgr/job.c @@ -20,12 +20,17 @@ #include "qmgr.h" +static inline BOOL is_job_done(const BackgroundCopyJobImpl *job) +{ + return job->state == BG_JOB_STATE_CANCELLED || job->state == BG_JOB_STATE_ACKNOWLEDGED; +} + static inline BackgroundCopyJobImpl *impl_from_IBackgroundCopyJob2(IBackgroundCopyJob2 *iface) { return CONTAINING_RECORD(iface, BackgroundCopyJobImpl, IBackgroundCopyJob2_iface); } -static HRESULT WINAPI BITS_IBackgroundCopyJob_QueryInterface( +static HRESULT WINAPI BackgroundCopyJob_QueryInterface( IBackgroundCopyJob2 *iface, REFIID riid, void **obj) { BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); @@ -45,7 +50,7 @@ static HRESULT WINAPI BITS_IBackgroundCopyJob_QueryInterface( return E_NOINTERFACE; } -static ULONG WINAPI BITS_IBackgroundCopyJob_AddRef(IBackgroundCopyJob2 *iface) +static ULONG WINAPI BackgroundCopyJob_AddRef(IBackgroundCopyJob2 *iface) { BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); ULONG ref = InterlockedIncrement(&This->ref); @@ -53,7 +58,7 @@ static ULONG WINAPI BITS_IBackgroundCopyJob_AddRef(IBackgroundCopyJob2 *iface) return ref; } -static ULONG WINAPI BITS_IBackgroundCopyJob_Release(IBackgroundCopyJob2 *iface) +static ULONG WINAPI BackgroundCopyJob_Release(IBackgroundCopyJob2 *iface) { BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); ULONG ref = InterlockedDecrement(&This->ref); @@ -64,7 +69,10 @@ static ULONG WINAPI BITS_IBackgroundCopyJob_Release(IBackgroundCopyJob2 *iface) { This->cs.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&This->cs); + if (This->callback) + IBackgroundCopyCallback2_Release(This->callback); HeapFree(GetProcessHeap(), 0, This->displayName); + HeapFree(GetProcessHeap(), 0, This->description); HeapFree(GetProcessHeap(), 0, This); } @@ -73,50 +81,56 @@ static ULONG WINAPI BITS_IBackgroundCopyJob_Release(IBackgroundCopyJob2 *iface) /*** IBackgroundCopyJob methods ***/ -static HRESULT WINAPI BITS_IBackgroundCopyJob_AddFileSet( +static HRESULT WINAPI BackgroundCopyJob_AddFileSet( IBackgroundCopyJob2 *iface, ULONG cFileCount, BG_FILE_INFO *pFileSet) { + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + HRESULT hr = S_OK; ULONG i; + + TRACE("(%p)->(%d %p)\n", This, cFileCount, pFileSet); + + EnterCriticalSection(&This->cs); + for (i = 0; i < cFileCount; ++i) { - HRESULT hr = IBackgroundCopyJob2_AddFile(iface, pFileSet[i].RemoteName, - pFileSet[i].LocalName); - if (FAILED(hr)) - return hr; + BackgroundCopyFileImpl *file; + + /* We should return E_INVALIDARG in these cases. */ + FIXME("Check for valid filenames and supported protocols\n"); + + hr = BackgroundCopyFileConstructor(This, pFileSet[i].RemoteName, pFileSet[i].LocalName, &file); + if (hr != S_OK) break; + + /* Add a reference to the file to file list */ + list_add_head(&This->files, &file->entryFromJob); + This->jobProgress.BytesTotal = BG_SIZE_UNKNOWN; + ++This->jobProgress.FilesTotal; } - return S_OK; + + LeaveCriticalSection(&This->cs); + + return hr; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_AddFile( +static HRESULT WINAPI BackgroundCopyJob_AddFile( IBackgroundCopyJob2 *iface, LPCWSTR RemoteUrl, LPCWSTR LocalName) { BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); - BackgroundCopyFileImpl *file; - HRESULT res; + BG_FILE_INFO file; - /* We should return E_INVALIDARG in these cases. */ - FIXME("Check for valid filenames and supported protocols\n"); + TRACE("(%p)->(%s %s)\n", This, debugstr_w(RemoteUrl), debugstr_w(LocalName)); - res = BackgroundCopyFileConstructor(This, RemoteUrl, LocalName, &file); - if (res != S_OK) - return res; - - /* Add a reference to the file to file list */ - IBackgroundCopyFile_AddRef(&file->IBackgroundCopyFile_iface); - EnterCriticalSection(&This->cs); - list_add_head(&This->files, &file->entryFromJob); - This->jobProgress.BytesTotal = BG_SIZE_UNKNOWN; - ++This->jobProgress.FilesTotal; - LeaveCriticalSection(&This->cs); - - return S_OK; + file.RemoteName = (LPWSTR)RemoteUrl; + file.LocalName = (LPWSTR)LocalName; + return IBackgroundCopyJob2_AddFileSet(iface, 1, &file); } -static HRESULT WINAPI BITS_IBackgroundCopyJob_EnumFiles( +static HRESULT WINAPI BackgroundCopyJob_EnumFiles( IBackgroundCopyJob2 *iface, IEnumBackgroundCopyFiles **enum_files) { @@ -125,22 +139,24 @@ static HRESULT WINAPI BITS_IBackgroundCopyJob_EnumFiles( return EnumBackgroundCopyFilesConstructor(This, enum_files); } -static HRESULT WINAPI BITS_IBackgroundCopyJob_Suspend( +static HRESULT WINAPI BackgroundCopyJob_Suspend( IBackgroundCopyJob2 *iface) { - FIXME("Not implemented\n"); + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + FIXME("(%p): stub\n", This); return E_NOTIMPL; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_Resume( +static HRESULT WINAPI BackgroundCopyJob_Resume( IBackgroundCopyJob2 *iface) { BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); HRESULT rv = S_OK; + TRACE("(%p)\n", This); + EnterCriticalSection(&globalMgr.cs); - if (This->state == BG_JOB_STATE_CANCELLED - || This->state == BG_JOB_STATE_ACKNOWLEDGED) + if (is_job_done(This)) { rv = BG_E_INVALID_STATE; } @@ -159,23 +175,25 @@ static HRESULT WINAPI BITS_IBackgroundCopyJob_Resume( return rv; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_Cancel( +static HRESULT WINAPI BackgroundCopyJob_Cancel( IBackgroundCopyJob2 *iface) { - FIXME("Not implemented\n"); + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + FIXME("(%p): stub\n", This); return E_NOTIMPL; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_Complete( +static HRESULT WINAPI BackgroundCopyJob_Complete( IBackgroundCopyJob2 *iface) { BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); HRESULT rv = S_OK; + TRACE("(%p)\n", This); + EnterCriticalSection(&This->cs); - if (This->state == BG_JOB_STATE_CANCELLED - || This->state == BG_JOB_STATE_ACKNOWLEDGED) + if (is_job_done(This)) { rv = BG_E_INVALID_STATE; } @@ -208,21 +226,24 @@ static HRESULT WINAPI BITS_IBackgroundCopyJob_Complete( return rv; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_GetId( +static HRESULT WINAPI BackgroundCopyJob_GetId( IBackgroundCopyJob2 *iface, GUID *pVal) { BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + TRACE("(%p)->(%p)\n", This, pVal); *pVal = This->jobId; return S_OK; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_GetType( +static HRESULT WINAPI BackgroundCopyJob_GetType( IBackgroundCopyJob2 *iface, BG_JOB_TYPE *pVal) { BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + TRACE("(%p)->(%p)\n", This, pVal); + if (!pVal) return E_INVALIDARG; @@ -230,12 +251,14 @@ static HRESULT WINAPI BITS_IBackgroundCopyJob_GetType( return S_OK; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_GetProgress( +static HRESULT WINAPI BackgroundCopyJob_GetProgress( IBackgroundCopyJob2 *iface, BG_JOB_PROGRESS *pVal) { BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + TRACE("(%p)->(%p)\n", This, pVal); + if (!pVal) return E_INVALIDARG; @@ -249,20 +272,23 @@ static HRESULT WINAPI BITS_IBackgroundCopyJob_GetProgress( return S_OK; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_GetTimes( +static HRESULT WINAPI BackgroundCopyJob_GetTimes( IBackgroundCopyJob2 *iface, BG_JOB_TIMES *pVal) { - FIXME("Not implemented\n"); + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + FIXME("(%p)->(%p): stub\n", This, pVal); return E_NOTIMPL; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_GetState( +static HRESULT WINAPI BackgroundCopyJob_GetState( IBackgroundCopyJob2 *iface, BG_JOB_STATE *pVal) { BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + TRACE("(%p)->(%p)\n", This, pVal); + if (!pVal) return E_INVALIDARG; @@ -271,113 +297,191 @@ static HRESULT WINAPI BITS_IBackgroundCopyJob_GetState( return S_OK; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_GetError( +static HRESULT WINAPI BackgroundCopyJob_GetError( IBackgroundCopyJob2 *iface, IBackgroundCopyError **ppError) { - FIXME("Not implemented\n"); + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + FIXME("(%p)->(%p): stub\n", This, ppError); return E_NOTIMPL; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_GetOwner( - IBackgroundCopyJob2 *iface, - LPWSTR *pVal) -{ - FIXME("Not implemented\n"); - return E_NOTIMPL; -} - -static HRESULT WINAPI BITS_IBackgroundCopyJob_SetDisplayName( - IBackgroundCopyJob2 *iface, - LPCWSTR Val) -{ - FIXME("Not implemented\n"); - return E_NOTIMPL; -} - -static HRESULT WINAPI BITS_IBackgroundCopyJob_GetDisplayName( +static HRESULT WINAPI BackgroundCopyJob_GetOwner( IBackgroundCopyJob2 *iface, LPWSTR *pVal) { BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); - int n; - - if (!pVal) - return E_INVALIDARG; - - n = (lstrlenW(This->displayName) + 1) * sizeof **pVal; - *pVal = CoTaskMemAlloc(n); - if (*pVal == NULL) - return E_OUTOFMEMORY; - memcpy(*pVal, This->displayName, n); - return S_OK; + FIXME("(%p)->(%p): stub\n", This, pVal); + return E_NOTIMPL; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_SetDescription( +static HRESULT WINAPI BackgroundCopyJob_SetDisplayName( IBackgroundCopyJob2 *iface, LPCWSTR Val) { - FIXME("Not implemented\n"); + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + FIXME("(%p)->(%s): stub\n", This, debugstr_w(Val)); return E_NOTIMPL; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_GetDescription( +static HRESULT WINAPI BackgroundCopyJob_GetDisplayName( IBackgroundCopyJob2 *iface, LPWSTR *pVal) { - FIXME("Not implemented\n"); - return E_NOTIMPL; + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + + TRACE("(%p)->(%p)\n", This, pVal); + + return return_strval(This->displayName, pVal); } -static HRESULT WINAPI BITS_IBackgroundCopyJob_SetPriority( +static HRESULT WINAPI BackgroundCopyJob_SetDescription( + IBackgroundCopyJob2 *iface, + LPCWSTR Val) +{ + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + static const int max_description_len = 1024; + HRESULT hr = S_OK; + int len; + + TRACE("(%p)->(%s)\n", This, debugstr_w(Val)); + + if (!Val) return E_INVALIDARG; + + len = strlenW(Val); + if (len > max_description_len) return BG_E_STRING_TOO_LONG; + + EnterCriticalSection(&This->cs); + + if (is_job_done(This)) + { + hr = BG_E_INVALID_STATE; + } + else + { + HeapFree(GetProcessHeap(), 0, This->description); + if ((This->description = HeapAlloc(GetProcessHeap(), 0, (len+1)*sizeof(WCHAR)))) + strcpyW(This->description, Val); + else + hr = E_OUTOFMEMORY; + } + + LeaveCriticalSection(&This->cs); + + return hr; +} + +static HRESULT WINAPI BackgroundCopyJob_GetDescription( + IBackgroundCopyJob2 *iface, + LPWSTR *pVal) +{ + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + + TRACE("(%p)->(%p)\n", This, pVal); + + return return_strval(This->description, pVal); +} + +static HRESULT WINAPI BackgroundCopyJob_SetPriority( IBackgroundCopyJob2 *iface, BG_JOB_PRIORITY Val) { - FIXME("(%p,0x%08x) stub\n", iface, Val); + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + FIXME("(%p)->(%d): stub\n", This, Val); return S_OK; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_GetPriority( +static HRESULT WINAPI BackgroundCopyJob_GetPriority( IBackgroundCopyJob2 *iface, BG_JOB_PRIORITY *pVal) { - FIXME("Not implemented\n"); + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + FIXME("(%p)->(%p): stub\n", This, pVal); return E_NOTIMPL; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_SetNotifyFlags( +static HRESULT WINAPI BackgroundCopyJob_SetNotifyFlags( IBackgroundCopyJob2 *iface, ULONG Val) { - FIXME("Not implemented\n"); - return E_NOTIMPL; + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + static const ULONG valid_flags = BG_NOTIFY_JOB_TRANSFERRED | + BG_NOTIFY_JOB_ERROR | + BG_NOTIFY_DISABLE | + BG_NOTIFY_JOB_MODIFICATION | + BG_NOTIFY_FILE_TRANSFERRED; + + TRACE("(%p)->(0x%x)\n", This, Val); + + if (is_job_done(This)) return BG_E_INVALID_STATE; + if (Val & ~valid_flags) return E_NOTIMPL; + This->notify_flags = Val; + return S_OK; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_GetNotifyFlags( +static HRESULT WINAPI BackgroundCopyJob_GetNotifyFlags( IBackgroundCopyJob2 *iface, ULONG *pVal) { - FIXME("Not implemented\n"); - return E_NOTIMPL; + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + + TRACE("(%p)->(%p)\n", This, pVal); + + if (!pVal) return E_INVALIDARG; + + *pVal = This->notify_flags; + + return S_OK; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_SetNotifyInterface( +static HRESULT WINAPI BackgroundCopyJob_SetNotifyInterface( IBackgroundCopyJob2 *iface, IUnknown *Val) { - FIXME("Not implemented\n"); - return E_NOTIMPL; + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + HRESULT hr = S_OK; + + TRACE("(%p)->(%p)\n", This, Val); + + if (is_job_done(This)) return BG_E_INVALID_STATE; + + if (This->callback) + { + IBackgroundCopyCallback2_Release(This->callback); + This->callback = NULL; + This->callback2 = FALSE; + } + + if (Val) + { + hr = IUnknown_QueryInterface(Val, &IID_IBackgroundCopyCallback2, (void**)&This->callback); + if (FAILED(hr)) + hr = IUnknown_QueryInterface(Val, &IID_IBackgroundCopyCallback, (void**)&This->callback); + else + This->callback2 = TRUE; + } + + return hr; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_GetNotifyInterface( +static HRESULT WINAPI BackgroundCopyJob_GetNotifyInterface( IBackgroundCopyJob2 *iface, IUnknown **pVal) { - FIXME("Not implemented\n"); - return E_NOTIMPL; + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + + TRACE("(%p)->(%p)\n", This, pVal); + + if (!pVal) return E_INVALIDARG; + + *pVal = (IUnknown*)This->callback; + if (*pVal) + IUnknown_AddRef(*pVal); + + return S_OK; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_SetMinimumRetryDelay( +static HRESULT WINAPI BackgroundCopyJob_SetMinimumRetryDelay( IBackgroundCopyJob2 *iface, ULONG Seconds) { @@ -385,180 +489,195 @@ static HRESULT WINAPI BITS_IBackgroundCopyJob_SetMinimumRetryDelay( return S_OK; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_GetMinimumRetryDelay( +static HRESULT WINAPI BackgroundCopyJob_GetMinimumRetryDelay( IBackgroundCopyJob2 *iface, ULONG *Seconds) { - FIXME("%p\n", Seconds); + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + FIXME("(%p)->(%p): stub\n", This, Seconds); *Seconds = 30; return S_OK; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_SetNoProgressTimeout( +static HRESULT WINAPI BackgroundCopyJob_SetNoProgressTimeout( IBackgroundCopyJob2 *iface, ULONG Seconds) { - FIXME("%u\n", Seconds); + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + FIXME("(%p)->(%d): stub\n", This, Seconds); return S_OK; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_GetNoProgressTimeout( +static HRESULT WINAPI BackgroundCopyJob_GetNoProgressTimeout( IBackgroundCopyJob2 *iface, ULONG *Seconds) { - FIXME("%p\n", Seconds); + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + FIXME("(%p)->(%p): stub\n", This, Seconds); *Seconds = 900; return S_OK; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_GetErrorCount( +static HRESULT WINAPI BackgroundCopyJob_GetErrorCount( IBackgroundCopyJob2 *iface, ULONG *Errors) { - FIXME("Not implemented\n"); + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + FIXME("(%p)->(%p): stub\n", This, Errors); return E_NOTIMPL; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_SetProxySettings( +static HRESULT WINAPI BackgroundCopyJob_SetProxySettings( IBackgroundCopyJob2 *iface, BG_JOB_PROXY_USAGE ProxyUsage, const WCHAR *ProxyList, const WCHAR *ProxyBypassList) { - FIXME("Not implemented\n"); + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + FIXME("(%p)->(%d %s %s): stub\n", This, ProxyUsage, debugstr_w(ProxyList), debugstr_w(ProxyBypassList)); return E_NOTIMPL; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_GetProxySettings( +static HRESULT WINAPI BackgroundCopyJob_GetProxySettings( IBackgroundCopyJob2 *iface, BG_JOB_PROXY_USAGE *pProxyUsage, LPWSTR *pProxyList, LPWSTR *pProxyBypassList) { - FIXME("Not implemented\n"); + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + FIXME("(%p)->(%p %p %p): stub\n", This, pProxyUsage, pProxyList, pProxyBypassList); return E_NOTIMPL; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_TakeOwnership( +static HRESULT WINAPI BackgroundCopyJob_TakeOwnership( IBackgroundCopyJob2 *iface) { - FIXME("Not implemented\n"); + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + FIXME("(%p): stub\n", This); return E_NOTIMPL; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_SetNotifyCmdLine( +static HRESULT WINAPI BackgroundCopyJob_SetNotifyCmdLine( IBackgroundCopyJob2 *iface, LPCWSTR prog, LPCWSTR params) { - FIXME("Not implemented\n"); + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + FIXME("(%p)->(%s %s): stub\n", This, debugstr_w(prog), debugstr_w(params)); return E_NOTIMPL; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_GetNotifyCmdLine( +static HRESULT WINAPI BackgroundCopyJob_GetNotifyCmdLine( IBackgroundCopyJob2 *iface, LPWSTR *prog, LPWSTR *params) { - FIXME("Not implemented\n"); + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + FIXME("(%p)->(%p %p): stub\n", This, prog, params); return E_NOTIMPL; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_GetReplyProgress( +static HRESULT WINAPI BackgroundCopyJob_GetReplyProgress( IBackgroundCopyJob2 *iface, BG_JOB_REPLY_PROGRESS *progress) { - FIXME("Not implemented\n"); + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + FIXME("(%p)->(%p): stub\n", This, progress); return E_NOTIMPL; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_GetReplyData( +static HRESULT WINAPI BackgroundCopyJob_GetReplyData( IBackgroundCopyJob2 *iface, byte **pBuffer, UINT64 *pLength) { - FIXME("Not implemented\n"); + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + FIXME("(%p)->(%p %p): stub\n", This, pBuffer, pLength); return E_NOTIMPL; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_SetReplyFileName( +static HRESULT WINAPI BackgroundCopyJob_SetReplyFileName( IBackgroundCopyJob2 *iface, LPCWSTR filename) { - FIXME("Not implemented\n"); + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + FIXME("(%p)->(%s): stub\n", This, debugstr_w(filename)); return E_NOTIMPL; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_GetReplyFileName( +static HRESULT WINAPI BackgroundCopyJob_GetReplyFileName( IBackgroundCopyJob2 *iface, LPWSTR *pFilename) { - FIXME("Not implemented\n"); + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + FIXME("(%p)->(%p): stub\n", This, pFilename); return E_NOTIMPL; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_SetCredentials( +static HRESULT WINAPI BackgroundCopyJob_SetCredentials( IBackgroundCopyJob2 *iface, BG_AUTH_CREDENTIALS *cred) { - FIXME("Not implemented\n"); + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + FIXME("(%p)->(%p): stub\n", This, cred); return S_OK; } -static HRESULT WINAPI BITS_IBackgroundCopyJob_RemoveCredentials( +static HRESULT WINAPI BackgroundCopyJob_RemoveCredentials( IBackgroundCopyJob2 *iface, BG_AUTH_TARGET target, BG_AUTH_SCHEME scheme) { - FIXME("Not implemented\n"); + BackgroundCopyJobImpl *This = impl_from_IBackgroundCopyJob2(iface); + FIXME("(%p)->(%d %d): stub\n", This, target, scheme); return S_OK; } -static const IBackgroundCopyJob2Vtbl BITS_IBackgroundCopyJob_Vtbl = +static const IBackgroundCopyJob2Vtbl BackgroundCopyJobVtbl = { - BITS_IBackgroundCopyJob_QueryInterface, - BITS_IBackgroundCopyJob_AddRef, - BITS_IBackgroundCopyJob_Release, - BITS_IBackgroundCopyJob_AddFileSet, - BITS_IBackgroundCopyJob_AddFile, - BITS_IBackgroundCopyJob_EnumFiles, - BITS_IBackgroundCopyJob_Suspend, - BITS_IBackgroundCopyJob_Resume, - BITS_IBackgroundCopyJob_Cancel, - BITS_IBackgroundCopyJob_Complete, - BITS_IBackgroundCopyJob_GetId, - BITS_IBackgroundCopyJob_GetType, - BITS_IBackgroundCopyJob_GetProgress, - BITS_IBackgroundCopyJob_GetTimes, - BITS_IBackgroundCopyJob_GetState, - BITS_IBackgroundCopyJob_GetError, - BITS_IBackgroundCopyJob_GetOwner, - BITS_IBackgroundCopyJob_SetDisplayName, - BITS_IBackgroundCopyJob_GetDisplayName, - BITS_IBackgroundCopyJob_SetDescription, - BITS_IBackgroundCopyJob_GetDescription, - BITS_IBackgroundCopyJob_SetPriority, - BITS_IBackgroundCopyJob_GetPriority, - BITS_IBackgroundCopyJob_SetNotifyFlags, - BITS_IBackgroundCopyJob_GetNotifyFlags, - BITS_IBackgroundCopyJob_SetNotifyInterface, - BITS_IBackgroundCopyJob_GetNotifyInterface, - BITS_IBackgroundCopyJob_SetMinimumRetryDelay, - BITS_IBackgroundCopyJob_GetMinimumRetryDelay, - BITS_IBackgroundCopyJob_SetNoProgressTimeout, - BITS_IBackgroundCopyJob_GetNoProgressTimeout, - BITS_IBackgroundCopyJob_GetErrorCount, - BITS_IBackgroundCopyJob_SetProxySettings, - BITS_IBackgroundCopyJob_GetProxySettings, - BITS_IBackgroundCopyJob_TakeOwnership, - BITS_IBackgroundCopyJob_SetNotifyCmdLine, - BITS_IBackgroundCopyJob_GetNotifyCmdLine, - BITS_IBackgroundCopyJob_GetReplyProgress, - BITS_IBackgroundCopyJob_GetReplyData, - BITS_IBackgroundCopyJob_SetReplyFileName, - BITS_IBackgroundCopyJob_GetReplyFileName, - BITS_IBackgroundCopyJob_SetCredentials, - BITS_IBackgroundCopyJob_RemoveCredentials + BackgroundCopyJob_QueryInterface, + BackgroundCopyJob_AddRef, + BackgroundCopyJob_Release, + BackgroundCopyJob_AddFileSet, + BackgroundCopyJob_AddFile, + BackgroundCopyJob_EnumFiles, + BackgroundCopyJob_Suspend, + BackgroundCopyJob_Resume, + BackgroundCopyJob_Cancel, + BackgroundCopyJob_Complete, + BackgroundCopyJob_GetId, + BackgroundCopyJob_GetType, + BackgroundCopyJob_GetProgress, + BackgroundCopyJob_GetTimes, + BackgroundCopyJob_GetState, + BackgroundCopyJob_GetError, + BackgroundCopyJob_GetOwner, + BackgroundCopyJob_SetDisplayName, + BackgroundCopyJob_GetDisplayName, + BackgroundCopyJob_SetDescription, + BackgroundCopyJob_GetDescription, + BackgroundCopyJob_SetPriority, + BackgroundCopyJob_GetPriority, + BackgroundCopyJob_SetNotifyFlags, + BackgroundCopyJob_GetNotifyFlags, + BackgroundCopyJob_SetNotifyInterface, + BackgroundCopyJob_GetNotifyInterface, + BackgroundCopyJob_SetMinimumRetryDelay, + BackgroundCopyJob_GetMinimumRetryDelay, + BackgroundCopyJob_SetNoProgressTimeout, + BackgroundCopyJob_GetNoProgressTimeout, + BackgroundCopyJob_GetErrorCount, + BackgroundCopyJob_SetProxySettings, + BackgroundCopyJob_GetProxySettings, + BackgroundCopyJob_TakeOwnership, + BackgroundCopyJob_SetNotifyCmdLine, + BackgroundCopyJob_GetNotifyCmdLine, + BackgroundCopyJob_GetReplyProgress, + BackgroundCopyJob_GetReplyData, + BackgroundCopyJob_SetReplyFileName, + BackgroundCopyJob_GetReplyFileName, + BackgroundCopyJob_SetCredentials, + BackgroundCopyJob_RemoveCredentials }; HRESULT BackgroundCopyJobConstructor(LPCWSTR displayName, BG_JOB_TYPE type, GUID *job_id, BackgroundCopyJobImpl **job) @@ -573,14 +692,14 @@ HRESULT BackgroundCopyJobConstructor(LPCWSTR displayName, BG_JOB_TYPE type, GUID if (!This) return E_OUTOFMEMORY; - This->IBackgroundCopyJob2_iface.lpVtbl = &BITS_IBackgroundCopyJob_Vtbl; + This->IBackgroundCopyJob2_iface.lpVtbl = &BackgroundCopyJobVtbl; InitializeCriticalSection(&This->cs); This->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": BackgroundCopyJobImpl.cs"); This->ref = 1; This->type = type; - n = (lstrlenW(displayName) + 1) * sizeof *displayName; + n = (strlenW(displayName) + 1) * sizeof *displayName; This->displayName = HeapAlloc(GetProcessHeap(), 0, n); if (!This->displayName) { @@ -609,8 +728,15 @@ HRESULT BackgroundCopyJobConstructor(LPCWSTR displayName, BG_JOB_TYPE type, GUID This->jobProgress.FilesTransferred = 0; This->state = BG_JOB_STATE_SUSPENDED; + This->description = NULL; + This->notify_flags = BG_NOTIFY_JOB_ERROR | BG_NOTIFY_JOB_TRANSFERRED; + This->callback = NULL; + This->callback2 = FALSE; *job = This; + + TRACE("created job %s:%p\n", debugstr_guid(&This->jobId), This); + return S_OK; } diff --git a/dll/win32/qmgr/qmgr.c b/dll/win32/qmgr/qmgr.c index 28a90d7f658..69c5c3ae96a 100644 --- a/dll/win32/qmgr/qmgr.c +++ b/dll/win32/qmgr/qmgr.c @@ -22,10 +22,10 @@ BackgroundCopyManagerImpl globalMgr; -static HRESULT WINAPI BITS_IBackgroundCopyManager_QueryInterface(IBackgroundCopyManager *iface, +static HRESULT WINAPI BackgroundCopyManager_QueryInterface(IBackgroundCopyManager *iface, REFIID riid, void **ppv) { - TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv); + TRACE("(%s, %p)\n", debugstr_guid(riid), ppv); if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IBackgroundCopyManager)) { @@ -38,24 +38,25 @@ static HRESULT WINAPI BITS_IBackgroundCopyManager_QueryInterface(IBackgroundCopy return E_NOINTERFACE; } -static ULONG WINAPI BITS_IBackgroundCopyManager_AddRef(IBackgroundCopyManager *iface) +static ULONG WINAPI BackgroundCopyManager_AddRef(IBackgroundCopyManager *iface) { return 2; } -static ULONG WINAPI BITS_IBackgroundCopyManager_Release(IBackgroundCopyManager *iface) +static ULONG WINAPI BackgroundCopyManager_Release(IBackgroundCopyManager *iface) { return 1; } /*** IBackgroundCopyManager interface methods ***/ -static HRESULT WINAPI BITS_IBackgroundCopyManager_CreateJob(IBackgroundCopyManager *iface, +static HRESULT WINAPI BackgroundCopyManager_CreateJob(IBackgroundCopyManager *iface, LPCWSTR DisplayName, BG_JOB_TYPE Type, GUID *pJobId, IBackgroundCopyJob **ppJob) { BackgroundCopyJobImpl *job; HRESULT hres; - TRACE("\n"); + + TRACE("(%s %d %p %p)\n", debugstr_w(DisplayName), Type, pJobId, ppJob); hres = BackgroundCopyJobConstructor(DisplayName, Type, pJobId, &job); if (FAILED(hres)) @@ -70,50 +71,73 @@ static HRESULT WINAPI BITS_IBackgroundCopyManager_CreateJob(IBackgroundCopyManag return S_OK; } -static HRESULT WINAPI BITS_IBackgroundCopyManager_GetJob(IBackgroundCopyManager *iface, - REFGUID jobID, IBackgroundCopyJob **ppJob) +static HRESULT WINAPI BackgroundCopyManager_GetJob(IBackgroundCopyManager *iface, + REFGUID jobID, IBackgroundCopyJob **job) { - FIXME("Not implemented\n"); - return E_NOTIMPL; + BackgroundCopyManagerImpl *qmgr = &globalMgr; + HRESULT hr = BG_E_NOT_FOUND; + BackgroundCopyJobImpl *cur; + + TRACE("(%s %p)\n", debugstr_guid(jobID), job); + + if (!job || !jobID) return E_INVALIDARG; + + *job = NULL; + + EnterCriticalSection(&qmgr->cs); + + LIST_FOR_EACH_ENTRY(cur, &qmgr->jobs, BackgroundCopyJobImpl, entryFromQmgr) + { + if (IsEqualGUID(&cur->jobId, jobID)) + { + *job = (IBackgroundCopyJob*)&cur->IBackgroundCopyJob2_iface; + IBackgroundCopyJob2_AddRef(&cur->IBackgroundCopyJob2_iface); + hr = S_OK; + break; + } + } + + LeaveCriticalSection(&qmgr->cs); + + return hr; } -static HRESULT WINAPI BITS_IBackgroundCopyManager_EnumJobs(IBackgroundCopyManager *iface, - DWORD dwFlags, IEnumBackgroundCopyJobs **ppEnum) +static HRESULT WINAPI BackgroundCopyManager_EnumJobs(IBackgroundCopyManager *iface, + DWORD flags, IEnumBackgroundCopyJobs **ppEnum) { - TRACE("\n"); + TRACE("(0x%x %p)\n", flags, ppEnum); return enum_copy_job_create(&globalMgr, ppEnum); } -static HRESULT WINAPI BITS_IBackgroundCopyManager_GetErrorDescription(IBackgroundCopyManager *iface, - HRESULT hResult, DWORD LanguageId, LPWSTR *pErrorDescription) +static HRESULT WINAPI BackgroundCopyManager_GetErrorDescription(IBackgroundCopyManager *iface, + HRESULT hr, DWORD langid, LPWSTR *error_description) { - FIXME("Not implemented\n"); + FIXME("(0x%08x 0x%x %p): stub\n", hr, langid, error_description); return E_NOTIMPL; } - -static const IBackgroundCopyManagerVtbl BITS_IBackgroundCopyManager_Vtbl = +static const IBackgroundCopyManagerVtbl BackgroundCopyManagerVtbl = { - BITS_IBackgroundCopyManager_QueryInterface, - BITS_IBackgroundCopyManager_AddRef, - BITS_IBackgroundCopyManager_Release, - BITS_IBackgroundCopyManager_CreateJob, - BITS_IBackgroundCopyManager_GetJob, - BITS_IBackgroundCopyManager_EnumJobs, - BITS_IBackgroundCopyManager_GetErrorDescription + BackgroundCopyManager_QueryInterface, + BackgroundCopyManager_AddRef, + BackgroundCopyManager_Release, + BackgroundCopyManager_CreateJob, + BackgroundCopyManager_GetJob, + BackgroundCopyManager_EnumJobs, + BackgroundCopyManager_GetErrorDescription }; BackgroundCopyManagerImpl globalMgr = { - { &BITS_IBackgroundCopyManager_Vtbl }, + { &BackgroundCopyManagerVtbl }, { NULL, -1, 0, 0, 0, 0 }, NULL, LIST_INIT(globalMgr.jobs) }; /* Constructor for instances of background copy manager */ -HRESULT BackgroundCopyManagerConstructor(IUnknown *pUnkOuter, LPVOID *ppObj) +HRESULT BackgroundCopyManagerConstructor(LPVOID *ppObj) { - TRACE("(%p,%p)\n", pUnkOuter, ppObj); + TRACE("(%p)\n", ppObj); *ppObj = &globalMgr; return S_OK; } diff --git a/dll/win32/qmgr/qmgr.h b/dll/win32/qmgr/qmgr.h index c93bcc2ba3e..ae8668502e8 100644 --- a/dll/win32/qmgr/qmgr.h +++ b/dll/win32/qmgr/qmgr.h @@ -34,9 +34,11 @@ #include #include #include +#include #include #include +#include WINE_DEFAULT_DEBUG_CHANNEL(qmgr); @@ -46,11 +48,15 @@ typedef struct IBackgroundCopyJob2 IBackgroundCopyJob2_iface; LONG ref; LPWSTR displayName; + LPWSTR description; BG_JOB_TYPE type; GUID jobId; struct list files; BG_JOB_PROGRESS jobProgress; BG_JOB_STATE state; + ULONG notify_flags; + IBackgroundCopyCallback2 *callback; + BOOL callback2; /* IBackgroundCopyCallback2 is supported in addition to IBackgroundCopyCallback */ /* Protects file list, and progress */ CRITICAL_SECTION cs; struct list entryFromQmgr; @@ -87,7 +93,7 @@ extern HANDLE stop_event DECLSPEC_HIDDEN; extern ClassFactoryImpl BITS_ClassFactory DECLSPEC_HIDDEN; extern BackgroundCopyManagerImpl globalMgr DECLSPEC_HIDDEN; -HRESULT BackgroundCopyManagerConstructor(IUnknown *pUnkOuter, LPVOID *ppObj) DECLSPEC_HIDDEN; +HRESULT BackgroundCopyManagerConstructor(LPVOID *ppObj) DECLSPEC_HIDDEN; HRESULT BackgroundCopyJobConstructor(LPCWSTR displayName, BG_JOB_TYPE type, GUID *pJobId, BackgroundCopyJobImpl **job) DECLSPEC_HIDDEN; HRESULT enum_copy_job_create(BackgroundCopyManagerImpl *qmgr, @@ -109,6 +115,19 @@ qmgr_strdup(const char *s) return d ? memcpy(d, s, n) : NULL; } +static inline HRESULT return_strval(const WCHAR *str, WCHAR **ret) +{ + int len; + + if (!ret) return E_INVALIDARG; + + len = strlenW(str); + *ret = CoTaskMemAlloc((len+1)*sizeof(WCHAR)); + if (!*ret) return E_OUTOFMEMORY; + strcpyW(*ret, str); + return S_OK; +} + static inline BOOL transitionJobState(BackgroundCopyJobImpl *job, BG_JOB_STATE fromState, BG_JOB_STATE toState) diff --git a/dll/win32/qmgr/qmgr.inf b/dll/win32/qmgr/qmgr.inf deleted file mode 100644 index c3d0380cd90..00000000000 --- a/dll/win32/qmgr/qmgr.inf +++ /dev/null @@ -1,16 +0,0 @@ -[version] -Signature="$CHICAGO$" - -[RegisterDll] -AddReg = Qmgr.Reg - -[UnregisterDll] -DelReg = Qmgr.Reg - -[Qmgr.Reg] -HKCR,"AppID\BITS","AppID",,"%CLSID_BackgroundCopyQMgr%" -HKCR,"AppID\%CLSID_BackgroundCopyQMgr%","LocalService",,"BITS" -HKCR,"CLSID\%CLSID_BackgroundCopyManager%","AppID",,"%CLSID_BackgroundCopyQMgr%" - -HKLM,"Software\Microsoft\Windows NT\CurrentVersion\SvcHost","netsvcs",0x00010008,"BITS" -HKLM,"System\CurrentControlSet\Services\BITS\Parameters","ServiceDll",0x00020000,"qmgr.dll" diff --git a/dll/win32/qmgr/qmgr.rgs b/dll/win32/qmgr/qmgr.rgs new file mode 100644 index 00000000000..675505ed6a1 --- /dev/null +++ b/dll/win32/qmgr/qmgr.rgs @@ -0,0 +1,15 @@ +HKCR +{ + NoRemove AppID + { + '{69AD4AEE-51BE-439B-A92C-86AE490E8B30}' { val LocalService = s 'BITS' } + BITS { val AppID = s '{69AD4AEE-51BE-439B-A92C-86AE490E8B30}' } + } + NoRemove CLSID + { + '{4991D34B-80A1-4291-83B6-3328366B9097}' + { + val AppID = s '{69AD4AEE-51BE-439B-A92C-86AE490E8B30}' + } + } +} diff --git a/dll/win32/qmgr/qmgr_local.idl b/dll/win32/qmgr/qmgr_local.idl index 8e1341d010f..edbe71eacde 100644 --- a/dll/win32/qmgr/qmgr_local.idl +++ b/dll/win32/qmgr/qmgr_local.idl @@ -16,7 +16,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma makedep ident + #include "bits.idl" #define DO_NO_IMPORTS #include "bits1_5.idl" +#include "bits3_0.idl" diff --git a/dll/win32/qmgr/qmgr_main.c b/dll/win32/qmgr/qmgr_main.c index 267bd1f827c..7576e4a1c67 100644 --- a/dll/win32/qmgr/qmgr_main.c +++ b/dll/win32/qmgr/qmgr_main.c @@ -29,14 +29,12 @@ #include #include #include +#include #include /* Handle to the base address of this DLL */ static HINSTANCE hInst; -/* Other GUIDs used by this module */ -DEFINE_GUID(CLSID_BackgroundCopyQMgr, 0x69AD4AEE, 0x51BE, 0x439b, 0xA9,0x2C, 0x86,0xAE,0x49,0x0E,0x8B,0x30); - /* Entry point for DLL */ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { @@ -55,116 +53,12 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) return TRUE; } -static HRESULT init_register_strtable(STRTABLEA *strtable) -{ -#define CLSID_EXPANSION_ENTRY(id) { "CLSID_" #id, &CLSID_ ## id } - static const struct { - const char *name; - const CLSID *clsid; - } expns[] = { - CLSID_EXPANSION_ENTRY(BackgroundCopyQMgr), - CLSID_EXPANSION_ENTRY(BackgroundCopyManager) - }; -#undef CLSID_EXPANSION_ENTRY - static STRENTRYA pse[sizeof expns / sizeof expns[0]]; - DWORD i; - - strtable->cEntries = sizeof pse / sizeof pse[0]; - strtable->pse = pse; - for (i = 0; i < strtable->cEntries; i++) { - static const char dummy_sample[] = "{12345678-1234-1234-1234-123456789012}"; - const CLSID *clsid = expns[i].clsid; - pse[i].pszName = qmgr_strdup(expns[i].name); - pse[i].pszValue = HeapAlloc(GetProcessHeap(), 0, sizeof dummy_sample); - if (!pse[i].pszName || !pse[i].pszValue) - return E_OUTOFMEMORY; - sprintf(pse[i].pszValue, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", - clsid->Data1, clsid->Data2, clsid->Data3, clsid->Data4[0], - clsid->Data4[1], clsid->Data4[2], clsid->Data4[3], clsid->Data4[4], - clsid->Data4[5], clsid->Data4[6], clsid->Data4[7]); - } - - return S_OK; -} - -static void cleanup_register_strtable(STRTABLEA *strtable) -{ - DWORD i; - for (i = 0; i < strtable->cEntries; i++) { - HeapFree(GetProcessHeap(), 0, strtable->pse[i].pszName); - HeapFree(GetProcessHeap(), 0, strtable->pse[i].pszValue); - if (!strtable->pse[i].pszName || !strtable->pse[i].pszValue) - return; - } -} - -static HRESULT register_service(BOOL do_register) -{ - static const WCHAR name[] = { 'B','I','T','S', 0 }; - static const WCHAR path[] = { 's','v','c','h','o','s','t','.','e','x','e', - ' ','-','k',' ','n','e','t','s','v','c','s', 0 }; - SC_HANDLE scm, service; - - scm = OpenSCManagerW(NULL, NULL, SC_MANAGER_ALL_ACCESS); - if (!scm) - return SELFREG_E_CLASS; - - if (do_register) - service = CreateServiceW(scm, name, name, SERVICE_ALL_ACCESS, - SERVICE_WIN32_OWN_PROCESS, - SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, - path, NULL, NULL, NULL, NULL, NULL); - else - service = OpenServiceW(scm, name, DELETE); - - - CloseServiceHandle(scm); - if (service) - { - if (!do_register) DeleteService(service); - CloseServiceHandle(service); - } - return S_OK; -} - -/* Use an INF file to register or unregister the DLL */ -static HRESULT register_server(BOOL do_register) -{ - HRESULT hr; - STRTABLEA strtable; - HMODULE hAdvpack; - HRESULT (WINAPI *pRegInstall)(HMODULE hm, LPCSTR pszSection, const STRTABLEA* pstTable); - static const WCHAR wszAdvpack[] = {'a','d','v','p','a','c','k','.','d','l','l',0}; - - TRACE("(%x)\n", do_register); - - hr = register_service(do_register); - if (FAILED(hr)) { - ERR("register_service failed: %d\n", GetLastError()); - return hr; - } - - hAdvpack = LoadLibraryW(wszAdvpack); - pRegInstall = (void *)GetProcAddress(hAdvpack, "RegInstall"); - - hr = init_register_strtable(&strtable); - if (SUCCEEDED(hr)) - hr = pRegInstall(hInst, do_register ? "RegisterDll" : "UnregisterDll", - &strtable); - cleanup_register_strtable(&strtable); - - if (FAILED(hr)) - ERR("RegInstall failed: %08x\n", hr); - - return hr; -} - HRESULT WINAPI DllRegisterServer(void) { - return register_server(TRUE); + return __wine_register_resources(hInst); } HRESULT WINAPI DllUnregisterServer(void) { - return register_server(FALSE); + return __wine_unregister_resources(hInst); } diff --git a/dll/win32/qmgr/rsrc.rc b/dll/win32/qmgr/rsrc.rc index dfc64d05b11..66fd2a599b1 100644 --- a/dll/win32/qmgr/rsrc.rc +++ b/dll/win32/qmgr/rsrc.rc @@ -16,5 +16,5 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* @makedep: qmgr.inf */ -REGINST REGINST qmgr.inf +/* @makedep: qmgr.rgs */ +1 WINE_REGISTRY qmgr.rgs diff --git a/dll/win32/qmgrprxy/qmgrprxy.idl b/dll/win32/qmgrprxy/qmgrprxy.idl index 369301a540a..97c1da3fd79 100644 --- a/dll/win32/qmgrprxy/qmgrprxy.idl +++ b/dll/win32/qmgrprxy/qmgrprxy.idl @@ -16,10 +16,15 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma makedep ident +#pragma makedep proxy +#pragma makedep register + #include "bits.idl" #define DO_NO_IMPORTS #include "bits1_5.idl" +#include "bits3_0.idl" [ threading(both), diff --git a/dll/win32/qmgrprxy/qmgrprxy.rgs b/dll/win32/qmgrprxy/qmgrprxy.rgs index 0492aa1b543..c6696983e3e 100644 --- a/dll/win32/qmgrprxy/qmgrprxy.rgs +++ b/dll/win32/qmgrprxy/qmgrprxy.rgs @@ -42,6 +42,11 @@ HKCR NumMethods = s 43 ProxyStubClsid32 = s '{5CE34C0D-0DC9-4C1F-897C-DAA1B78CEE7C}' } + '{659CDEAC-489E-11D9-A9CD-000D56965251}' = s 'IBackgroundCopyCallback2' + { + NumMethods = s 7 + ProxyStubClsid32 = s '{5CE34C0D-0DC9-4C1F-897C-DAA1B78CEE7C}' + } } NoRemove CLSID { diff --git a/dll/win32/riched20/CMakeLists.txt b/dll/win32/riched20/CMakeLists.txt index 339445459ec..8491fdc1d07 100644 --- a/dll/win32/riched20/CMakeLists.txt +++ b/dll/win32/riched20/CMakeLists.txt @@ -40,6 +40,6 @@ list(APPEND ADDITIONAL_SOURCE add_library(riched20 SHARED ${SOURCE} ${ADDITIONAL_SOURCE}) set_module_type(riched20 win32dll) target_link_libraries(riched20 wine uuid) -add_importlibs(riched20 ole32 oleaut32 imm32 user32 gdi32 msvcrt kernel32 ntdll) +add_importlibs(riched20 ole32 oleaut32 usp10 imm32 user32 gdi32 msvcrt kernel32 ntdll) add_pch(riched20 editor.h SOURCE) add_cd_file(TARGET riched20 DESTINATION reactos/system32 FOR all) diff --git a/dll/win32/riched20/caret.c b/dll/win32/riched20/caret.c index 07e042b8378..90b30a2f576 100644 --- a/dll/win32/riched20/caret.c +++ b/dll/win32/riched20/caret.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ + #include "editor.h" WINE_DEFAULT_DEBUG_CHANNEL(richedit); @@ -55,7 +56,19 @@ int ME_GetSelectionOfs(ME_TextEditor *editor, int *from, int *to) int ME_GetSelection(ME_TextEditor *editor, ME_Cursor **from, ME_Cursor **to) { - if (ME_GetCursorOfs(&editor->pCursors[0]) < ME_GetCursorOfs(&editor->pCursors[1])) + int from_ofs = ME_GetCursorOfs( &editor->pCursors[0] ); + int to_ofs = ME_GetCursorOfs( &editor->pCursors[1] ); + BOOL swap = (from_ofs > to_ofs); + + if (from_ofs == to_ofs) + { + /* If cursor[0] is at the beginning of a run and cursor[1] at the end + of the prev run then we need to swap. */ + if (editor->pCursors[0].nOffset < editor->pCursors[1].nOffset) + swap = TRUE; + } + + if (!swap) { *from = &editor->pCursors[0]; *to = &editor->pCursors[1]; @@ -127,7 +140,6 @@ int ME_SetSelection(ME_TextEditor *editor, int from, int to) ME_SetCursorToStart(editor, &editor->pCursors[1]); ME_SetCursorToEnd(editor, &editor->pCursors[0]); ME_InvalidateSelection(editor); - ME_ClearTempStyle(editor); return len + 1; } @@ -150,7 +162,6 @@ int ME_SetSelection(ME_TextEditor *editor, int from, int to) editor->pCursors[1] = editor->pCursors[0]; ME_Repaint(editor); } - ME_ClearTempStyle(editor); return end; } @@ -179,7 +190,6 @@ int ME_SetSelection(ME_TextEditor *editor, int from, int to) ME_SetCursorToEnd(editor, &editor->pCursors[0]); editor->pCursors[1] = editor->pCursors[0]; ME_InvalidateSelection(editor); - ME_ClearTempStyle(editor); return len; } @@ -283,13 +293,15 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start, int nChars, BOOL bForce) { ME_Cursor c = *start; - int nOfs = ME_GetCursorOfs(start); + int nOfs = ME_GetCursorOfs(start), text_len = ME_GetTextLength( editor ); int shift = 0; int totalChars = nChars; ME_DisplayItem *start_para; + BOOL delete_all = FALSE; /* Prevent deletion past last end of paragraph run. */ - nChars = min(nChars, ME_GetTextLength(editor) - nOfs); + nChars = min(nChars, text_len - nOfs); + if (nChars == text_len) delete_all = TRUE; start_para = c.pPara; if (!bForce) @@ -423,6 +435,7 @@ BOOL ME_InternalDeleteText(ME_TextEditor *editor, ME_Cursor *start, continue; } } + if (delete_all) ME_SetDefaultParaFormat( start_para->member.para.pFmt ); return TRUE; } @@ -526,7 +539,7 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, ME_InternalInsertTextFromCursor(editor, nCursor, &tab, 1, style, MERF_TAB); pos++; } else { /* handle EOLs */ - ME_DisplayItem *tp, *end_run; + ME_DisplayItem *tp, *end_run, *run, *prev; ME_Style *tmp_style; int eol_len = 0; @@ -560,17 +573,43 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, } p = &editor->pCursors[nCursor]; - if (p->nOffset) - ME_SplitRunSimple(editor, p); + + if (p->nOffset == p->pRun->member.run.len) + { + run = ME_FindItemFwd( p->pRun, diRun ); + if (!run) run = p->pRun; + } + else + { + if (p->nOffset) ME_SplitRunSimple(editor, p); + run = p->pRun; + } + tmp_style = ME_GetInsertStyle(editor, nCursor); /* ME_SplitParagraph increases style refcount */ - tp = ME_SplitParagraph(editor, p->pRun, p->pRun->member.run.style, eol_str, eol_len, 0); - p->pRun = ME_FindItemFwd(tp, diRun); - p->pPara = tp; + tp = ME_SplitParagraph(editor, run, run->member.run.style, eol_str, eol_len, 0); + end_run = ME_FindItemBack(tp, diRun); ME_ReleaseStyle(end_run->member.run.style); end_run->member.run.style = tmp_style; - p->nOffset = 0; + + /* Move any cursors that were at the end of the previous run to the beginning of the new para */ + prev = ME_FindItemBack( end_run, diRun ); + if (prev) + { + int i; + for (i = 0; i < editor->nCursors; i++) + { + if (editor->pCursors[i].pRun == prev && + editor->pCursors[i].nOffset == prev->member.run.len) + { + editor->pCursors[i].pPara = tp; + editor->pCursors[i].pRun = run; + editor->pCursors[i].nOffset = 0; + } + } + } + } } len -= pos - str; @@ -865,7 +904,7 @@ static ME_DisplayItem* ME_FindPixelPosInTableRow(int x, int y, } static BOOL ME_FindRunInRow(ME_TextEditor *editor, ME_DisplayItem *pRow, - int x, ME_Cursor *cursor, int *pbCaretAtEnd) + int x, ME_Cursor *cursor, BOOL *pbCaretAtEnd) { ME_DisplayItem *pNext, *pLastRun; ME_Row *row = &pRow->member.row; @@ -925,7 +964,7 @@ static BOOL ME_FindPixelPos(ME_TextEditor *editor, int x, int y, y -= editor->rcFormat.top; if (is_eol) - *is_eol = 0; + *is_eol = FALSE; /* find paragraph */ for (; p != editor->pBuffer->pLast; p = p->member.para.next_para) @@ -1070,8 +1109,7 @@ static void ME_ExtendAnchorSelection(ME_TextEditor *editor) void ME_LButtonDown(ME_TextEditor *editor, int x, int y, int clickNum) { ME_Cursor tmp_cursor; - int is_selection = 0; - BOOL is_shift; + BOOL is_selection = FALSE, is_shift; editor->nUDArrowX = -1; @@ -1128,7 +1166,6 @@ void ME_LButtonDown(ME_TextEditor *editor, int x, int y, int clickNum) ME_InvalidateSelection(editor); ITextHost_TxShowCaret(editor->texthost, FALSE); ME_ShowCaret(editor); - ME_ClearTempStyle(editor); ME_SendSelChange(editor); } @@ -1447,7 +1484,9 @@ void ME_DeleteSelection(ME_TextEditor *editor) { int from, to; int nStartCursor = ME_GetSelectionOfs(editor, &from, &to); + int nEndCursor = nStartCursor ^ 1; ME_DeleteTextAtCursor(editor, nStartCursor, to - from); + editor->pCursors[nEndCursor] = editor->pCursors[nStartCursor]; } ME_Style *ME_GetSelectionInsertStyle(ME_TextEditor *editor) @@ -1495,14 +1534,14 @@ ME_ArrowKey(ME_TextEditor *editor, int nVKey, BOOL extend, BOOL ctrl) ME_CheckCharOffsets(editor); switch(nVKey) { case VK_LEFT: - editor->bCaretAtEnd = 0; + editor->bCaretAtEnd = FALSE; if (ctrl) success = ME_MoveCursorWords(editor, &tmp_curs, -1); else success = ME_MoveCursorChars(editor, &tmp_curs, -1); break; case VK_RIGHT: - editor->bCaretAtEnd = 0; + editor->bCaretAtEnd = FALSE; if (ctrl) success = ME_MoveCursorWords(editor, &tmp_curs, +1); else @@ -1525,7 +1564,7 @@ ME_ArrowKey(ME_TextEditor *editor, int nVKey, BOOL extend, BOOL ctrl) ME_ArrowCtrlHome(editor, &tmp_curs); else ME_ArrowHome(editor, &tmp_curs); - editor->bCaretAtEnd = 0; + editor->bCaretAtEnd = FALSE; break; } case VK_END: diff --git a/dll/win32/riched20/editor.c b/dll/win32/riched20/editor.c index e63b92877a5..7ccdd494354 100644 --- a/dll/win32/riched20/editor.c +++ b/dll/win32/riched20/editor.c @@ -245,13 +245,13 @@ static const WCHAR REListBox20W[] = {'R','E','L','i','s','t','B','o','x','2','0' static const WCHAR REComboBox20W[] = {'R','E','C','o','m','b','o','B','o','x','2','0','W', 0}; static HCURSOR hLeft; -int me_debug = 0; +BOOL me_debug = FALSE; HANDLE me_heap = NULL; static BOOL ME_ListBoxRegistered = FALSE; static BOOL ME_ComboBoxRegistered = FALSE; -static inline int is_version_nt(void) +static inline BOOL is_version_nt(void) { return !(GetVersion() & 0x80000000); } @@ -284,6 +284,9 @@ static LRESULT ME_StreamInText(ME_TextEditor *editor, DWORD dwFormat, ME_InStrea WCHAR *pText; LRESULT total_bytes_read = 0; BOOL is_read = FALSE; + DWORD cp = CP_ACP, copy = 0; + char conv_buf[4 + STREAMIN_BUFFER_SIZE]; /* up to 4 additional UTF-8 bytes */ + static const char bom_utf8[] = {0xEF, 0xBB, 0xBF}; TRACE("%08x %p\n", dwFormat, stream); @@ -305,8 +308,7 @@ static LRESULT ME_StreamInText(ME_TextEditor *editor, DWORD dwFormat, ME_InStrea if (!(dwFormat & SF_UNICODE)) { char * buf = stream->buffer; - DWORD size = stream->dwSize; - DWORD cp = CP_ACP; + DWORD size = stream->dwSize, end; if (!is_read) { @@ -319,8 +321,56 @@ static LRESULT ME_StreamInText(ME_TextEditor *editor, DWORD dwFormat, ME_InStrea } } - nWideChars = MultiByteToWideChar(cp, 0, buf, size, wszText, STREAMIN_BUFFER_SIZE); + if (cp == CP_UTF8) + { + if (copy) + { + memcpy(conv_buf + copy, buf, size); + buf = conv_buf; + size += copy; + } + end = size; + while ((buf[end-1] & 0xC0) == 0x80) + { + --end; + --total_bytes_read; /* strange, but seems to match windows */ + } + if (buf[end-1] & 0x80) + { + DWORD need = 0; + if ((buf[end-1] & 0xE0) == 0xC0) + need = 1; + if ((buf[end-1] & 0xF0) == 0xE0) + need = 2; + if ((buf[end-1] & 0xF8) == 0xF0) + need = 3; + + if (size - end >= need) + { + /* we have enough bytes for this sequence */ + end = size; + } + else + { + /* need more bytes, so don't transcode this sequence */ + --end; + } + } + } + else + end = size; + + nWideChars = MultiByteToWideChar(cp, 0, buf, end, wszText, STREAMIN_BUFFER_SIZE); pText = wszText; + + if (cp == CP_UTF8) + { + if (end != size) + { + memcpy(conv_buf, buf + end, size - end); + copy = size - end; + } + } } else { @@ -1146,11 +1196,8 @@ static BOOL ME_RTFInsertOleObject(RTF_Info *info, HENHMETAFILE hemf, HBITMAP hbm } if (OleCreateDefaultHandler(&CLSID_NULL, NULL, &IID_IOleObject, (void**)&lpObject) == S_OK && -#if 0 - /* FIXME: enable it when rich-edit properly implements this method */ IRichEditOle_GetClientSite(info->lpRichEditOle, &lpClientSite) == S_OK && IOleObject_SetClientSite(lpObject, lpClientSite) == S_OK && -#endif IOleObject_GetUserClassID(lpObject, &clsid) == S_OK && IOleObject_QueryInterface(lpObject, &IID_IOleCache, (void**)&lpOleCache) == S_OK && IOleCache_Cache(lpOleCache, &fm, 0, &conn) == S_OK && @@ -1581,7 +1628,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre ME_Cursor linebreakCursor = *selEnd; ME_MoveCursorChars(editor, &linebreakCursor, -linebreakSize); - ME_GetTextW(editor, lastchar, 2, &linebreakCursor, linebreakSize, 0); + ME_GetTextW(editor, lastchar, 2, &linebreakCursor, linebreakSize, FALSE); if (lastchar[0] == '\r' && (lastchar[1] == '\n' || lastchar[1] == '\0')) { ME_InternalDeleteText(editor, &linebreakCursor, linebreakSize, FALSE); } @@ -1916,7 +1963,7 @@ static int ME_GetTextEx(ME_TextEditor *editor, GETTEXTEX *ex, LPARAM pText) ME_SetCursorToStart(editor, &start); nChars = INT_MAX; } - if (ex->codepage == 1200) + if (ex->codepage == CP_UNICODE) { return ME_GetTextW(editor, (LPWSTR)pText, ex->cb / sizeof(WCHAR) - 1, &start, nChars, ex->flags & GT_USECRLF); @@ -1951,12 +1998,12 @@ static int ME_GetTextRange(ME_TextEditor *editor, WCHAR *strText, { if (!strText) return 0; if (unicode) { - return ME_GetTextW(editor, strText, INT_MAX, start, nLen, 0); + return ME_GetTextW(editor, strText, INT_MAX, start, nLen, FALSE); } else { int nChars; WCHAR *p = ALLOC_N_OBJ(WCHAR, nLen+1); if (!p) return 0; - nChars = ME_GetTextW(editor, p, nLen, start, nLen, 0); + nChars = ME_GetTextW(editor, p, nLen, start, nLen, FALSE); WideCharToMultiByte(CP_ACP, 0, p, nChars+1, (char *)strText, nLen+1, NULL, NULL); FREE_OBJ(p); @@ -1964,6 +2011,22 @@ static int ME_GetTextRange(ME_TextEditor *editor, WCHAR *strText, } } +static int handle_EM_EXSETSEL( ME_TextEditor *editor, int to, int from ) +{ + int end; + + TRACE("%d - %d\n", to, from ); + + ME_InvalidateSelection( editor ); + end = ME_SetSelection( editor, to, from ); + ME_InvalidateSelection( editor ); + ITextHost_TxShowCaret( editor->texthost, FALSE ); + ME_ShowCaret( editor ); + ME_SendSelChange( editor ); + + return end; +} + typedef struct tagME_GlobalDestStruct { HGLOBAL hData; @@ -2331,7 +2394,7 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey) case 'A': if (ctrl_is_down) { - ME_SetSelection(editor, 0, -1); + handle_EM_EXSETSEL( editor, 0, -1 ); return TRUE; } break; @@ -2790,6 +2853,8 @@ ME_TextEditor *ME_MakeEditor(ITextHost *texthost, BOOL bEmulateVersion10) ed->horz_si.nPage = 0; ed->horz_si.nPos = 0; + ed->wheel_remain = 0; + OleInitialize(NULL); return ed; @@ -2857,6 +2922,23 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) return TRUE; } +static inline int get_default_line_height( ME_TextEditor *editor ) +{ + int height = 0; + + if (editor->pBuffer && editor->pBuffer->pDefaultStyle) + height = editor->pBuffer->pDefaultStyle->tm.tmHeight; + if (height <= 0) height = 24; + + return height; +} + +static inline int calc_wheel_change( int *remain, int amount_per_click ) +{ + int change = amount_per_click * (float)*remain / WHEEL_DELTA; + *remain -= WHEEL_DELTA * change / amount_per_click; + return change; +} static const char * const edit_messages[] = { "EM_GETSEL", @@ -3074,11 +3156,14 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, return ME_StreamOut(editor, wParam, (EDITSTREAM *)lParam); case WM_GETDLGCODE: { - UINT code = DLGC_WANTCHARS|DLGC_WANTTAB|DLGC_WANTARROWS|DLGC_HASSETSEL; + UINT code = DLGC_WANTCHARS|DLGC_WANTTAB|DLGC_WANTARROWS; + if (lParam) editor->bDialogMode = TRUE; if (editor->styleFlags & ES_MULTILINE) code |= DLGC_WANTMESSAGE; + if (!(editor->styleFlags & ES_SAVESEL)) + code |= DLGC_HASSETSEL; return code; } case EM_EMPTYUNDOBUFFER: @@ -3194,12 +3279,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } case EM_SETSEL: { - ME_InvalidateSelection(editor); - ME_SetSelection(editor, wParam, lParam); - ME_InvalidateSelection(editor); - ITextHost_TxShowCaret(editor->texthost, FALSE); - ME_ShowCaret(editor); - ME_SendSelChange(editor); + handle_EM_EXSETSEL( editor, wParam, lParam ); return 0; } case EM_SETSCROLLPOS: @@ -3223,19 +3303,9 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } case EM_EXSETSEL: { - int end; CHARRANGE range = *(CHARRANGE *)lParam; - TRACE("EM_EXSETSEL (%d,%d)\n", range.cpMin, range.cpMax); - - ME_InvalidateSelection(editor); - end = ME_SetSelection(editor, range.cpMin, range.cpMax); - ME_InvalidateSelection(editor); - ITextHost_TxShowCaret(editor->texthost, FALSE); - ME_ShowCaret(editor); - ME_SendSelChange(editor); - - return end; + return handle_EM_EXSETSEL( editor, range.cpMin, range.cpMax ); } case EM_SHOWSCROLLBAR: { @@ -3274,11 +3344,11 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, { LPWSTR wszText; SETTEXTEX *pStruct = (SETTEXTEX *)wParam; - size_t len = 0; - int from, to; + int from, to, len; ME_Style *style; - BOOL bRtf, bUnicode, bSelection; + BOOL bRtf, bUnicode, bSelection, bUTF8; int oldModify = editor->nModifyStep; + static const char utf8_bom[] = {0xef, 0xbb, 0xbf}; if (!pStruct) return 0; @@ -3286,7 +3356,8 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, * we know it isn't unicode. */ bRtf = (lParam && (!strncmp((char *)lParam, "{\\rtf", 5) || !strncmp((char *)lParam, "{\\urtf", 6))); - bUnicode = !bRtf && pStruct->codepage == 1200; + bUnicode = !bRtf && pStruct->codepage == CP_UNICODE; + bUTF8 = (lParam && (!strncmp((char *)lParam, utf8_bom, 3))); TRACE("EM_SETTEXTEX - %s, flags %d, cp %d\n", bUnicode ? debugstr_w((LPCWSTR)lParam) : debugstr_a((LPCSTR)lParam), @@ -3312,11 +3383,15 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, len = lParam ? strlen((char *)lParam) : 0; } } else { - /* FIXME: make use of pStruct->codepage in the to unicode translation */ - wszText = lParam ? ME_ToUnicode(bUnicode, (void *)lParam) : NULL; - len = wszText ? lstrlenW(wszText) : 0; - ME_InsertTextFromCursor(editor, 0, wszText, len, style); - ME_EndToUnicode(bUnicode, wszText); + if (bUTF8 && !bUnicode) { + wszText = ME_ToUnicode(CP_UTF8, (void *)(lParam+3), &len); + ME_InsertTextFromCursor(editor, 0, wszText, len, style); + ME_EndToUnicode(CP_UTF8, wszText); + } else { + wszText = ME_ToUnicode(pStruct->codepage, (void *)lParam, &len); + ME_InsertTextFromCursor(editor, 0, wszText, len, style); + ME_EndToUnicode(pStruct->codepage, wszText); + } } if (bSelection) { @@ -3487,7 +3562,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, { if (!(editor->styleFlags & ES_MULTILINE)) return FALSE; - ME_ScrollDown(editor, lParam * 8); /* FIXME follow the original */ + ME_ScrollDown( editor, lParam * get_default_line_height( editor ) ); return TRUE; } case WM_CLEAR: @@ -3503,8 +3578,9 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, { int from, to, nStartCursor; ME_Style *style; - LPWSTR wszText = lParam ? ME_ToUnicode(unicode, (void *)lParam) : NULL; - size_t len = wszText ? lstrlenW(wszText) : 0; + int len = 0; + LONG codepage = unicode ? CP_UNICODE : CP_ACP; + LPWSTR wszText = ME_ToUnicode(codepage, (void *)lParam, &len); TRACE("EM_REPLACESEL - %s\n", debugstr_w(wszText)); nStartCursor = ME_GetSelectionOfs(editor, &from, &to); @@ -3519,7 +3595,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, */ if (len>0 && wszText[len-1] == '\n') ME_ClearTempStyle(editor); - ME_EndToUnicode(unicode, wszText); + ME_EndToUnicode(codepage, wszText); ME_CommitUndo(editor); ME_UpdateSelectionLinkAttribute(editor); if (!wParam) @@ -3574,9 +3650,11 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } else { - LPWSTR wszText = ME_ToUnicode(unicode, (void *)lParam); + int textLen; + LONG codepage = unicode ? CP_UNICODE : CP_ACP; + LPWSTR wszText = ME_ToUnicode(codepage, (void *)lParam, &textLen); TRACE("WM_SETTEXT - %s\n", debugstr_w(wszText)); /* debugstr_w() */ - if (lstrlenW(wszText) > 0) + if (textLen > 0) { int len = -1; @@ -3591,7 +3669,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } ME_InsertTextFromCursor(editor, 0, wszText, len, editor->pBuffer->pDefaultStyle); } - ME_EndToUnicode(unicode, wszText); + ME_EndToUnicode(codepage, wszText); } } else @@ -3639,7 +3717,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, /* CR/LF conversion required in 2.0 mode, verbatim in 1.0 mode */ how.flags = GTL_CLOSE | (editor->bEmulateVersion10 ? 0 : GTL_USECRLF) | GTL_NUMCHARS; - how.codepage = unicode ? 1200 : CP_ACP; + how.codepage = unicode ? CP_UNICODE : CP_ACP; return ME_GetTextLengthEx(editor, &how); } case EM_GETTEXTLENGTHEX: @@ -3649,7 +3727,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, GETTEXTEX ex; ex.cb = wParam * (unicode ? sizeof(WCHAR) : sizeof(CHAR)); ex.flags = GT_USECRLF; - ex.codepage = unicode ? 1200 : CP_ACP; + ex.codepage = unicode ? CP_UNICODE : CP_ACP; ex.lpDefaultChar = NULL; ex.lpUsedDefChar = NULL; return ME_GetTextEx(editor, &ex, lParam); @@ -3948,6 +4026,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } case WM_CREATE: { + void *text = NULL; INT max; ME_SetDefaultFormatRect(editor); @@ -3973,6 +4052,29 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } } + if (lParam) + { + text = (unicode ? (void*)((CREATESTRUCTW*)lParam)->lpszName + : (void*)((CREATESTRUCTA*)lParam)->lpszName); + } + if (text) + { + WCHAR *textW; + int len; + LONG codepage = unicode ? CP_UNICODE : CP_ACP; + textW = ME_ToUnicode(codepage, text, &len); + if (!(editor->styleFlags & ES_MULTILINE)) + { + len = 0; + while(textW[len] != '\0' && textW[len] != '\r' && textW[len] != '\n') + len++; + } + ME_InsertTextFromCursor(editor, 0, textW, len, editor->pBuffer->pDefaultStyle); + ME_EndToUnicode(codepage, textW); + ME_SetCursorToStart(editor, &editor->pCursors[0]); + ME_SetCursorToStart(editor, &editor->pCursors[1]); + } + ME_CommitUndo(editor); ME_WrapMarkedParagraphs(editor); ME_MoveCaret(editor); @@ -4047,6 +4149,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, case WM_KILLFOCUS: ME_CommitUndo(editor); /* End coalesced undos for typed characters */ editor->bHaveFocus = FALSE; + editor->wheel_remain = 0; ME_HideCaret(editor); ME_SendOldNotify(editor, EN_KILLFOCUS); return 0; @@ -4133,14 +4236,9 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, case WM_VSCROLL: { int origNPos; - int lineHeight; + int lineHeight = get_default_line_height( editor ); origNPos = editor->vert_si.nPos; - lineHeight = 24; - - if (editor->pBuffer && editor->pBuffer->pDefaultStyle) - lineHeight = editor->pBuffer->pDefaultStyle->tm.tmHeight; - if (lineHeight <= 0) lineHeight = 24; switch(LOWORD(wParam)) { @@ -4180,8 +4278,7 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } case WM_MOUSEWHEEL: { - int gcWheelDelta; - UINT pulScrollLines; + int delta; BOOL ctrl_is_down; if ((editor->nEventMask & ENM_MOUSEEVENTS) && @@ -4190,9 +4287,16 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, ctrl_is_down = GetKeyState(VK_CONTROL) & 0x8000; - gcWheelDelta = GET_WHEEL_DELTA_WPARAM(wParam); + delta = GET_WHEEL_DELTA_WPARAM(wParam); - if (abs(gcWheelDelta) >= WHEEL_DELTA) + /* if scrolling changes direction, ignore left overs */ + if ((delta < 0 && editor->wheel_remain < 0) || + (delta > 0 && editor->wheel_remain > 0)) + editor->wheel_remain += delta; + else + editor->wheel_remain = delta; + + if (editor->wheel_remain) { if (ctrl_is_down) { int numerator; @@ -4202,14 +4306,18 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam, } else { numerator = editor->nZoomNumerator * 100 / editor->nZoomDenominator; } - numerator = numerator + (gcWheelDelta / WHEEL_DELTA) * 10; + numerator += calc_wheel_change( &editor->wheel_remain, 10 ); if (numerator >= 10 && numerator <= 500) ME_SetZoom(editor, numerator, 100); } else { - SystemParametersInfoW(SPI_GETWHEELSCROLLLINES,0, &pulScrollLines, 0); - /* FIXME follow the original */ - if (pulScrollLines) - ME_ScrollDown(editor,pulScrollLines * (-gcWheelDelta / WHEEL_DELTA) * 8); + UINT max_lines = 3; + int lines = 0; + + SystemParametersInfoW( SPI_GETWHEELSCROLLLINES, 0, &max_lines, 0 ); + if (max_lines) + lines = calc_wheel_change( &editor->wheel_remain, (int)max_lines ); + if (lines) + ME_ScrollDown( editor, -lines * get_default_line_height( editor ) ); } } break; @@ -4617,7 +4725,7 @@ int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int buflen, int nLen; /* bCRLF flag is only honored in 2.0 and up. 1.0 must always return text verbatim */ - if (editor->bEmulateVersion10) bCRLF = 0; + if (editor->bEmulateVersion10) bCRLF = FALSE; pRun = start->pRun; assert(pRun); @@ -4902,7 +5010,7 @@ static BOOL ME_IsCandidateAnURL(ME_TextEditor *editor, const ME_Cursor *start, i WCHAR bufferW[MAX_PREFIX_LEN + 1]; unsigned int i; - ME_GetTextW(editor, bufferW, MAX_PREFIX_LEN, start, nChars, 0); + ME_GetTextW(editor, bufferW, MAX_PREFIX_LEN, start, nChars, FALSE); for (i = 0; i < sizeof(prefixes) / sizeof(*prefixes); i++) { if (nChars < prefixes[i].length) continue; diff --git a/dll/win32/riched20/editor.h b/dll/win32/riched20/editor.h index 0521522035e..4c19c49620e 100644 --- a/dll/win32/riched20/editor.h +++ b/dll/win32/riched20/editor.h @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -128,7 +129,6 @@ ME_DisplayItem *ME_FindItemBackOrHere(ME_DisplayItem *di, ME_DIType nTypeOrClass ME_DisplayItem *ME_MakeDI(ME_DIType type) DECLSPEC_HIDDEN; void ME_DestroyDisplayItem(ME_DisplayItem *item) DECLSPEC_HIDDEN; void ME_DumpDocument(ME_TextBuffer *buffer) DECLSPEC_HIDDEN; -const char *ME_GetDITypeName(ME_DIType type) DECLSPEC_HIDDEN; /* string.c */ ME_String *ME_MakeStringN(LPCWSTR szText, int nMaxChars) DECLSPEC_HIDDEN; @@ -141,9 +141,11 @@ int ME_CallWordBreakProc(ME_TextEditor *editor, WCHAR *str, INT len, INT start, void ME_StrDeleteV(ME_String *s, int nVChar, int nChars) DECLSPEC_HIDDEN; BOOL ME_InsertString(ME_String *s, int ofs, const WCHAR *insert, int len) DECLSPEC_HIDDEN; +#define CP_UNICODE 1200 + /* smart helpers for A<->W conversions, they reserve/free memory and call MultiByte<->WideChar functions */ -LPWSTR ME_ToUnicode(BOOL unicode, LPVOID psz) DECLSPEC_HIDDEN; -void ME_EndToUnicode(BOOL unicode, LPVOID psz) DECLSPEC_HIDDEN; +LPWSTR ME_ToUnicode(LONG codepage, LPVOID psz, INT *len) DECLSPEC_HIDDEN; +void ME_EndToUnicode(LONG codepage, LPVOID psz) DECLSPEC_HIDDEN; static inline int ME_IsWSpace(WCHAR ch) { @@ -177,7 +179,7 @@ int ME_CharFromPointContext(ME_Context *c, int cx, ME_Run *run, BOOL closest, BO int ME_CharFromPoint(ME_TextEditor *editor, int cx, ME_Run *run, BOOL closest, BOOL visual_order) DECLSPEC_HIDDEN; int ME_PointFromCharContext(ME_Context *c, ME_Run *pRun, int nOffset, BOOL visual_order) DECLSPEC_HIDDEN; int ME_PointFromChar(ME_TextEditor *editor, ME_Run *pRun, int nOffset, BOOL visual_order) DECLSPEC_HIDDEN; -int ME_CanJoinRuns(const ME_Run *run1, const ME_Run *run2) DECLSPEC_HIDDEN; +BOOL ME_CanJoinRuns(const ME_Run *run1, const ME_Run *run2) DECLSPEC_HIDDEN; void ME_JoinRuns(ME_TextEditor *editor, ME_DisplayItem *p) DECLSPEC_HIDDEN; ME_DisplayItem *ME_SplitRunSimple(ME_TextEditor *editor, ME_Cursor *cursor) DECLSPEC_HIDDEN; void ME_UpdateRunFlags(ME_TextEditor *editor, ME_Run *run) DECLSPEC_HIDDEN; @@ -290,7 +292,7 @@ void ME_RTFParAttrHook(struct _RTF_Info *info) DECLSPEC_HIDDEN; void ME_RTFTblAttrHook(struct _RTF_Info *info) DECLSPEC_HIDDEN; void ME_RTFSpecialCharHook(struct _RTF_Info *info) DECLSPEC_HIDDEN; void ME_StreamInFill(ME_InStream *stream) DECLSPEC_HIDDEN; -extern int me_debug DECLSPEC_HIDDEN; +extern BOOL me_debug DECLSPEC_HIDDEN; /* table.c */ BOOL ME_IsInTable(ME_DisplayItem *pItem) DECLSPEC_HIDDEN; diff --git a/dll/win32/riched20/editstr.h b/dll/win32/riched20/editstr.h index 3d696822973..5356b0639bf 100644 --- a/dll/win32/riched20/editstr.h +++ b/dll/win32/riched20/editstr.h @@ -38,6 +38,7 @@ typedef struct tagME_Style HFONT hFont; /* cached font for the style */ TEXTMETRICW tm; /* cached font metrics for the style */ int nRefs; /* reference count */ + SCRIPT_CACHE script_cache; } ME_Style; typedef enum { @@ -104,6 +105,7 @@ typedef enum { #define MEPF_CELL 0x04 /* The paragraph is nested in a cell */ #define MEPF_ROWSTART 0x08 /* Hidden empty paragraph at the start of the row */ #define MEPF_ROWEND 0x10 /* Visible empty paragraph at the end of the row */ +#define MEPF_COMPLEX 0x20 /* Use uniscribe */ /******************************** structures *************************/ @@ -120,6 +122,15 @@ typedef struct tagME_Run int nAscent, nDescent; /* pixels above/below baseline */ POINT pt; /* relative to para's position */ REOBJECT *ole_obj; /* FIXME: should be a union with strText (at least) */ + + SCRIPT_ANALYSIS script_analysis; + int num_glyphs, max_glyphs; + WORD *glyphs; + SCRIPT_VISATTR *vis_attrs; + int *advances; + GOFFSET *offsets; + int max_clusters; + WORD *clusters; } ME_Run; typedef struct tagME_Border @@ -401,6 +412,7 @@ typedef struct tagME_TextEditor SCROLLINFO vert_si, horz_si; BOOL bMouseCaptured; + int wheel_remain; } ME_TextEditor; typedef struct tagME_Context diff --git a/dll/win32/riched20/list.c b/dll/win32/riched20/list.c index f71318a137f..10732e523dd 100644 --- a/dll/win32/riched20/list.c +++ b/dll/win32/riched20/list.c @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ + #include "editor.h" WINE_DEFAULT_DEBUG_CHANNEL(richedit_lists); @@ -138,9 +139,24 @@ ME_DisplayItem *ME_FindItemFwd(ME_DisplayItem *di, ME_DIType nTypeOrClass) return NULL; } +static const char *ME_GetDITypeName(ME_DIType type) +{ + switch(type) + { + case diParagraph: return "diParagraph"; + case diRun: return "diRun"; + case diCell: return "diCell"; + case diTextStart: return "diTextStart"; + case diTextEnd: return "diTextEnd"; + case diStartRow: return "diStartRow"; + default: return "?"; + } +} + void ME_DestroyDisplayItem(ME_DisplayItem *item) { -/* TRACE("type=%s\n", ME_GetDITypeName(item->type)); */ + if (0) + TRACE("type=%s\n", ME_GetDITypeName(item->type)); if (item->type==diParagraph) { FREE_OBJ(item->member.para.pFmt); @@ -150,6 +166,8 @@ void ME_DestroyDisplayItem(ME_DisplayItem *item) if (item->type==diRun) { if (item->member.run.ole_obj) ME_DeleteReObject(item->member.run.ole_obj); + heap_free( item->member.run.glyphs ); + heap_free( item->member.run.clusters ); ME_ReleaseStyle(item->member.run.style); } FREE_OBJ(item); @@ -171,20 +189,6 @@ ME_DisplayItem *ME_MakeDI(ME_DIType type) return item; } -const char *ME_GetDITypeName(ME_DIType type) -{ - switch(type) - { - case diParagraph: return "diParagraph"; - case diRun: return "diRun"; - case diCell: return "diCell"; - case diTextStart: return "diTextStart"; - case diTextEnd: return "diTextEnd"; - case diStartRow: return "diStartRow"; - default: return "?"; - } -} - void ME_DumpDocument(ME_TextBuffer *buffer) { /* FIXME this is useless, */ diff --git a/dll/win32/riched20/msvc-thiscall.c b/dll/win32/riched20/msvc-thiscall.c index 80f34595727..ca96c94b547 100644 --- a/dll/win32/riched20/msvc-thiscall.c +++ b/dll/win32/riched20/msvc-thiscall.c @@ -113,7 +113,7 @@ DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxUIActivate,4) DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxUIDeactivate,4) DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetText,8) DEFINE_THISCALL_WRAPPER(fnTextSrv_TxSetText,8) -DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetCurrentTargetX,8) +DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetCurTargetX,8) DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetBaseLinePos,8) DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetNaturalSize,36) DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetDropTarget,8) diff --git a/dll/win32/riched20/msvc.h b/dll/win32/riched20/msvc.h index 0e44d43f48a..bcc603b1034 100644 --- a/dll/win32/riched20/msvc.h +++ b/dll/win32/riched20/msvc.h @@ -101,7 +101,7 @@ typedef HRESULT (WINAPI typeof(fnTextSrv_OnTxUIActivate))(ITextServices *iface); typedef HRESULT (WINAPI typeof(fnTextSrv_OnTxUIDeactivate))(ITextServices *iface); typedef HRESULT (WINAPI typeof(fnTextSrv_TxGetText))(ITextServices *iface,BSTR* pbstrText); typedef HRESULT (WINAPI typeof(fnTextSrv_TxSetText))(ITextServices *iface,LPCWSTR pszText); -typedef HRESULT (WINAPI typeof(fnTextSrv_TxGetCurrentTargetX))(ITextServices *iface,LONG* x); +typedef HRESULT (WINAPI typeof(fnTextSrv_TxGetCurTargetX))(ITextServices *iface,LONG* x); typedef HRESULT (WINAPI typeof(fnTextSrv_TxGetBaseLinePos))(ITextServices *iface,LONG* x); typedef HRESULT (WINAPI typeof(fnTextSrv_TxGetNaturalSize))(ITextServices *iface,DWORD dwAspect,HDC hdcDraw,HDC hicTargetDev,DVTARGETDEVICE* ptd,DWORD dwMode,const SIZEL* psizelExtent,LONG* pwidth,LONG* pheight); typedef HRESULT (WINAPI typeof(fnTextSrv_TxGetDropTarget))(ITextServices *iface,struct IDropTarget** ppDropTarget); diff --git a/dll/win32/riched20/paint.c b/dll/win32/riched20/paint.c index e728b47432a..f89306113b5 100644 --- a/dll/win32/riched20/paint.c +++ b/dll/win32/riched20/paint.c @@ -331,7 +331,12 @@ static void draw_text( ME_Context *c, ME_Run *run, int x, int y, BOOL selected, old_text = SetTextColor( c->hDC, text_color ); if (selected) old_back = SetBkColor( c->hDC, back_color ); - ExtTextOutW( c->hDC, x, y, selected ? ETO_OPAQUE : 0, sel_rect, text, run->len, NULL ); + if (run->para->nFlags & MEPF_COMPLEX) + ScriptTextOut( c->hDC, &run->style->script_cache, x, y, selected ? ETO_OPAQUE : 0, sel_rect, + &run->script_analysis, NULL, 0, run->glyphs, run->num_glyphs, run->advances, + NULL, run->offsets ); + else + ExtTextOutW( c->hDC, x, y, selected ? ETO_OPAQUE : 0, sel_rect, text, run->len, NULL ); if (selected) SetBkColor( c->hDC, old_back ); SetTextColor( c->hDC, old_text ); diff --git a/dll/win32/riched20/reader.c b/dll/win32/riched20/reader.c index f082a30c9a1..9e115b5514b 100644 --- a/dll/win32/riched20/reader.c +++ b/dll/win32/riched20/reader.c @@ -41,8 +41,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(richedit); -extern HANDLE me_heap; - static int _RTFGetChar(RTF_Info *); static void _RTFGetToken (RTF_Info *); static void _RTFGetToken2 (RTF_Info *); @@ -247,7 +245,7 @@ void RTFInit(RTF_Info *info) info->rtfLineNum = 0; info->rtfLinePos = 0; info->prevChar = EOF; - info->bumpLine = 0; + info->bumpLine = FALSE; info->dwCPOutputCount = 0; if (!info->cpOutputBuffer) @@ -713,7 +711,7 @@ static void _RTFGetToken2(RTF_Info *info) static int GetChar(RTF_Info *info) { int c; - int oldBumpLine; + BOOL oldBumpLine; if ((c = _RTFGetChar(info)) != EOF) { @@ -721,16 +719,16 @@ static int GetChar(RTF_Info *info) info->rtfTextBuf[info->rtfTextLen] = '\0'; } if (info->prevChar == EOF) - info->bumpLine = 1; - oldBumpLine = info->bumpLine; /* non-zero if prev char was line ending */ - info->bumpLine = 0; + info->bumpLine = TRUE; + oldBumpLine = info->bumpLine; /* TRUE if prev char was line ending */ + info->bumpLine = FALSE; if (c == '\r') - info->bumpLine = 1; + info->bumpLine = TRUE; else if (c == '\n') { - info->bumpLine = 1; + info->bumpLine = TRUE; if (info->prevChar == '\r') /* oops, previous \r wasn't */ - oldBumpLine = 0; /* really a line ending */ + oldBumpLine = FALSE; /* really a line ending */ } ++info->rtfLinePos; if (oldBumpLine) /* were we supposed to increment the */ diff --git a/dll/win32/riched20/richole.c b/dll/win32/riched20/richole.c index b9e7699f864..e33bba5b201 100644 --- a/dll/win32/riched20/richole.c +++ b/dll/win32/riched20/richole.c @@ -503,6 +503,9 @@ ITextDocument_fnGetSelection(ITextDocument* me, ITextSelection** ppSel) { IRichEditOleImpl *This = impl_from_ITextDocument(me); TRACE("(%p)\n", me); + + if(!ppSel) + return E_INVALIDARG; *ppSel = &This->txtSel->ITextSelection_iface; ITextSelection_AddRef(*ppSel); return S_OK; @@ -1502,7 +1505,7 @@ LRESULT CreateIRichEditOle(ME_TextEditor *editor, LPVOID *ppObj) return 0; } reo->clientSite = CreateOleClientSite(reo); - if (!reo->txtSel) + if (!reo->clientSite) { ITextSelection_Release(&reo->txtSel->ITextSelection_iface); heap_free(reo); diff --git a/dll/win32/riched20/row.c b/dll/win32/riched20/row.c index 7f48d4a4bab..1bf153f6ca9 100644 --- a/dll/win32/riched20/row.c +++ b/dll/win32/riched20/row.c @@ -21,6 +21,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ + #include "editor.h" /* I'm sure these functions would simplify some code in caret ops etc, diff --git a/dll/win32/riched20/rtf.h b/dll/win32/riched20/rtf.h index 766a8b3b4ec..4b10744b8ef 100644 --- a/dll/win32/riched20/rtf.h +++ b/dll/win32/riched20/rtf.h @@ -1129,7 +1129,7 @@ struct _RTF_Info { char *pushedTextBuf; int prevChar; - int bumpLine; + BOOL bumpLine; /* Document-wide attributes */ RTFFont *fontList; /* these lists MUST be */ diff --git a/dll/win32/riched20/run.c b/dll/win32/riched20/run.c index 8929fc536cb..38d027003fb 100644 --- a/dll/win32/riched20/run.c +++ b/dll/win32/riched20/run.c @@ -30,17 +30,17 @@ WINE_DECLARE_DEBUG_CHANNEL(richedit_lists); /****************************************************************************** * ME_CanJoinRuns * - * Returns 1 if two runs can be safely merged into one, 0 otherwise. - */ -int ME_CanJoinRuns(const ME_Run *run1, const ME_Run *run2) + * Returns TRUE if two runs can be safely merged into one, FALSE otherwise. + */ +BOOL ME_CanJoinRuns(const ME_Run *run1, const ME_Run *run2) { if ((run1->nFlags | run2->nFlags) & MERF_NOJOIN) - return 0; + return FALSE; if (run1->style != run2->style) - return 0; + return FALSE; if ((run1->nFlags & MERF_STYLEFLAGS) != (run2->nFlags & MERF_STYLEFLAGS)) - return 0; - return 1; + return FALSE; + return TRUE; } void ME_SkipAndPropagateCharOffset(ME_DisplayItem *p, int shift) @@ -295,6 +295,14 @@ ME_DisplayItem *ME_MakeRun(ME_Style *s, int nFlags) item->member.run.nCharOfs = -1; item->member.run.len = 0; item->member.run.para = NULL; + item->member.run.num_glyphs = 0; + item->member.run.max_glyphs = 0; + item->member.run.glyphs = NULL; + item->member.run.vis_attrs = NULL; + item->member.run.advances = NULL; + item->member.run.offsets = NULL; + item->member.run.max_clusters = 0; + item->member.run.clusters = NULL; ME_AddRefStyle(s); return item; } @@ -310,23 +318,52 @@ ME_DisplayItem * ME_InsertRunAtCursor(ME_TextEditor *editor, ME_Cursor *cursor, ME_Style *style, const WCHAR *str, int len, int flags) { - ME_DisplayItem *pDI; + ME_DisplayItem *pDI, *insert_before = cursor->pRun, *prev; if (cursor->nOffset) - ME_SplitRunSimple(editor, cursor); + { + if (cursor->nOffset == cursor->pRun->member.run.len) + { + insert_before = ME_FindItemFwd( cursor->pRun, diRun ); + if (!insert_before) insert_before = cursor->pRun; /* Always insert before the final eop run */ + } + else + { + ME_SplitRunSimple( editor, cursor ); + insert_before = cursor->pRun; + } + } - add_undo_delete_run( editor, cursor->pPara->member.para.nCharOfs + - cursor->pRun->member.run.nCharOfs, len ); + add_undo_delete_run( editor, insert_before->member.run.para->nCharOfs + + insert_before->member.run.nCharOfs, len ); pDI = ME_MakeRun(style, flags); - pDI->member.run.nCharOfs = cursor->pRun->member.run.nCharOfs; + pDI->member.run.nCharOfs = insert_before->member.run.nCharOfs; pDI->member.run.len = len; - pDI->member.run.para = cursor->pRun->member.run.para; + pDI->member.run.para = insert_before->member.run.para; ME_InsertString( pDI->member.run.para->text, pDI->member.run.nCharOfs, str, len ); - ME_InsertBefore(cursor->pRun, pDI); + ME_InsertBefore( insert_before, pDI ); TRACE("Shift length:%d\n", len); - ME_PropagateCharOffset(cursor->pRun, len); - cursor->pPara->member.para.nFlags |= MEPF_REWRAP; + ME_PropagateCharOffset( insert_before, len ); + insert_before->member.run.para->nFlags |= MEPF_REWRAP; + + /* Move any cursors that were at the end of the previous run to the end of the inserted run */ + prev = ME_FindItemBack( pDI, diRun ); + if (prev) + { + int i; + + for (i = 0; i < editor->nCursors; i++) + { + if (editor->pCursors[i].pRun == prev && + editor->pCursors[i].nOffset == prev->member.run.len) + { + editor->pCursors[i].pRun = pDI; + editor->pCursors[i].nOffset = len; + } + } + } + return pDI; } @@ -439,6 +476,18 @@ int ME_CharFromPointContext(ME_Context *c, int cx, ME_Run *run, BOOL closest, BO return 1; } + if (run->para->nFlags & MEPF_COMPLEX) + { + int cp, trailing; + if (visual_order && run->script_analysis.fRTL) cx = run->nWidth - cx - 1; + + ScriptXtoCP( cx, run->len, run->num_glyphs, run->clusters, run->vis_attrs, run->advances, &run->script_analysis, + &cp, &trailing ); + TRACE("x %d cp %d trailing %d (run width %d) rtl %d log order %d\n", cx, cp, trailing, run->nWidth, + run->script_analysis.fRTL, run->script_analysis.fLogicalOrder); + return closest ? cp + trailing : cp; + } + if (c->editor->cPasswordMask) { mask_text = ME_MakeStringR( c->editor->cPasswordMask, run->len ); @@ -514,6 +563,14 @@ int ME_PointFromCharContext(ME_Context *c, ME_Run *pRun, int nOffset, BOOL visua nOffset = 0; } + if (pRun->para->nFlags & MEPF_COMPLEX) + { + int x; + ScriptCPtoX( nOffset, FALSE, pRun->len, pRun->num_glyphs, pRun->clusters, + pRun->vis_attrs, pRun->advances, &pRun->script_analysis, &x ); + if (visual_order && pRun->script_analysis.fRTL) x = pRun->nWidth - x - 1; + return x; + } if (c->editor->cPasswordMask) { mask_text = ME_MakeStringR(c->editor->cPasswordMask, pRun->len); @@ -563,8 +620,12 @@ SIZE ME_GetRunSizeCommon(ME_Context *c, const ME_Paragraph *para, ME_Run *run, i * this is wasteful for MERF_NONTEXT runs, but that shouldn't matter * in practice */ - - if (c->editor->cPasswordMask) + + if (para->nFlags & MEPF_COMPLEX) + { + size.cx = run->nWidth; + } + else if (c->editor->cPasswordMask) { ME_String *szMasked = ME_MakeStringR(c->editor->cPasswordMask,nLen); ME_GetTextExtent(c, szMasked->szData, nLen,run->style, &size); @@ -658,19 +719,20 @@ void ME_SetSelectionCharFormat(ME_TextEditor *editor, CHARFORMAT2W *pFmt) */ void ME_SetCharFormat(ME_TextEditor *editor, ME_Cursor *start, ME_Cursor *end, CHARFORMAT2W *pFmt) { - ME_DisplayItem *para; - ME_DisplayItem *run; - ME_DisplayItem *end_run = NULL; + ME_DisplayItem *run, *start_run = start->pRun, *end_run = NULL; if (end && start->pRun == end->pRun && start->nOffset == end->nOffset) return; - if (start->nOffset) + if (start->nOffset == start->pRun->member.run.len) + start_run = ME_FindItemFwd( start->pRun, diRun ); + else if (start->nOffset) { /* SplitRunSimple may or may not update the cursors, depending on whether they * are selection cursors, but we need to make sure they are valid. */ int split_offset = start->nOffset; ME_DisplayItem *split_run = ME_SplitRunSimple(editor, start); + start_run = start->pRun; if (end && end->pRun == split_run) { end->pRun = start->pRun; @@ -678,31 +740,26 @@ void ME_SetCharFormat(ME_TextEditor *editor, ME_Cursor *start, ME_Cursor *end, C } } - if (end && end->nOffset) - ME_SplitRunSimple(editor, end); - end_run = end ? end->pRun : NULL; + if (end) + { + if (end->nOffset == end->pRun->member.run.len) + end_run = ME_FindItemFwd( end->pRun, diRun ); + else + { + if (end->nOffset) ME_SplitRunSimple(editor, end); + end_run = end->pRun; + } + } - run = start->pRun; - para = start->pPara; - para->member.para.nFlags |= MEPF_REWRAP; - - while(run != end_run) + for (run = start_run; run != end_run; run = ME_FindItemFwd( run, diRun )) { ME_Style *new_style = ME_ApplyStyle(run->member.run.style, pFmt); - /* ME_DumpStyle(new_style); */ - add_undo_set_char_fmt( editor, para->member.para.nCharOfs + run->member.run.nCharOfs, + add_undo_set_char_fmt( editor, run->member.run.para->nCharOfs + run->member.run.nCharOfs, run->member.run.len, &run->member.run.style->fmt ); ME_ReleaseStyle(run->member.run.style); run->member.run.style = new_style; - run = ME_FindItemFwd(run, diRunOrParagraph); - if (run && run->type == diParagraph) - { - para = run; - run = ME_FindItemFwd(run, diRun); - if (run != end_run) - para->member.para.nFlags |= MEPF_REWRAP; - } + run->member.run.para->nFlags |= MEPF_REWRAP; } } diff --git a/dll/win32/riched20/string.c b/dll/win32/riched20/string.c index 6d7d222bde8..12e4ad741ee 100644 --- a/dll/win32/riched20/string.c +++ b/dll/win32/riched20/string.c @@ -172,23 +172,30 @@ ME_CallWordBreakProc(ME_TextEditor *editor, WCHAR *str, INT len, INT start, INT } } -LPWSTR ME_ToUnicode(BOOL unicode, LPVOID psz) +LPWSTR ME_ToUnicode(LONG codepage, LPVOID psz, INT *len) { - assert(psz != NULL); + *len = 0; + if (!psz) return NULL; - if (unicode) + if (codepage == CP_UNICODE) + { + *len = lstrlenW(psz); return psz; + } else { WCHAR *tmp; - int nChars = MultiByteToWideChar(CP_ACP, 0, psz, -1, NULL, 0); + int nChars = MultiByteToWideChar(codepage, 0, psz, -1, NULL, 0); + + if(!nChars) return NULL; + if((tmp = ALLOC_N_OBJ(WCHAR, nChars)) != NULL) - MultiByteToWideChar(CP_ACP, 0, psz, -1, tmp, nChars); + *len = MultiByteToWideChar(codepage, 0, psz, -1, tmp, nChars) - 1; return tmp; } } -void ME_EndToUnicode(BOOL unicode, LPVOID psz) +void ME_EndToUnicode(LONG codepage, LPVOID psz) { - if (!unicode) + if (codepage != CP_UNICODE) FREE_OBJ(psz); } diff --git a/dll/win32/riched20/style.c b/dll/win32/riched20/style.c index 62927149074..0817ea80004 100644 --- a/dll/win32/riched20/style.c +++ b/dll/win32/riched20/style.c @@ -149,6 +149,7 @@ ME_Style *ME_MakeStyle(CHARFORMAT2W *style) s->hFont = NULL; memset(&s->tm, 0, sizeof(s->tm)); s->tm.tmAscent = -1; + s->script_cache = NULL; all_refs++; TRACE_(richedit_style)("ME_MakeStyle %p, total refs=%d\n", s, all_refs); return s; @@ -435,6 +436,7 @@ static void ME_DestroyStyle(ME_Style *s) { DeleteObject(s->hFont); s->hFont = NULL; } + ScriptFreeCache( &s->script_cache ); FREE_OBJ(s); } diff --git a/dll/win32/riched20/table.c b/dll/win32/riched20/table.c index d5fbfcbd450..e78a1df20aa 100644 --- a/dll/win32/riched20/table.c +++ b/dll/win32/riched20/table.c @@ -34,7 +34,7 @@ * * Richedit version 4.1: * Tables are implemented such that cells can contain multiple paragraphs, - * each with it's own paragraph format, and cells may even contain tables + * each with its own paragraph format, and cells may even contain tables * nested within the cell. * * There is also a paragraph at the start of each table row that contains diff --git a/dll/win32/riched20/txtsrv.c b/dll/win32/riched20/txtsrv.c index 613919da4aa..fe4bf34eb7f 100644 --- a/dll/win32/riched20/txtsrv.c +++ b/dll/win32/riched20/txtsrv.c @@ -278,7 +278,7 @@ DECLSPEC_HIDDEN HRESULT WINAPI fnTextSrv_TxSetText(ITextServices *iface, LPCWSTR return S_OK; } -DECLSPEC_HIDDEN HRESULT WINAPI fnTextSrv_TxGetCurrentTargetX(ITextServices *iface, LONG *x) +DECLSPEC_HIDDEN HRESULT WINAPI fnTextSrv_TxGetCurTargetX(ITextServices *iface, LONG *x) { ITextServicesImpl *This = impl_from_ITextServices(iface); @@ -340,7 +340,7 @@ DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxUIActivate,4) DEFINE_THISCALL_WRAPPER(fnTextSrv_OnTxUIDeactivate,4) DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetText,8) DEFINE_THISCALL_WRAPPER(fnTextSrv_TxSetText,8) -DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetCurrentTargetX,8) +DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetCurTargetX,8) DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetBaseLinePos,8) DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetNaturalSize,36) DEFINE_THISCALL_WRAPPER(fnTextSrv_TxGetDropTarget,8) @@ -364,7 +364,7 @@ static const ITextServicesVtbl textservices_vtbl = THISCALL(fnTextSrv_OnTxUIDeactivate), THISCALL(fnTextSrv_TxGetText), THISCALL(fnTextSrv_TxSetText), - THISCALL(fnTextSrv_TxGetCurrentTargetX), + THISCALL(fnTextSrv_TxGetCurTargetX), THISCALL(fnTextSrv_TxGetBaseLinePos), THISCALL(fnTextSrv_TxGetNaturalSize), THISCALL(fnTextSrv_TxGetDropTarget), diff --git a/dll/win32/riched20/wrap.c b/dll/win32/riched20/wrap.c index 4509a54b955..6c9f2e3d5dd 100644 --- a/dll/win32/riched20/wrap.c +++ b/dll/win32/riched20/wrap.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ + #include "editor.h" WINE_DEFAULT_DEBUG_CHANNEL(richedit); @@ -31,6 +32,66 @@ WINE_DEFAULT_DEBUG_CHANNEL(richedit); * - no tabs */ + +static BOOL get_run_glyph_buffers( ME_Run *run ) +{ + heap_free( run->glyphs ); + run->glyphs = heap_alloc( run->max_glyphs * (sizeof(WORD) + sizeof(SCRIPT_VISATTR) + sizeof(int) + sizeof(GOFFSET)) ); + if (!run->glyphs) return FALSE; + + run->vis_attrs = (SCRIPT_VISATTR*)((char*)run->glyphs + run->max_glyphs * sizeof(WORD)); + run->advances = (int*)((char*)run->glyphs + run->max_glyphs * (sizeof(WORD) + sizeof(SCRIPT_VISATTR))); + run->offsets = (GOFFSET*)((char*)run->glyphs + run->max_glyphs * (sizeof(WORD) + sizeof(SCRIPT_VISATTR) + sizeof(int))); + + return TRUE; +} + +static HRESULT shape_run( ME_Context *c, ME_Run *run ) +{ + HRESULT hr; + HFONT old_font; + int i; + + if (!run->glyphs) + { + run->max_glyphs = 1.5 * run->len + 16; /* This is suggested in the uniscribe documentation */ + run->max_glyphs = (run->max_glyphs + 7) & ~7; /* Keep alignment simple */ + get_run_glyph_buffers( run ); + } + + if (run->max_clusters < run->len) + { + heap_free( run->clusters ); + run->max_clusters = run->len * 2; + run->clusters = heap_alloc( run->max_clusters * sizeof(WORD) ); + } + + old_font = ME_SelectStyleFont( c, run->style ); + while (1) + { + hr = ScriptShape( c->hDC, &run->style->script_cache, get_text( run, 0 ), run->len, run->max_glyphs, + &run->script_analysis, run->glyphs, run->clusters, run->vis_attrs, &run->num_glyphs ); + if (hr != E_OUTOFMEMORY) break; + if (run->max_glyphs > 10 * run->len) break; /* something has clearly gone wrong */ + run->max_glyphs *= 2; + get_run_glyph_buffers( run ); + } + + if (SUCCEEDED(hr)) + hr = ScriptPlace( c->hDC, &run->style->script_cache, run->glyphs, run->num_glyphs, run->vis_attrs, + &run->script_analysis, run->advances, run->offsets, NULL ); + + if (SUCCEEDED(hr)) + { + for (i = 0, run->nWidth = 0; i < run->num_glyphs; i++) + run->nWidth += run->advances[i]; + } + + ME_UnselectStyleFont( c, run->style, old_font ); + + return hr; +} + /****************************************************************************** * calc_run_extent * @@ -77,7 +138,10 @@ static ME_DisplayItem *split_run_extents(ME_WrapContext *wc, ME_DisplayItem *ite ME_SplitRunSimple(editor, &cursor); run2 = &cursor.pRun->member.run; + run2->script_analysis = run->script_analysis; + shape_run( wc->context, run ); + shape_run( wc->context, run2 ); calc_run_extent(wc->context, para, wc->nRow ? wc->nLeftMargin : wc->nFirstMargin, run); run2->pt.x = run->pt.x+run->nWidth; @@ -165,15 +229,73 @@ static void ME_BeginRow(ME_WrapContext *wc) wc->pt.y++; } +static void layout_row( ME_DisplayItem *start, const ME_DisplayItem *end ) +{ + ME_DisplayItem *p; + int i, num_runs = 0; + int buf[16 * 5]; /* 5 arrays - 4 of int & 1 of BYTE, alloc space for 5 of ints */ + int *vis_to_log = buf, *log_to_vis, *widths, *pos; + BYTE *levels; + BOOL found_black = FALSE; + + for (p = end->prev; p != start->prev; p = p->prev) + { + if (p->type == diRun) + { + if (!found_black) found_black = !(p->member.run.nFlags & (MERF_WHITESPACE | MERF_ENDPARA)); + if (found_black) num_runs++; + } + } + + TRACE("%d runs\n", num_runs); + if (!num_runs) return; + + if (num_runs > sizeof(buf) / (sizeof(buf[0]) * 5)) + vis_to_log = heap_alloc( num_runs * sizeof(int) * 5 ); + + log_to_vis = vis_to_log + num_runs; + widths = vis_to_log + 2 * num_runs; + pos = vis_to_log + 3 * num_runs; + levels = (BYTE*)(vis_to_log + 4 * num_runs); + + for (i = 0, p = start; i < num_runs; p = p->next) + { + if (p->type == diRun) + { + levels[i] = p->member.run.script_analysis.s.uBidiLevel; + widths[i] = p->member.run.nWidth; + TRACE( "%d: level %d width %d\n", i, levels[i], widths[i] ); + i++; + } + } + + ScriptLayout( num_runs, levels, vis_to_log, log_to_vis ); + + pos[0] = start->member.run.para->pt.x; + for (i = 1; i < num_runs; i++) + pos[i] = pos[i - 1] + widths[ vis_to_log[ i - 1 ] ]; + + for (i = 0, p = start; i < num_runs; p = p->next) + { + if (p->type == diRun) + { + p->member.run.pt.x = pos[ log_to_vis[ i ] ]; + TRACE( "%d: x = %d\n", i, p->member.run.pt.x ); + i++; + } + } + + if (vis_to_log != buf) heap_free( vis_to_log ); +} + static void ME_InsertRowStart(ME_WrapContext *wc, const ME_DisplayItem *pEnd) { - ME_DisplayItem *p, *row, *para; + ME_DisplayItem *p, *row; + ME_Paragraph *para = &wc->pPara->member.para; BOOL bSkippingSpaces = TRUE; int ascent = 0, descent = 0, width=0, shift = 0, align = 0; - PARAFORMAT2 *pFmt; + /* wrap text */ - para = wc->pPara; - pFmt = para->member.para.pFmt; for (p = pEnd->prev; p!=wc->pRowStart->prev; p = p->prev) { @@ -207,10 +329,10 @@ static void ME_InsertRowStart(ME_WrapContext *wc, const ME_DisplayItem *pEnd) } } - para->member.para.nWidth = max(para->member.para.nWidth, width); + para->nWidth = max(para->nWidth, width); row = ME_MakeRow(ascent+descent, ascent, width); if (wc->context->editor->bEmulateVersion10 && /* v1.0 - 3.0 */ - pFmt->dwMask & PFM_TABLE && pFmt->wEffects & PFE_TABLE) + (para->pFmt->dwMask & PFM_TABLE) && (para->pFmt->wEffects & PFE_TABLE)) { /* The text was shifted down in ME_BeginRow so move the wrap context * back to where it should be. */ @@ -221,12 +343,15 @@ static void ME_InsertRowStart(ME_WrapContext *wc, const ME_DisplayItem *pEnd) row->member.row.pt = wc->pt; row->member.row.nLMargin = (!wc->nRow ? wc->nFirstMargin : wc->nLeftMargin); row->member.row.nRMargin = wc->nRightMargin; - assert(para->member.para.pFmt->dwMask & PFM_ALIGNMENT); - align = para->member.para.pFmt->wAlignment; + assert(para->pFmt->dwMask & PFM_ALIGNMENT); + align = para->pFmt->wAlignment; if (align == PFA_CENTER) shift = max((wc->nAvailWidth-width)/2, 0); if (align == PFA_RIGHT) shift = max(wc->nAvailWidth-width, 0); + + if (para->nFlags & MEPF_COMPLEX) layout_row( wc->pRowStart, pEnd ); + row->member.row.pt.x = row->member.row.nLMargin + shift; for (p = wc->pRowStart; p!=pEnd; p = p->next) { @@ -613,6 +738,111 @@ static void ME_PrepareParagraphForWrapping(ME_Context *c, ME_DisplayItem *tp) { } } +static HRESULT itemize_para( ME_Context *c, ME_DisplayItem *p ) +{ + ME_Paragraph *para = &p->member.para; + ME_Run *run; + ME_DisplayItem *di; + SCRIPT_ITEM buf[16], *items = buf; + int items_passed = sizeof( buf ) / sizeof( buf[0] ), num_items, cur_item; + SCRIPT_CONTROL control = { LANG_USER_DEFAULT, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, + FALSE, FALSE, 0 }; + SCRIPT_STATE state = { 0, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 0, 0 }; + HRESULT hr; + + assert( p->type == diParagraph ); + + while (1) + { + hr = ScriptItemize( para->text->szData, para->text->nLen, items_passed, &control, + &state, items, &num_items ); + if (hr != E_OUTOFMEMORY) break; /* may not be enough items if hr == E_OUTOFMEMORY */ + if (items_passed > para->text->nLen + 1) break; /* something else has gone wrong */ + items_passed *= 2; + if (items == buf) + items = heap_alloc( items_passed * sizeof( *items ) ); + else + items = heap_realloc( items, items_passed * sizeof( *items ) ); + if (!items) break; + } + if (FAILED( hr )) goto end; + + if (TRACE_ON( richedit )) + { + TRACE( "got items:\n" ); + for (cur_item = 0; cur_item < num_items; cur_item++) + { + TRACE( "\t%d - %d RTL %d bidi level %d\n", items[cur_item].iCharPos, items[cur_item+1].iCharPos - 1, + items[cur_item].a.fRTL, items[cur_item].a.s.uBidiLevel ); + } + + TRACE( "before splitting runs into ranges\n" ); + for (di = p->next; di != p->member.para.next_para; di = di->next) + { + if (di->type != diRun) continue; + TRACE( "\t%d: %s\n", di->member.run.nCharOfs, debugstr_run( &di->member.run ) ); + } + } + + /* split runs into ranges at item boundaries */ + for (di = p->next, cur_item = 0; di != p->member.para.next_para; di = di->next) + { + if (di->type != diRun) continue; + run = &di->member.run; + + if (run->nCharOfs == items[cur_item+1].iCharPos) cur_item++; + + items[cur_item].a.fLogicalOrder = TRUE; + run->script_analysis = items[cur_item].a; + + if (run->nFlags & MERF_ENDPARA) break; /* don't split eop runs */ + + if (run->nCharOfs + run->len > items[cur_item+1].iCharPos) + { + ME_Cursor cursor = {p, di, items[cur_item+1].iCharPos - run->nCharOfs}; + ME_SplitRunSimple( c->editor, &cursor ); + } + } + + if (TRACE_ON( richedit )) + { + TRACE( "after splitting into ranges\n" ); + for (di = p->next; di != p->member.para.next_para; di = di->next) + { + if (di->type != diRun) continue; + TRACE( "\t%d: %s\n", di->member.run.nCharOfs, debugstr_run( &di->member.run ) ); + } + } + + para->nFlags |= MEPF_COMPLEX; + +end: + if (items != buf) heap_free( items ); + return hr; +} + + +static HRESULT shape_para( ME_Context *c, ME_DisplayItem *p ) +{ + ME_DisplayItem *di; + ME_Run *run; + HRESULT hr; + + for (di = p->next; di != p->member.para.next_para; di = di->next) + { + if (di->type != diRun) continue; + run = &di->member.run; + + hr = shape_run( c, run ); + if (FAILED( hr )) + { + run->para->nFlags &= ~MEPF_COMPLEX; + return hr; + } + } + return hr; +} + static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) { ME_DisplayItem *p; ME_WrapContext wc; @@ -625,6 +855,15 @@ static void ME_WrapTextParagraph(ME_Context *c, ME_DisplayItem *tp) { return; } ME_PrepareParagraphForWrapping(c, tp); + + /* For now treating all non-password text as complex for better testing */ + if (!c->editor->cPasswordMask /* && + ScriptIsComplex( tp->member.para.text->szData, tp->member.para.text->nLen, SIC_COMPLEX ) == S_OK */) + { + if (SUCCEEDED( itemize_para( c, tp ) )) + shape_para( c, tp ); + } + pFmt = tp->member.para.pFmt; wc.context = c; diff --git a/dll/win32/riched20/writer.c b/dll/win32/riched20/writer.c index c67d1921da5..9a2c3c7f87a 100644 --- a/dll/win32/riched20/writer.c +++ b/dll/win32/riched20/writer.c @@ -23,6 +23,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(richedit); + static BOOL ME_StreamOutRTFText(ME_OutStream *pStream, const WCHAR *text, LONG nChars); diff --git a/dll/win32/rpcrt4/epm.idl b/dll/win32/rpcrt4/epm.idl index 67fad348c88..52951869c1f 100644 --- a/dll/win32/rpcrt4/epm.idl +++ b/dll/win32/rpcrt4/epm.idl @@ -16,4 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma makedep client + #include "wine/epm.idl" diff --git a/dll/win32/rpcrt4/ndr_marshall.c b/dll/win32/rpcrt4/ndr_marshall.c index cff81857284..6f19cb35761 100644 --- a/dll/win32/rpcrt4/ndr_marshall.c +++ b/dll/win32/rpcrt4/ndr_marshall.c @@ -789,7 +789,7 @@ static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING desc; NDR_MARSHALL m; ULONG pointer_id; - int pointer_needs_marshaling; + BOOL pointer_needs_marshaling; TRACE("(%p,%p,%p,%p)\n", pStubMsg, Buffer, Pointer, pFormat); TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr); @@ -804,14 +804,14 @@ static void PointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, ERR("NULL ref pointer is not allowed\n"); RpcRaiseException(RPC_X_NULL_REF_POINTER); } - pointer_needs_marshaling = 1; + pointer_needs_marshaling = TRUE; break; case RPC_FC_UP: /* unique pointer */ case RPC_FC_OP: /* object pointer - same as unique here */ if (Pointer) - pointer_needs_marshaling = 1; + pointer_needs_marshaling = TRUE; else - pointer_needs_marshaling = 0; + pointer_needs_marshaling = FALSE; pointer_id = Pointer ? NDR_POINTER_ID(pStubMsg) : 0; TRACE("writing 0x%08x to buffer\n", pointer_id); NDR_LOCAL_UINT32_WRITE(Buffer, pointer_id); @@ -857,7 +857,7 @@ static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING desc; NDR_UNMARSHALL m; DWORD pointer_id = 0; - int pointer_needs_unmarshaling; + BOOL pointer_needs_unmarshaling; TRACE("(%p,%p,%p,%p,%p,%d)\n", pStubMsg, Buffer, pPointer, pSrcPointer, pFormat, fMustAlloc); TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr); @@ -867,16 +867,16 @@ static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, switch (type) { case RPC_FC_RP: /* ref pointer (always non-null) */ - pointer_needs_unmarshaling = 1; + pointer_needs_unmarshaling = TRUE; break; case RPC_FC_UP: /* unique pointer */ pointer_id = NDR_LOCAL_UINT32_READ(Buffer); TRACE("pointer_id is 0x%08x\n", pointer_id); if (pointer_id) - pointer_needs_unmarshaling = 1; + pointer_needs_unmarshaling = TRUE; else { *pPointer = NULL; - pointer_needs_unmarshaling = 0; + pointer_needs_unmarshaling = FALSE; } break; case RPC_FC_OP: /* object pointer - we must free data before overwriting it */ @@ -888,11 +888,11 @@ static void PointerUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, fMustAlloc = TRUE; } if (pointer_id) - pointer_needs_unmarshaling = 1; + pointer_needs_unmarshaling = TRUE; else { *pPointer = NULL; - pointer_needs_unmarshaling = 0; + pointer_needs_unmarshaling = FALSE; } break; case RPC_FC_FP: @@ -972,7 +972,7 @@ static void PointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned type = pFormat[0], attr = pFormat[1]; PFORMAT_STRING desc; NDR_BUFFERSIZE m; - int pointer_needs_sizing; + BOOL pointer_needs_sizing; ULONG pointer_id; TRACE("(%p,%p,%p)\n", pStubMsg, Pointer, pFormat); @@ -1027,7 +1027,7 @@ static ULONG PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING desc; NDR_MEMORYSIZE m; DWORD pointer_id = 0; - int pointer_needs_sizing; + BOOL pointer_needs_sizing; TRACE("(%p,%p,%p)\n", pStubMsg, Buffer, pFormat); TRACE("type=0x%x, attr=", type); dump_pointer_attr(attr); @@ -1037,16 +1037,16 @@ static ULONG PointerMemorySize(PMIDL_STUB_MESSAGE pStubMsg, switch (type) { case RPC_FC_RP: /* ref pointer (always non-null) */ - pointer_needs_sizing = 1; + pointer_needs_sizing = TRUE; break; case RPC_FC_UP: /* unique pointer */ case RPC_FC_OP: /* object pointer - we must free data before overwriting it */ pointer_id = NDR_LOCAL_UINT32_READ(Buffer); TRACE("pointer_id is 0x%08x\n", pointer_id); if (pointer_id) - pointer_needs_sizing = 1; + pointer_needs_sizing = TRUE; else - pointer_needs_sizing = 0; + pointer_needs_sizing = FALSE; break; case RPC_FC_FP: { @@ -1193,7 +1193,7 @@ static unsigned char * EmbeddedPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *bufptr = bufbase + *(const SHORT*)&info[2]; unsigned char *saved_memory = pStubMsg->Memory; - pStubMsg->Memory = membase; + pStubMsg->Memory = pMemory; PointerMarshall(pStubMsg, bufptr, *(unsigned char**)memptr, info+4); pStubMsg->Memory = saved_memory; } @@ -1347,7 +1347,7 @@ static void EmbeddedPointerBufferSize(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *memptr = membase + *(const SHORT*)&info[0]; unsigned char *saved_memory = pStubMsg->Memory; - pStubMsg->Memory = membase; + pStubMsg->Memory = pMemory; PointerBufferSize(pStubMsg, *(unsigned char**)memptr, info+4); pStubMsg->Memory = saved_memory; } @@ -2874,7 +2874,7 @@ static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg, case RPC_FC_POINTER: { unsigned char *saved_buffer; - int pointer_buffer_mark_set = 0; + BOOL pointer_buffer_mark_set = FALSE; TRACE("pointer=%p <= %p\n", *(unsigned char**)pMemory, pMemory); TRACE("pStubMsg->Buffer before %p\n", pStubMsg->Buffer); if (*pFormat != RPC_FC_POINTER) @@ -2886,7 +2886,7 @@ static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg, { pStubMsg->Buffer = pStubMsg->PointerBufferMark; pStubMsg->PointerBufferMark = NULL; - pointer_buffer_mark_set = 1; + pointer_buffer_mark_set = TRUE; } else if (*pPointer != RPC_FC_RP) safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ @@ -3043,7 +3043,7 @@ static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, case RPC_FC_POINTER: { unsigned char *saved_buffer; - int pointer_buffer_mark_set = 0; + BOOL pointer_buffer_mark_set = FALSE; TRACE("pointer => %p\n", pMemory); if (*pFormat != RPC_FC_POINTER) pPointer = pFormat; @@ -3054,7 +3054,7 @@ static unsigned char * ComplexUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, { pStubMsg->Buffer = pStubMsg->PointerBufferMark; pStubMsg->PointerBufferMark = NULL; - pointer_buffer_mark_set = 1; + pointer_buffer_mark_set = TRUE; } else if (*pPointer != RPC_FC_RP) safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ @@ -3408,7 +3408,7 @@ static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, case RPC_FC_POINTER: { unsigned char *saved_buffer; - int pointer_buffer_mark_set = 0; + BOOL pointer_buffer_mark_set = FALSE; if (*pFormat != RPC_FC_POINTER) pPointer = pFormat; if (*pPointer != RPC_FC_RP) @@ -3418,7 +3418,7 @@ static ULONG ComplexStructMemorySize(PMIDL_STUB_MESSAGE pStubMsg, { pStubMsg->Buffer = pStubMsg->PointerBufferMark; pStubMsg->PointerBufferMark = NULL; - pointer_buffer_mark_set = 1; + pointer_buffer_mark_set = TRUE; } else if (*pPointer != RPC_FC_RP) safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ @@ -3564,7 +3564,7 @@ unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING conf_array = NULL; PFORMAT_STRING pointer_desc = NULL; unsigned char *OldMemory = pStubMsg->Memory; - int pointer_buffer_mark_set = 0; + BOOL pointer_buffer_mark_set = FALSE; ULONG count = 0; ULONG max_count = 0; ULONG offset = 0; @@ -3587,7 +3587,7 @@ unsigned char * WINAPI NdrComplexStructMarshall(PMIDL_STUB_MESSAGE pStubMsg, /* save it for use by embedded pointer code later */ pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength; TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - pStubMsg->Buffer)); - pointer_buffer_mark_set = 1; + pointer_buffer_mark_set = TRUE; /* restore the original buffer length */ pStubMsg->BufferLength = saved_buffer_length; @@ -3650,7 +3650,7 @@ unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, PFORMAT_STRING conf_array = NULL; PFORMAT_STRING pointer_desc = NULL; unsigned char *pMemory; - int pointer_buffer_mark_set = 0; + BOOL pointer_buffer_mark_set = FALSE; ULONG count = 0; ULONG max_count = 0; ULONG offset = 0; @@ -3673,7 +3673,7 @@ unsigned char * WINAPI NdrComplexStructUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, /* save it for use by embedded pointer code later */ pStubMsg->PointerBufferMark = pStubMsg->Buffer; TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->PointerBufferMark - saved_buffer)); - pointer_buffer_mark_set = 1; + pointer_buffer_mark_set = TRUE; /* restore the original buffer */ pStubMsg->Buffer = saved_buffer; @@ -4113,7 +4113,7 @@ unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char *pMemory, PFORMAT_STRING pFormat) { - int pointer_buffer_mark_set = 0; + BOOL pointer_buffer_mark_set = FALSE; TRACE("(%p,%p,%p)\n", pStubMsg, pMemory, pFormat); @@ -4144,7 +4144,7 @@ unsigned char * WINAPI NdrComplexArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg, /* save it for use by embedded pointer code later */ pStubMsg->PointerBufferMark = (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength; TRACE("difference = 0x%x\n", (ULONG)(pStubMsg->Buffer - (unsigned char *)pStubMsg->RpcMsg->Buffer)); - pointer_buffer_mark_set = 1; + pointer_buffer_mark_set = TRUE; /* restore fields */ pStubMsg->ActualCount = saved_actual_count; @@ -4177,7 +4177,7 @@ unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned char fMustAlloc) { unsigned char *saved_buffer; - int pointer_buffer_mark_set = 0; + BOOL pointer_buffer_mark_set = FALSE; int saved_ignore_embedded; TRACE("(%p,%p,%p,%d)\n", pStubMsg, ppMemory, pFormat, fMustAlloc); @@ -4204,7 +4204,7 @@ unsigned char * WINAPI NdrComplexArrayUnmarshall(PMIDL_STUB_MESSAGE pStubMsg, { /* save it for use by embedded pointer code later */ pStubMsg->PointerBufferMark = pStubMsg->Buffer; - pointer_buffer_mark_set = 1; + pointer_buffer_mark_set = TRUE; } /* restore the original buffer */ pStubMsg->Buffer = saved_buffer; @@ -5702,7 +5702,7 @@ static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned c if (m) { unsigned char *saved_buffer = NULL; - int pointer_buffer_mark_set = 0; + BOOL pointer_buffer_mark_set = FALSE; switch(*desc) { case RPC_FC_RP: @@ -5715,7 +5715,7 @@ static unsigned char *union_arm_marshall(PMIDL_STUB_MESSAGE pStubMsg, unsigned c { pStubMsg->Buffer = pStubMsg->PointerBufferMark; pStubMsg->PointerBufferMark = NULL; - pointer_buffer_mark_set = 1; + pointer_buffer_mark_set = TRUE; } else safe_buffer_increment(pStubMsg, 4); /* for pointer ID */ @@ -5770,7 +5770,7 @@ static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg, if (m) { unsigned char *saved_buffer = NULL; - int pointer_buffer_mark_set = 0; + BOOL pointer_buffer_mark_set = FALSE; switch(*desc) { case RPC_FC_RP: @@ -5783,7 +5783,7 @@ static unsigned char *union_arm_unmarshall(PMIDL_STUB_MESSAGE pStubMsg, { pStubMsg->Buffer = pStubMsg->PointerBufferMark; pStubMsg->PointerBufferMark = NULL; - pointer_buffer_mark_set = 1; + pointer_buffer_mark_set = TRUE; } else pStubMsg->Buffer += 4; /* for pointer ID */ diff --git a/dll/win32/rpcrt4/rpc_message.c b/dll/win32/rpcrt4/rpc_message.c index b3cfe5a4cdc..86ca467858f 100644 --- a/dll/win32/rpcrt4/rpc_message.c +++ b/dll/win32/rpcrt4/rpc_message.c @@ -60,20 +60,20 @@ DWORD RPCRT4_GetHeaderSize(const RpcPktHdr *Header) return ret; } -static int packet_has_body(const RpcPktHdr *Header) +static BOOL packet_has_body(const RpcPktHdr *Header) { return (Header->common.ptype == PKT_FAULT) || (Header->common.ptype == PKT_REQUEST) || (Header->common.ptype == PKT_RESPONSE); } -static int packet_has_auth_verifier(const RpcPktHdr *Header) +static BOOL packet_has_auth_verifier(const RpcPktHdr *Header) { return !(Header->common.ptype == PKT_BIND_NACK) && !(Header->common.ptype == PKT_SHUTDOWN); } -static int packet_does_auth_negotiation(const RpcPktHdr *Header) +static BOOL packet_does_auth_negotiation(const RpcPktHdr *Header) { switch (Header->common.ptype) { diff --git a/dll/win32/rpcrt4/rpc_transport.c b/dll/win32/rpcrt4/rpc_transport.c index e48b1cd168e..f60ea9f50d1 100644 --- a/dll/win32/rpcrt4/rpc_transport.c +++ b/dll/win32/rpcrt4/rpc_transport.c @@ -79,6 +79,8 @@ #define DEFAULT_NCACN_HTTP_TIMEOUT (60 * 1000) +#define ARRAYSIZE(a) (sizeof((a)) / sizeof((a)[0])) + WINE_DEFAULT_DEBUG_CHANNEL(rpc); static RPC_STATUS RPCRT4_SpawnConnection(RpcConnection** Connection, RpcConnection* OldConnection); @@ -136,6 +138,24 @@ static RPC_STATUS rpcrt4_conn_listen_pipe(RpcConnection_np *npc) } } +#ifndef __REACTOS__ +static RPC_STATUS rpcrt4_conn_listen_pipe(RpcConnection_np *npc) +{ + if (npc->listening) + return RPC_S_OK; + + npc->listening = TRUE; + npc->listen_thread = CreateThread(NULL, 0, listen_thread, npc, 0, NULL); + if (!npc->listen_thread) + { + npc->listening = FALSE; + ERR("Couldn't create listen thread (error was %d)\n", GetLastError()); + return RPC_S_OUT_OF_RESOURCES; + } + return RPC_S_OK; +} +#endif + static RPC_STATUS rpcrt4_conn_create_pipe(RpcConnection *Connection, LPCSTR pname) { RpcConnection_np *npc = (RpcConnection_np *) Connection; @@ -1909,6 +1929,19 @@ static RPC_STATUS wait_async_request(RpcHttpAsyncData *async_data, BOOL call_ret return RPC_S_OK; } +struct authinfo +{ + DWORD scheme; + CredHandle cred; + CtxtHandle ctx; + TimeStamp exp; + ULONG attr; + ULONG max_token; + char *data; + unsigned int data_len; + BOOL finished; /* finished authenticating */ +}; + typedef struct _RpcConnection_http { RpcConnection common; @@ -1916,6 +1949,7 @@ typedef struct _RpcConnection_http HINTERNET session; HINTERNET in_request; HINTERNET out_request; + WCHAR *servername; HANDLE timer_cancelled; HANDLE cancel_event; DWORD last_sent_time; @@ -2176,14 +2210,14 @@ static RPC_STATUS rpcrt4_http_internet_connect(RpcConnection_http *httpc) HeapFree(GetProcessHeap(), 0, password); HeapFree(GetProcessHeap(), 0, user); HeapFree(GetProcessHeap(), 0, proxy); - HeapFree(GetProcessHeap(), 0, servername); if (!httpc->session) { ERR("InternetConnectW failed with error %d\n", GetLastError()); + HeapFree(GetProcessHeap(), 0, servername); return RPC_S_SERVER_UNAVAILABLE; } - + httpc->servername = servername; return RPC_S_OK; } @@ -2194,6 +2228,8 @@ static RPC_STATUS send_echo_request(HINTERNET req, RpcHttpAsyncData *async_data, BOOL ret; RPC_STATUS status; + TRACE("sending echo request to server\n"); + prepare_async_request(async_data); ret = HttpSendRequestW(req, NULL, 0, NULL, 0); status = wait_async_request(async_data, ret, cancel_event); @@ -2210,9 +2246,8 @@ static RPC_STATUS send_echo_request(HINTERNET req, RpcHttpAsyncData *async_data, /* prepare the in pipe for use by RPC packets */ static RPC_STATUS rpcrt4_http_prepare_in_pipe(HINTERNET in_request, RpcHttpAsyncData *async_data, HANDLE cancel_event, - const UUID *connection_uuid, - const UUID *in_pipe_uuid, - const UUID *association_uuid) + const UUID *connection_uuid, const UUID *in_pipe_uuid, + const UUID *association_uuid, BOOL authorized) { BOOL ret; RPC_STATUS status; @@ -2220,10 +2255,12 @@ static RPC_STATUS rpcrt4_http_prepare_in_pipe(HINTERNET in_request, RpcHttpAsync INTERNET_BUFFERSW buffers_in; DWORD bytes_written; - /* prepare in pipe */ - status = send_echo_request(in_request, async_data, cancel_event); - if (status != RPC_S_OK) return status; - + if (!authorized) + { + /* ask wininet to authorize, if necessary */ + status = send_echo_request(in_request, async_data, cancel_event); + if (status != RPC_S_OK) return status; + } memset(&buffers_in, 0, sizeof(buffers_in)); buffers_in.dwStructSize = sizeof(buffers_in); /* FIXME: get this from the registry */ @@ -2293,12 +2330,10 @@ static RPC_STATUS rpcrt4_http_read_http_packet(HINTERNET request, RpcPktHdr *hdr } /* prepare the out pipe for use by RPC packets */ -static RPC_STATUS rpcrt4_http_prepare_out_pipe(HINTERNET out_request, - RpcHttpAsyncData *async_data, - HANDLE cancel_event, - const UUID *connection_uuid, - const UUID *out_pipe_uuid, - ULONG *flow_control_increment) +static RPC_STATUS rpcrt4_http_prepare_out_pipe(HINTERNET out_request, RpcHttpAsyncData *async_data, + HANDLE cancel_event, const UUID *connection_uuid, + const UUID *out_pipe_uuid, ULONG *flow_control_increment, + BOOL authorized) { BOOL ret; RPC_STATUS status; @@ -2306,13 +2341,22 @@ static RPC_STATUS rpcrt4_http_prepare_out_pipe(HINTERNET out_request, BYTE *data_from_server; RpcPktHdr pkt_from_server; ULONG field1, field3; + DWORD bytes_read; + BYTE buf[20]; - status = send_echo_request(out_request, async_data, cancel_event); - if (status != RPC_S_OK) return status; + if (!authorized) + { + /* ask wininet to authorize, if necessary */ + status = send_echo_request(out_request, async_data, cancel_event); + if (status != RPC_S_OK) return status; + } + else + InternetReadFile(out_request, buf, sizeof(buf), &bytes_read); hdr = RPCRT4_BuildHttpConnectHeader(TRUE, connection_uuid, out_pipe_uuid, NULL); if (!hdr) return RPC_S_OUT_OF_RESOURCES; + TRACE("sending HTTP connect header to server\n"); prepare_async_request(async_data); ret = HttpSendRequestW(out_request, NULL, 0, hdr, hdr->common.frag_len); status = wait_async_request(async_data, ret, cancel_event); @@ -2359,7 +2403,7 @@ static RPC_STATUS rpcrt4_http_prepare_out_pipe(HINTERNET out_request, static UINT encode_base64(const char *bin, unsigned int len, WCHAR *base64) { - static char enc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + static const char enc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; UINT i = 0, x; while (len > 0) @@ -2397,55 +2441,392 @@ static UINT encode_base64(const char *bin, unsigned int len, WCHAR *base64) return i; } -static RPC_STATUS insert_authorization_header(HINTERNET request, RpcQualityOfService *qos) +static inline char decode_char( WCHAR c ) { - static const WCHAR basicW[] = - {'A','u','t','h','o','r','i','z','a','t','i','o','n',':',' ','B','a','s','i','c',' '}; - RPC_HTTP_TRANSPORT_CREDENTIALS_W *creds; - SEC_WINNT_AUTH_IDENTITY_W *id; - int len, datalen, userlen, passlen; - WCHAR *header, *ptr; - char *data; + if (c >= 'A' && c <= 'Z') return c - 'A'; + if (c >= 'a' && c <= 'z') return c - 'a' + 26; + if (c >= '0' && c <= '9') return c - '0' + 52; + if (c == '+') return 62; + if (c == '/') return 63; + return 64; +} + +static unsigned int decode_base64( const WCHAR *base64, unsigned int len, char *buf ) +{ + unsigned int i = 0; + char c0, c1, c2, c3; + const WCHAR *p = base64; + + while (len > 4) + { + if ((c0 = decode_char( p[0] )) > 63) return 0; + if ((c1 = decode_char( p[1] )) > 63) return 0; + if ((c2 = decode_char( p[2] )) > 63) return 0; + if ((c3 = decode_char( p[3] )) > 63) return 0; + + if (buf) + { + buf[i + 0] = (c0 << 2) | (c1 >> 4); + buf[i + 1] = (c1 << 4) | (c2 >> 2); + buf[i + 2] = (c2 << 6) | c3; + } + len -= 4; + i += 3; + p += 4; + } + if (p[2] == '=') + { + if ((c0 = decode_char( p[0] )) > 63) return 0; + if ((c1 = decode_char( p[1] )) > 63) return 0; + + if (buf) buf[i] = (c0 << 2) | (c1 >> 4); + i++; + } + else if (p[3] == '=') + { + if ((c0 = decode_char( p[0] )) > 63) return 0; + if ((c1 = decode_char( p[1] )) > 63) return 0; + if ((c2 = decode_char( p[2] )) > 63) return 0; + + if (buf) + { + buf[i + 0] = (c0 << 2) | (c1 >> 4); + buf[i + 1] = (c1 << 4) | (c2 >> 2); + } + i += 2; + } + else + { + if ((c0 = decode_char( p[0] )) > 63) return 0; + if ((c1 = decode_char( p[1] )) > 63) return 0; + if ((c2 = decode_char( p[2] )) > 63) return 0; + if ((c3 = decode_char( p[3] )) > 63) return 0; + + if (buf) + { + buf[i + 0] = (c0 << 2) | (c1 >> 4); + buf[i + 1] = (c1 << 4) | (c2 >> 2); + buf[i + 2] = (c2 << 6) | c3; + } + i += 3; + } + return i; +} + +static struct authinfo *alloc_authinfo(void) +{ + struct authinfo *ret; + + if (!(ret = HeapAlloc(GetProcessHeap(), 0, sizeof(*ret) ))) return NULL; + + SecInvalidateHandle(&ret->cred); + SecInvalidateHandle(&ret->ctx); + memset(&ret->exp, 0, sizeof(ret->exp)); + ret->scheme = 0; + ret->attr = 0; + ret->max_token = 0; + ret->data = NULL; + ret->data_len = 0; + ret->finished = FALSE; + return ret; +} + +static void destroy_authinfo(struct authinfo *info) +{ + if (!info) return; + + if (SecIsValidHandle(&info->ctx)) + DeleteSecurityContext(&info->ctx); + if (SecIsValidHandle(&info->cred)) + FreeCredentialsHandle(&info->cred); + + HeapFree(GetProcessHeap(), 0, info->data); + HeapFree(GetProcessHeap(), 0, info); +} + +static const WCHAR basicW[] = {'B','a','s','i','c',0}; +static const WCHAR ntlmW[] = {'N','T','L','M',0}; +static const WCHAR passportW[] = {'P','a','s','s','p','o','r','t',0}; +static const WCHAR digestW[] = {'D','i','g','e','s','t',0}; +static const WCHAR negotiateW[] = {'N','e','g','o','t','i','a','t','e',0}; + +static const struct +{ + const WCHAR *str; + unsigned int len; + DWORD scheme; +} +auth_schemes[] = +{ + { basicW, ARRAYSIZE(basicW) - 1, RPC_C_HTTP_AUTHN_SCHEME_BASIC }, + { ntlmW, ARRAYSIZE(ntlmW) - 1, RPC_C_HTTP_AUTHN_SCHEME_NTLM }, + { passportW, ARRAYSIZE(passportW) - 1, RPC_C_HTTP_AUTHN_SCHEME_PASSPORT }, + { digestW, ARRAYSIZE(digestW) - 1, RPC_C_HTTP_AUTHN_SCHEME_DIGEST }, + { negotiateW, ARRAYSIZE(negotiateW) - 1, RPC_C_HTTP_AUTHN_SCHEME_NEGOTIATE } +}; +static const unsigned int num_auth_schemes = sizeof(auth_schemes)/sizeof(auth_schemes[0]); + +static DWORD auth_scheme_from_header( const WCHAR *header ) +{ + unsigned int i; + for (i = 0; i < num_auth_schemes; i++) + { + if (!strncmpiW( header, auth_schemes[i].str, auth_schemes[i].len ) && + (header[auth_schemes[i].len] == ' ' || !header[auth_schemes[i].len])) return auth_schemes[i].scheme; + } + return 0; +} + +static BOOL get_authvalue(HINTERNET request, DWORD scheme, WCHAR *buffer, DWORD buflen) +{ + DWORD len, index = 0; + for (;;) + { + len = buflen; + if (!HttpQueryInfoW(request, HTTP_QUERY_WWW_AUTHENTICATE, buffer, &len, &index)) return FALSE; + if (auth_scheme_from_header(buffer) == scheme) break; + } + return TRUE; +} + +static RPC_STATUS do_authorization(HINTERNET request, SEC_WCHAR *servername, + const RPC_HTTP_TRANSPORT_CREDENTIALS_W *creds, struct authinfo **auth_ptr) +{ + struct authinfo *info = *auth_ptr; + SEC_WINNT_AUTH_IDENTITY_W *id = creds->TransportCredentials; RPC_STATUS status = RPC_S_SERVER_UNAVAILABLE; - if (!qos || qos->qos->AdditionalSecurityInfoType != RPC_C_AUTHN_INFO_TYPE_HTTP) - return RPC_S_OK; + if ((!info && !(info = alloc_authinfo()))) return RPC_S_SERVER_UNAVAILABLE; - creds = qos->qos->u.HttpCredentials; - if (creds->AuthenticationTarget != RPC_C_HTTP_AUTHN_TARGET_SERVER || !creds->NumberOfAuthnSchemes) - return RPC_S_OK; - - if (creds->AuthnSchemes[0] != RPC_C_HTTP_AUTHN_SCHEME_BASIC) + switch (creds->AuthnSchemes[0]) { - FIXME("scheme %u not supported\n", creds->AuthnSchemes[0]); - return RPC_S_OK; + case RPC_C_HTTP_AUTHN_SCHEME_BASIC: + { + int userlen = WideCharToMultiByte(CP_UTF8, 0, id->User, id->UserLength, NULL, 0, NULL, NULL); + int passlen = WideCharToMultiByte(CP_UTF8, 0, id->Password, id->PasswordLength, NULL, 0, NULL, NULL); + + info->data_len = userlen + passlen + 1; + if (!(info->data = HeapAlloc(GetProcessHeap(), 0, info->data_len))) + { + status = RPC_S_OUT_OF_MEMORY; + break; + } + WideCharToMultiByte(CP_UTF8, 0, id->User, id->UserLength, info->data, userlen, NULL, NULL); + info->data[userlen] = ':'; + WideCharToMultiByte(CP_UTF8, 0, id->Password, id->PasswordLength, info->data + userlen + 1, passlen, NULL, NULL); + + info->scheme = RPC_C_HTTP_AUTHN_SCHEME_BASIC; + info->finished = TRUE; + status = RPC_S_OK; + break; } - id = creds->TransportCredentials; - if (!id->User || !id->Password) return RPC_S_OK; - - userlen = WideCharToMultiByte(CP_UTF8, 0, id->User, id->UserLength, NULL, 0, NULL, NULL); - passlen = WideCharToMultiByte(CP_UTF8, 0, id->Password, id->PasswordLength, NULL, 0, NULL, NULL); - - datalen = userlen + passlen + 1; - if (!(data = HeapAlloc(GetProcessHeap(), 0, datalen))) return RPC_S_OUT_OF_MEMORY; - - WideCharToMultiByte(CP_UTF8, 0, id->User, id->UserLength, data, userlen, NULL, NULL); - data[userlen] = ':'; - WideCharToMultiByte(CP_UTF8, 0, id->Password, id->PasswordLength, data + userlen + 1, passlen, NULL, NULL); - - len = ((datalen + 2) * 4) / 3; - if ((header = HeapAlloc(GetProcessHeap(), 0, sizeof(basicW) + (len + 2) * sizeof(WCHAR)))) + case RPC_C_HTTP_AUTHN_SCHEME_NTLM: + case RPC_C_HTTP_AUTHN_SCHEME_NEGOTIATE: { - memcpy(header, basicW, sizeof(basicW)); - ptr = header + sizeof(basicW) / sizeof(basicW[0]); - len = encode_base64(data, datalen, ptr); + + static SEC_WCHAR ntlmW[] = {'N','T','L','M',0}, negotiateW[] = {'N','e','g','o','t','i','a','t','e',0}; + SECURITY_STATUS ret; + SecBufferDesc out_desc, in_desc; + SecBuffer out, in; + ULONG flags = ISC_REQ_CONNECTION|ISC_REQ_USE_DCE_STYLE|ISC_REQ_MUTUAL_AUTH|ISC_REQ_DELEGATE; + SEC_WCHAR *scheme; + int scheme_len; + const WCHAR *p; + WCHAR auth_value[2048]; + DWORD size = sizeof(auth_value); + BOOL first = FALSE; + + if (creds->AuthnSchemes[0] == RPC_C_HTTP_AUTHN_SCHEME_NTLM) scheme = ntlmW; + else scheme = negotiateW; + scheme_len = strlenW( scheme ); + + if (!*auth_ptr) + { + TimeStamp exp; + SecPkgInfoW *pkg_info; + + ret = AcquireCredentialsHandleW(NULL, scheme, SECPKG_CRED_OUTBOUND, NULL, id, NULL, NULL, &info->cred, &exp); + if (ret != SEC_E_OK) break; + + ret = QuerySecurityPackageInfoW(scheme, &pkg_info); + if (ret != SEC_E_OK) break; + + info->max_token = pkg_info->cbMaxToken; + FreeContextBuffer(pkg_info); + first = TRUE; + } + else + { + if (info->finished || !get_authvalue(request, creds->AuthnSchemes[0], auth_value, size)) break; + if (auth_scheme_from_header(auth_value) != info->scheme) + { + ERR("authentication scheme changed\n"); + break; + } + } + in.BufferType = SECBUFFER_TOKEN; + in.cbBuffer = 0; + in.pvBuffer = NULL; + + in_desc.ulVersion = 0; + in_desc.cBuffers = 1; + in_desc.pBuffers = ∈ + + p = auth_value + scheme_len; + if (!first && *p == ' ') + { + int len = strlenW(++p); + in.cbBuffer = decode_base64(p, len, NULL); + if (!(in.pvBuffer = HeapAlloc(GetProcessHeap(), 0, in.cbBuffer))) break; + decode_base64(p, len, in.pvBuffer); + } + out.BufferType = SECBUFFER_TOKEN; + out.cbBuffer = info->max_token; + if (!(out.pvBuffer = HeapAlloc(GetProcessHeap(), 0, out.cbBuffer))) + { + HeapFree(GetProcessHeap(), 0, in.pvBuffer); + break; + } + out_desc.ulVersion = 0; + out_desc.cBuffers = 1; + out_desc.pBuffers = &out; + + ret = InitializeSecurityContextW(first ? &info->cred : NULL, first ? NULL : &info->ctx, + first ? servername : NULL, flags, 0, SECURITY_NETWORK_DREP, + in.pvBuffer ? &in_desc : NULL, 0, &info->ctx, &out_desc, + &info->attr, &info->exp); + HeapFree(GetProcessHeap(), 0, in.pvBuffer); + if (ret == SEC_E_OK) + { + HeapFree(GetProcessHeap(), 0, info->data); + info->data = out.pvBuffer; + info->data_len = out.cbBuffer; + info->finished = TRUE; + TRACE("sending last auth packet\n"); + status = RPC_S_OK; + } + else if (ret == SEC_I_CONTINUE_NEEDED) + { + HeapFree(GetProcessHeap(), 0, info->data); + info->data = out.pvBuffer; + info->data_len = out.cbBuffer; + TRACE("sending next auth packet\n"); + status = RPC_S_OK; + } + else + { + ERR("InitializeSecurityContextW failed with error 0x%08x\n", ret); + HeapFree(GetProcessHeap(), 0, out.pvBuffer); + break; + } + info->scheme = creds->AuthnSchemes[0]; + break; + } + default: + FIXME("scheme %u not supported\n", creds->AuthnSchemes[0]); + break; + } + + if (status != RPC_S_OK) + { + destroy_authinfo(info); + *auth_ptr = NULL; + return status; + } + *auth_ptr = info; + return RPC_S_OK; +} + +static RPC_STATUS insert_authorization_header(HINTERNET request, ULONG scheme, char *data, int data_len) +{ + static const WCHAR authW[] = {'A','u','t','h','o','r','i','z','a','t','i','o','n',':',' '}; + static const WCHAR basicW[] = {'B','a','s','i','c',' '}; + static const WCHAR negotiateW[] = {'N','e','g','o','t','i','a','t','e',' '}; + static const WCHAR ntlmW[] = {'N','T','L','M',' '}; + int scheme_len, auth_len = sizeof(authW) / sizeof(authW[0]), len = ((data_len + 2) * 4) / 3; + const WCHAR *scheme_str; + WCHAR *header, *ptr; + RPC_STATUS status = RPC_S_SERVER_UNAVAILABLE; + + switch (scheme) + { + case RPC_C_HTTP_AUTHN_SCHEME_BASIC: + scheme_str = basicW; + scheme_len = sizeof(basicW) / sizeof(basicW[0]); + break; + case RPC_C_HTTP_AUTHN_SCHEME_NEGOTIATE: + scheme_str = negotiateW; + scheme_len = sizeof(negotiateW) / sizeof(negotiateW[0]); + break; + case RPC_C_HTTP_AUTHN_SCHEME_NTLM: + scheme_str = ntlmW; + scheme_len = sizeof(ntlmW) / sizeof(ntlmW[0]); + break; + default: + ERR("unknown scheme %u\n", scheme); + return RPC_S_SERVER_UNAVAILABLE; + } + if ((header = HeapAlloc(GetProcessHeap(), 0, (auth_len + scheme_len + len + 2) * sizeof(WCHAR)))) + { + memcpy(header, authW, auth_len * sizeof(WCHAR)); + ptr = header + auth_len; + memcpy(ptr, scheme_str, scheme_len * sizeof(WCHAR)); + ptr += scheme_len; + len = encode_base64(data, data_len, ptr); ptr[len++] = '\r'; ptr[len++] = '\n'; ptr[len] = 0; - if ((HttpAddRequestHeadersW(request, header, -1, HTTP_ADDREQ_FLAG_ADD_IF_NEW))) status = RPC_S_OK; + if (HttpAddRequestHeadersW(request, header, -1, HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE)) + status = RPC_S_OK; HeapFree(GetProcessHeap(), 0, header); } - HeapFree(GetProcessHeap(), 0, data); + return status; +} + +static void drain_content(HINTERNET request) +{ + DWORD count, len = 0, size = sizeof(len); + char buf[2048]; + + HttpQueryInfoW(request, HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH, &len, &size, NULL); + if (!len) return; + for (;;) + { + count = min(sizeof(buf), len); + if (!InternetReadFile(request, buf, count, &count) || !count) return; + len -= count; + } +} + +static RPC_STATUS authorize_request(RpcConnection_http *httpc, HINTERNET request) +{ + static const WCHAR authW[] = {'A','u','t','h','o','r','i','z','a','t','i','o','n',':','\r','\n',0}; + struct authinfo *info = NULL; + RPC_STATUS status; + BOOL ret; + + for (;;) + { + status = do_authorization(request, httpc->servername, httpc->common.QOS->qos->u.HttpCredentials, &info); + if (status != RPC_S_OK) break; + + status = insert_authorization_header(request, info->scheme, info->data, info->data_len); + if (status != RPC_S_OK) break; + + prepare_async_request(httpc->async_data); + ret = HttpSendRequestW(request, NULL, 0, NULL, 0); + status = wait_async_request(httpc->async_data, ret, httpc->cancel_event); + if (status != RPC_S_OK || info->finished) break; + + status = rpcrt4_http_check_response(request); + if (status != RPC_S_OK && status != ERROR_ACCESS_DENIED) break; + drain_content(request); + } + + if (info->scheme != RPC_C_HTTP_AUTHN_SCHEME_BASIC) + HttpAddRequestHeadersW(request, authW, -1, HTTP_ADDREQ_FLAG_REPLACE); + + destroy_authinfo(info); return status; } @@ -2473,6 +2854,31 @@ static RPC_STATUS insert_cookie_header(HINTERNET request, const WCHAR *value) return status; } +static BOOL has_credentials(RpcConnection_http *httpc) +{ + RPC_HTTP_TRANSPORT_CREDENTIALS_W *creds; + SEC_WINNT_AUTH_IDENTITY_W *id; + + if (!httpc->common.QOS || httpc->common.QOS->qos->AdditionalSecurityInfoType != RPC_C_AUTHN_INFO_TYPE_HTTP) + return FALSE; + + creds = httpc->common.QOS->qos->u.HttpCredentials; + if (creds->AuthenticationTarget != RPC_C_HTTP_AUTHN_TARGET_SERVER || !creds->NumberOfAuthnSchemes) + return FALSE; + + id = creds->TransportCredentials; + if (!id || !id->User || !id->Password) return FALSE; + + return TRUE; +} + +static BOOL is_secure(RpcConnection_http *httpc) +{ + return httpc->common.QOS && + (httpc->common.QOS->qos->AdditionalSecurityInfoType == RPC_C_AUTHN_INFO_TYPE_HTTP) && + (httpc->common.QOS->qos->u.HttpCredentials->Flags & RPC_C_HTTP_FLAG_USE_SSL); +} + static RPC_STATUS rpcrt4_ncacn_http_open(RpcConnection* Connection) { RpcConnection_http *httpc = (RpcConnection_http *)Connection; @@ -2485,7 +2891,7 @@ static RPC_STATUS rpcrt4_ncacn_http_open(RpcConnection* Connection) DWORD flags; WCHAR *url; RPC_STATUS status; - BOOL secure; + BOOL secure, credentials; HttpTimerThreadData *timer_data; HANDLE thread; @@ -2518,13 +2924,13 @@ static RPC_STATUS rpcrt4_ncacn_http_open(RpcConnection* Connection) strcatW(url, wszColon); MultiByteToWideChar(CP_ACP, 0, Connection->Endpoint, -1, url+strlenW(url), strlen(Connection->Endpoint)+1); - secure = httpc->common.QOS && - (httpc->common.QOS->qos->AdditionalSecurityInfoType == RPC_C_AUTHN_INFO_TYPE_HTTP) && - (httpc->common.QOS->qos->u.HttpCredentials->Flags & RPC_C_HTTP_FLAG_USE_SSL); + secure = is_secure(httpc); + credentials = has_credentials(httpc); flags = INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_AUTO_REDIRECT; if (secure) flags |= INTERNET_FLAG_SECURE; + if (credentials) flags |= INTERNET_FLAG_NO_AUTH; httpc->in_request = HttpOpenRequestW(httpc->session, wszVerbIn, url, NULL, NULL, wszAcceptTypes, flags, (DWORD_PTR)httpc->async_data); @@ -2534,13 +2940,28 @@ static RPC_STATUS rpcrt4_ncacn_http_open(RpcConnection* Connection) HeapFree(GetProcessHeap(), 0, url); return RPC_S_SERVER_UNAVAILABLE; } - status = insert_authorization_header(httpc->in_request, httpc->common.QOS); - if (status != RPC_S_OK) - return status; - status = insert_cookie_header(httpc->in_request, Connection->CookieAuth); if (status != RPC_S_OK) + { + HeapFree(GetProcessHeap(), 0, url); return status; + } + if (credentials) + { + status = authorize_request(httpc, httpc->in_request); + if (status != RPC_S_OK) + { + HeapFree(GetProcessHeap(), 0, url); + return status; + } + status = rpcrt4_http_check_response(httpc->in_request); + if (status != RPC_S_OK) + { + HeapFree(GetProcessHeap(), 0, url); + return status; + } + drain_content(httpc->in_request); + } httpc->out_request = HttpOpenRequestW(httpc->session, wszVerbOut, url, NULL, NULL, wszAcceptTypes, flags, (DWORD_PTR)httpc->async_data); @@ -2550,29 +2971,26 @@ static RPC_STATUS rpcrt4_ncacn_http_open(RpcConnection* Connection) ERR("HttpOpenRequestW failed with error %d\n", GetLastError()); return RPC_S_SERVER_UNAVAILABLE; } - status = insert_authorization_header(httpc->out_request, httpc->common.QOS); - if (status != RPC_S_OK) - return status; - status = insert_cookie_header(httpc->out_request, Connection->CookieAuth); if (status != RPC_S_OK) return status; - status = rpcrt4_http_prepare_in_pipe(httpc->in_request, - httpc->async_data, - httpc->cancel_event, - &httpc->connection_uuid, - &httpc->in_pipe_uuid, - &Connection->assoc->http_uuid); + if (credentials) + { + status = authorize_request(httpc, httpc->out_request); + if (status != RPC_S_OK) + return status; + } + + status = rpcrt4_http_prepare_in_pipe(httpc->in_request, httpc->async_data, httpc->cancel_event, + &httpc->connection_uuid, &httpc->in_pipe_uuid, + &Connection->assoc->http_uuid, credentials); if (status != RPC_S_OK) return status; - status = rpcrt4_http_prepare_out_pipe(httpc->out_request, - httpc->async_data, - httpc->cancel_event, - &httpc->connection_uuid, - &httpc->out_pipe_uuid, - &httpc->flow_control_increment); + status = rpcrt4_http_prepare_out_pipe(httpc->out_request, httpc->async_data, httpc->cancel_event, + &httpc->connection_uuid, &httpc->out_pipe_uuid, + &httpc->flow_control_increment, credentials); if (status != RPC_S_OK) return status; @@ -2835,6 +3253,8 @@ static int rpcrt4_ncacn_http_close(RpcConnection *Connection) RpcHttpAsyncData_Release(httpc->async_data); if (httpc->cancel_event) CloseHandle(httpc->cancel_event); + HeapFree(GetProcessHeap(), 0, httpc->servername); + httpc->servername = NULL; return 0; } @@ -2992,8 +3412,6 @@ static const struct protseq_ops protseq_list[] = }, }; -#define ARRAYSIZE(a) (sizeof((a)) / sizeof((a)[0])) - const struct protseq_ops *rpcrt4_get_protseq_ops(const char *protseq) { unsigned int i; diff --git a/dll/win32/rpcrt4/rpcrt4_main.c b/dll/win32/rpcrt4/rpcrt4_main.c index 1b0d79f3622..060297483b4 100644 --- a/dll/win32/rpcrt4/rpcrt4_main.c +++ b/dll/win32/rpcrt4/rpcrt4_main.c @@ -365,7 +365,8 @@ static RPC_STATUS RPC_UuidGetNodeAddress(BYTE *address) */ RPC_STATUS WINAPI UuidCreateSequential(UUID *Uuid) { - static int initialised, count; + static BOOL initialised; + static int count; ULONGLONG time; static ULONGLONG timelast; @@ -384,7 +385,7 @@ RPC_STATUS WINAPI UuidCreateSequential(UUID *Uuid) sequence &= 0x1fff; status = RPC_UuidGetNodeAddress(address); - initialised = 1; + initialised = TRUE; } /* Generate time element of the UUID. Account for going faster diff --git a/dll/win32/shdocvw/shdocvw_v1.idl b/dll/win32/shdocvw/shdocvw_v1.idl index 45b91115497..8418be66f84 100644 --- a/dll/win32/shdocvw/shdocvw_v1.idl +++ b/dll/win32/shdocvw/shdocvw_v1.idl @@ -16,4 +16,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma makedep regtypelib + #include "exdisp.idl" diff --git a/dll/win32/shell32/bitmap_res.rc b/dll/win32/shell32/bitmap_res.rc index 653c74ce963..02b98960545 100644 --- a/dll/win32/shell32/bitmap_res.rc +++ b/dll/win32/shell32/bitmap_res.rc @@ -1,4 +1,4 @@ -IDB_SHELL_ABOUT_LOGO_24BPP BITMAP "res/bitmaps/shell_about_logo_24bpp.bmp" +IDB_REACTOS BITMAP "res/bitmaps/reactos.bmp" /* IDB_SHELL_IEXPLORE_LG BITMAP "res/bitmaps/204+205.bmp" diff --git a/dll/win32/shell32/res/bitmaps/reactos.bmp b/dll/win32/shell32/res/bitmaps/reactos.bmp new file mode 100644 index 00000000000..41986988417 Binary files /dev/null and b/dll/win32/shell32/res/bitmaps/reactos.bmp differ diff --git a/dll/win32/shell32/res/bitmaps/shell_about_logo_24bpp.bmp b/dll/win32/shell32/res/bitmaps/shell_about_logo_24bpp.bmp deleted file mode 100644 index 335383f3f1d..00000000000 Binary files a/dll/win32/shell32/res/bitmaps/shell_about_logo_24bpp.bmp and /dev/null differ diff --git a/dll/win32/shell32/shell32_main.cpp b/dll/win32/shell32/shell32_main.cpp index 047f9185adb..bcdd151dd86 100644 --- a/dll/win32/shell32/shell32_main.cpp +++ b/dll/win32/shell32/shell32_main.cpp @@ -1097,7 +1097,7 @@ INT_PTR CALLBACK AboutDlgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam WCHAR szAuthorsText[20]; // Preload the ROS bitmap - hLogoBmp = (HBITMAP)LoadImage(shell32_hInstance, MAKEINTRESOURCE(IDB_SHELL_ABOUT_LOGO_24BPP), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); + hLogoBmp = (HBITMAP)LoadImage(shell32_hInstance, MAKEINTRESOURCE(IDB_REACTOS), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR); if(hLogoBmp) { diff --git a/dll/win32/shell32/shresdef.h b/dll/win32/shell32/shresdef.h index 607a42f01fe..94459f50dea 100644 --- a/dll/win32/shell32/shresdef.h +++ b/dll/win32/shell32/shresdef.h @@ -24,7 +24,7 @@ #define IDA_SHELLVIEW 1 /* Bitmaps */ -#define IDB_SHELL_ABOUT_LOGO_24BPP 131 +#define IDB_REACTOS 131 /* Strings */ diff --git a/dll/win32/stdole2.tlb/std_ole_v2.idl b/dll/win32/stdole2.tlb/std_ole_v2.idl index e2700a62aec..649d1822889 100644 --- a/dll/win32/stdole2.tlb/std_ole_v2.idl +++ b/dll/win32/stdole2.tlb/std_ole_v2.idl @@ -18,4 +18,6 @@ * */ +#pragma makedep regtypelib + #include "stdole2.idl" diff --git a/dll/win32/stdole32.tlb/std_ole_v1.idl b/dll/win32/stdole32.tlb/std_ole_v1.idl index 45fb3d50aed..359a81062ae 100644 --- a/dll/win32/stdole32.tlb/std_ole_v1.idl +++ b/dll/win32/stdole32.tlb/std_ole_v1.idl @@ -18,6 +18,8 @@ * */ +#pragma makedep regtypelib + [ uuid(00020430-0000-0000-C000-000000000046), restricted, diff --git a/dll/win32/sti/sti.rc b/dll/win32/sti/sti.rc index 2fef1279b44..8efbfdeba7f 100644 --- a/dll/win32/sti/sti.rc +++ b/dll/win32/sti/sti.rc @@ -1 +1 @@ -1 WINE_REGISTRY "sti.rgs" +1 WINE_REGISTRY sti_wia.rgs diff --git a/dll/win32/sti/sti_wia.idl b/dll/win32/sti/sti_wia.idl index f7744a17e1b..1aef5443db9 100644 --- a/dll/win32/sti/sti_wia.idl +++ b/dll/win32/sti/sti_wia.idl @@ -16,6 +16,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma makedep proxy +#pragma makedep register + #include "wia_lh.idl" [ diff --git a/dll/win32/sti/sti.rgs b/dll/win32/sti/sti_wia.rgs similarity index 100% rename from dll/win32/sti/sti.rgs rename to dll/win32/sti/sti_wia.rgs diff --git a/dll/win32/usp10/opentype.c b/dll/win32/usp10/opentype.c index a46daf2f619..2881f5d1806 100644 --- a/dll/win32/usp10/opentype.c +++ b/dll/win32/usp10/opentype.c @@ -933,7 +933,9 @@ static INT GSUB_apply_ChainContextSubst(const OT_LookupList* lookup, const OT_Lo } else if (GET_BE_WORD(ccsf1->SubstFormat) == 2) { +#ifndef __REACTOS__ FIXME(" TODO: subtype 2 (Class-based Chaining Context Glyph Substitution)\n"); +#endif continue; } else if (GET_BE_WORD(ccsf1->SubstFormat) == 3) diff --git a/dll/win32/usp10/usp10.c b/dll/win32/usp10/usp10.c index 406ad1c0ee5..4a574809edf 100644 --- a/dll/win32/usp10/usp10.c +++ b/dll/win32/usp10/usp10.c @@ -1605,12 +1605,12 @@ static HRESULT _ItemizeInternal(const WCHAR *pwcInChars, int cInChars, * item is set up to prevent random behaviour if the caller erroneously * checks the n+1 structure */ index++; + if (index + 1 > cMaxItems) return E_OUTOFMEMORY; memset(&pItems[index].a, 0, sizeof(SCRIPT_ANALYSIS)); TRACE("index=%d cnt=%d iCharPos=%d\n", index, cnt, pItems[index].iCharPos); /* Set one SCRIPT_STATE item being returned */ - if (index + 1 > cMaxItems) return E_OUTOFMEMORY; if (pcItems) *pcItems = index; /* Set SCRIPT_ITEM */ diff --git a/dll/win32/uxtheme/ncscrollbar.c b/dll/win32/uxtheme/ncscrollbar.c index 92431360d86..67745802592 100644 --- a/dll/win32/uxtheme/ncscrollbar.c +++ b/dll/win32/uxtheme/ncscrollbar.c @@ -22,7 +22,7 @@ static INT SCROLL_TrackingBar = 0; static INT SCROLL_TrackingPos = 0; static INT SCROLL_TrackingVal = 0; -void static ScreenToWindow( HWND hWnd, POINT* pt) +static void ScreenToWindow( HWND hWnd, POINT* pt) { RECT rcWnd; GetWindowRect(hWnd, &rcWnd); diff --git a/dll/win32/version/version.c b/dll/win32/version/version.c index ffb8ba6f1be..9bc6ad133af 100644 --- a/dll/win32/version/version.c +++ b/dll/win32/version/version.c @@ -84,9 +84,9 @@ static const IMAGE_RESOURCE_DIRECTORY *find_entry_by_id( const IMAGE_RESOURCE_DI while (min <= max) { pos = (min + max) / 2; - if (entry[pos].u1.Id == id) + if (entry[pos].u.Id == id) return (const IMAGE_RESOURCE_DIRECTORY *)((const char *)root + entry[pos].u2.s2.OffsetToDirectory); - if (entry[pos].u1.Id > id) max = pos - 1; + if (entry[pos].u.Id > id) max = pos - 1; else min = pos + 1; } return NULL; @@ -109,6 +109,46 @@ static const IMAGE_RESOURCE_DIRECTORY *find_entry_default( const IMAGE_RESOURCE_ } +/********************************************************************** + * push_language + * + * push a language onto the list of languages to try + */ +static inline int push_language( WORD *list, int pos, WORD lang ) +{ + int i; + for (i = 0; i < pos; i++) if (list[i] == lang) return pos; + list[pos++] = lang; + return pos; +} + + +/********************************************************************** + * find_entry_language + */ +static const IMAGE_RESOURCE_DIRECTORY *find_entry_language( const IMAGE_RESOURCE_DIRECTORY *dir, + const void *root ) +{ + const IMAGE_RESOURCE_DIRECTORY *ret; + WORD list[9]; + int i, pos = 0; + + /* cf. LdrFindResource_U */ + pos = push_language( list, pos, MAKELANGID( LANG_NEUTRAL, SUBLANG_NEUTRAL ) ); + pos = push_language( list, pos, LANGIDFROMLCID( NtCurrentTeb()->CurrentLocale ) ); + pos = push_language( list, pos, GetUserDefaultLangID() ); + pos = push_language( list, pos, MAKELANGID( PRIMARYLANGID(GetUserDefaultLangID()), SUBLANG_NEUTRAL )); + pos = push_language( list, pos, MAKELANGID( PRIMARYLANGID(GetUserDefaultLangID()), SUBLANG_DEFAULT )); + pos = push_language( list, pos, GetSystemDefaultLangID() ); + pos = push_language( list, pos, MAKELANGID( PRIMARYLANGID(GetSystemDefaultLangID()), SUBLANG_NEUTRAL )); + pos = push_language( list, pos, MAKELANGID( PRIMARYLANGID(GetSystemDefaultLangID()), SUBLANG_DEFAULT )); + pos = push_language( list, pos, MAKELANGID( LANG_ENGLISH, SUBLANG_DEFAULT ) ); + + for (i = 0; i < pos; i++) if ((ret = find_entry_by_id( dir, list[i], root ))) return ret; + return find_entry_default( dir, root ); +} + + /*********************************************************************** * read_xx_header [internal] */ @@ -160,7 +200,7 @@ static BOOL find_ne_resource( HFILE lzfd, DWORD *resLen, DWORD *resOff ) /* Read in NE header */ nehdoffset = LZSeek( lzfd, 0, SEEK_CUR ); - if ( sizeof(nehd) != LZRead( lzfd, (LPSTR)&nehd, sizeof(nehd) ) ) return 0; + if ( sizeof(nehd) != LZRead( lzfd, (LPSTR)&nehd, sizeof(nehd) ) ) return FALSE; resTabSize = nehd.ne_restab - nehd.ne_rsrctab; if ( !resTabSize ) @@ -235,7 +275,7 @@ static BOOL find_pe_resource( HFILE lzfd, DWORD *resLen, DWORD *resOff ) /* Read in PE header */ pehdoffset = LZSeek( lzfd, 0, SEEK_CUR ); len = LZRead( lzfd, (LPSTR)&pehd, sizeof(pehd) ); - if (len < sizeof(pehd.nt32.FileHeader)) return 0; + if (len < sizeof(pehd.nt32.FileHeader)) return FALSE; if (len < sizeof(pehd)) memset( (char *)&pehd + len, 0, sizeof(pehd) - len ); switch (pehd.nt32.OptionalHeader.Magic) @@ -247,7 +287,7 @@ static BOOL find_pe_resource( HFILE lzfd, DWORD *resLen, DWORD *resOff ) resDataDir = pehd.nt64.OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_RESOURCE; break; default: - return 0; + return FALSE; } if ( !resDataDir->Size ) @@ -316,7 +356,7 @@ static BOOL find_pe_resource( HFILE lzfd, DWORD *resLen, DWORD *resOff ) TRACE("No resid entry found\n" ); goto done; } - resPtr = find_entry_default( resPtr, resDir ); + resPtr = find_entry_language( resPtr, resDir ); if ( !resPtr ) { TRACE("No default language entry found\n" ); @@ -527,7 +567,7 @@ typedef struct { WORD wLength; WORD wValueLength; - WORD wType; + WORD wType; /* 1:Text, 0:Binary */ WCHAR szKey[1]; #if 0 /* variable length structure */ /* DWORD aligned */ @@ -847,7 +887,7 @@ static BOOL VersionInfo16_QueryValue( const VS_VERSION_INFO_STRUCT16 *info, LPCS * Gets a value from a 32-bit PE resource */ static BOOL VersionInfo32_QueryValue( const VS_VERSION_INFO_STRUCT32 *info, LPCWSTR lpSubBlock, - LPVOID *lplpBuffer, UINT *puLen ) + LPVOID *lplpBuffer, UINT *puLen, BOOL *pbText ) { TRACE("lpSubBlock : (%s)\n", debugstr_w(lpSubBlock)); @@ -883,6 +923,8 @@ static BOOL VersionInfo32_QueryValue( const VS_VERSION_INFO_STRUCT32 *info, LPCW *lplpBuffer = VersionInfo32_Value( info ); if (puLen) *puLen = info->wValueLength; + if (pbText) + *pbText = info->wType; return TRUE; } @@ -894,7 +936,6 @@ BOOL WINAPI VerQueryValueA( LPCVOID pBlock, LPCSTR lpSubBlock, LPVOID *lplpBuffer, PUINT puLen ) { static const char rootA[] = "\\"; - static const char varfileinfoA[] = "\\VarFileInfo\\Translation"; const VS_VERSION_INFO_STRUCT16 *info = pBlock; TRACE("(%p,%s,%p,%p)\n", @@ -908,7 +949,7 @@ BOOL WINAPI VerQueryValueA( LPCVOID pBlock, LPCSTR lpSubBlock, if ( !VersionInfoIs16( info ) ) { - BOOL ret; + BOOL ret, isText; INT len; LPWSTR lpSubBlockW; @@ -920,11 +961,11 @@ BOOL WINAPI VerQueryValueA( LPCVOID pBlock, LPCSTR lpSubBlock, MultiByteToWideChar(CP_ACP, 0, lpSubBlock, -1, lpSubBlockW, len); - ret = VersionInfo32_QueryValue(pBlock, lpSubBlockW, lplpBuffer, puLen); + ret = VersionInfo32_QueryValue(pBlock, lpSubBlockW, lplpBuffer, puLen, &isText); HeapFree(GetProcessHeap(), 0, lpSubBlockW); - if (ret && strcasecmp( lpSubBlock, rootA ) && strcasecmp( lpSubBlock, varfileinfoA )) + if (ret && isText) { /* Set lpBuffer so it points to the 'empty' area where we store * the converted strings @@ -1000,7 +1041,7 @@ BOOL WINAPI VerQueryValueW( LPCVOID pBlock, LPCWSTR lpSubBlock, return ret; } - return VersionInfo32_QueryValue(info, lpSubBlock, lplpBuffer, puLen); + return VersionInfo32_QueryValue(info, lpSubBlock, lplpBuffer, puLen, NULL); } diff --git a/dll/win32/wbemprox/builtin.c b/dll/win32/wbemprox/builtin.c index 628b0c2cb00..c053be79646 100644 --- a/dll/win32/wbemprox/builtin.c +++ b/dll/win32/wbemprox/builtin.c @@ -51,10 +51,17 @@ static const WCHAR class_logicaldisk2W[] = {'C','I','M','_','L','o','g','i','c','a','l','D','i','s','k',0}; static const WCHAR class_networkadapterW[] = {'W','i','n','3','2','_','N','e','t','w','o','r','k','A','d','a','p','t','e','r',0}; +static const WCHAR class_networkadapterconfigW[] = + {'W','i','n','3','2','_','N','e','t','w','o','r','k','A','d','a','p','t','e','r', + 'C','o','n','f','i','g','u','r','a','t','i','o','n',0}; static const WCHAR class_osW[] = {'W','i','n','3','2','_','O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0}; static const WCHAR class_paramsW[] = {'_','_','P','A','R','A','M','E','T','E','R','S',0}; +static const WCHAR class_physicalmediaW[] = + {'W','i','n','3','2','_','P','h','y','s','i','c','a','l','M','e','d','i','a',0}; +static const WCHAR class_physicalmemoryW[] = + {'W','i','n','3','2','_','P','h','y','s','i','c','a','l','M','e','m','o','r','y',0}; static const WCHAR class_qualifiersW[] = {'_','_','Q','U','A','L','I','F','I','E','R','S',0}; static const WCHAR class_process_getowner_outW[] = @@ -81,10 +88,16 @@ static const WCHAR prop_adaptertypeW[] = {'A','d','a','p','t','e','r','T','y','p','e',0}; static const WCHAR prop_addresswidthW[] = {'A','d','d','r','e','s','s','W','i','d','t','h',0}; +static const WCHAR prop_availabilityW[] = + {'A','v','a','i','l','a','b','i','l','i','t','y',0}; static const WCHAR prop_bootableW[] = {'B','o','o','t','a','b','l','e',0}; static const WCHAR prop_bootpartitionW[] = {'B','o','o','t','P','a','r','t','i','t','i','o','n',0}; +static const WCHAR prop_buildnumberW[] = + {'B','u','i','l','d','N','u','m','b','e','r',0}; +static const WCHAR prop_capacityW[] = + {'C','a','p','a','c','i','t','y',0}; static const WCHAR prop_captionW[] = {'C','a','p','t','i','o','n',0}; static const WCHAR prop_classW[] = @@ -137,12 +150,22 @@ static const WCHAR prop_handleW[] = {'H','a','n','d','l','e',0}; static const WCHAR prop_idW[] = {'I','D',0}; +static const WCHAR prop_identificationcodeW[] = + {'I','d','e','n','t','i','f','i','c','a','t','i','o','n','C','o','d','e',0}; static const WCHAR prop_indexW[] = {'I','n','d','e','x',0}; +static const WCHAR prop_installdateW[] = + {'I','n','s','t','a','l','l','D','a','t','e',0}; static const WCHAR prop_interfaceindexW[] = {'I','n','t','e','r','f','a','c','e','I','n','d','e','x',0}; +static const WCHAR prop_interfacetypeW[] = + {'I','n','t','e','r','f','a','c','e','T','y','p','e',0}; static const WCHAR prop_intvalueW[] = {'I','n','t','e','g','e','r','V','a','l','u','e',0}; +static const WCHAR prop_ipconnectionmetricW[] = + {'I','P','C','o','n','n','e','c','t','i','o','n','M','e','t','r','i','c',0}; +static const WCHAR prop_ipenabledW[] = + {'I','P','E','n','a','b','l','e','d',0}; static const WCHAR prop_lastbootuptimeW[] = {'L','a','s','t','B','o','o','t','U','p','T','i','m','e',0}; static const WCHAR prop_localdatetimeW[] = @@ -155,6 +178,8 @@ static const WCHAR prop_manufacturerW[] = {'M','a','n','u','f','a','c','t','u','r','e','r',0}; static const WCHAR prop_maxclockspeedW[] = {'M','a','x','C','l','o','c','k','S','p','e','e','d',0}; +static const WCHAR prop_mediatypeW[] = + {'M','e','d','i','a','T','y','p','e',0}; static const WCHAR prop_memberW[] = {'M','e','m','b','e','r',0}; static const WCHAR prop_methodW[] = @@ -201,6 +226,8 @@ static const WCHAR prop_servicepackminorW[] = {'S','e','r','v','i','c','e','P','a','c','k','M','i','n','o','r','V','e','r','s','i','o','n',0}; static const WCHAR prop_servicetypeW[] = {'S','e','r','v','i','c','e','T','y','p','e',0}; +static const WCHAR prop_smbiosbiosversionW[] = + {'S','M','B','I','O','S','B','I','O','S','V','e','r','s','i','o','n',0}; static const WCHAR prop_startmodeW[] = {'S','t','a','r','t','M','o','d','e',0}; static const WCHAR prop_sizeW[] = @@ -233,26 +260,33 @@ static const WCHAR prop_varianttypeW[] = {'V','a','r','i','a','n','t','T','y','p','e',0}; static const WCHAR prop_versionW[] = {'V','e','r','s','i','o','n',0}; +static const WCHAR prop_volumeserialnumberW[] = + {'V','o','l','u','m','e','S','e','r','i','a','l','N','u','m','b','e','r',0}; /* column definitions must be kept in sync with record structures below */ static const struct column col_baseboard[] = { { prop_manufacturerW, CIM_STRING }, + { prop_modelW, CIM_STRING }, + { prop_nameW, CIM_STRING }, { prop_serialnumberW, CIM_STRING }, { prop_tagW, CIM_STRING|COL_FLAG_KEY } }; static const struct column col_bios[] = { - { prop_descriptionW, CIM_STRING }, - { prop_manufacturerW, CIM_STRING }, - { prop_releasedateW, CIM_DATETIME }, - { prop_serialnumberW, CIM_STRING }, - { prop_versionW, CIM_STRING|COL_FLAG_KEY } + { prop_descriptionW, CIM_STRING }, + { prop_identificationcodeW, CIM_STRING }, + { prop_manufacturerW, CIM_STRING }, + { prop_releasedateW, CIM_DATETIME }, + { prop_serialnumberW, CIM_STRING }, + { prop_smbiosbiosversionW, CIM_STRING }, + { prop_versionW, CIM_STRING|COL_FLAG_KEY } }; static const struct column col_cdromdrive[] = { { prop_deviceidW, CIM_STRING|COL_FLAG_KEY }, { prop_driveW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_mediatypeW, CIM_STRING }, { prop_nameW, CIM_STRING }, { prop_pnpdeviceidW, CIM_STRING } }; @@ -280,11 +314,14 @@ static const struct column col_directory[] = }; static const struct column col_diskdrive[] = { - { prop_deviceidW, CIM_STRING|COL_FLAG_KEY }, - { prop_indexW, CIM_UINT32, VT_I4 }, - { prop_manufacturerW, CIM_STRING }, - { prop_modelW, CIM_STRING }, - { prop_serialnumberW, CIM_STRING } + { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, + { prop_indexW, CIM_UINT32, VT_I4 }, + { prop_interfacetypeW, CIM_STRING }, + { prop_manufacturerW, CIM_STRING }, + { prop_mediatypeW, CIM_STRING }, + { prop_modelW, CIM_STRING }, + { prop_serialnumberW, CIM_STRING }, + { prop_sizeW, CIM_UINT64 } }; static const struct column col_diskpartition[] = { @@ -300,38 +337,52 @@ static const struct column col_diskpartition[] = }; static const struct column col_logicaldisk[] = { - { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, - { prop_drivetypeW, CIM_UINT32, VT_I4 }, - { prop_filesystemW, CIM_STRING|COL_FLAG_DYNAMIC }, - { prop_freespaceW, CIM_UINT64 }, - { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC }, - { prop_sizeW, CIM_UINT64 } + { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, + { prop_drivetypeW, CIM_UINT32, VT_I4 }, + { prop_filesystemW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_freespaceW, CIM_UINT64 }, + { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_sizeW, CIM_UINT64 }, + { prop_volumeserialnumberW, CIM_STRING|COL_FLAG_DYNAMIC } }; static const struct column col_networkadapter[] = { { prop_adaptertypeW, CIM_STRING }, { prop_deviceidW, CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY }, + { prop_indexW, CIM_UINT32, VT_I4 }, { prop_interfaceindexW, CIM_UINT32, VT_I4 }, { prop_macaddressW, CIM_STRING|COL_FLAG_DYNAMIC }, { prop_manufacturerW, CIM_STRING }, + { prop_nameW, CIM_STRING|COL_FLAG_DYNAMIC }, { prop_netconnectionstatusW, CIM_UINT16, VT_I4 }, { prop_physicaladapterW, CIM_BOOLEAN }, { prop_pnpdeviceidW, CIM_STRING }, { prop_speedW, CIM_UINT64 } }; +static const struct column col_networkadapterconfig[] = +{ + { prop_indexW, CIM_UINT32|COL_FLAG_KEY }, + { prop_ipconnectionmetricW, CIM_UINT32 }, + { prop_ipenabledW, CIM_BOOLEAN }, + { prop_macaddressW, CIM_STRING|COL_FLAG_DYNAMIC } +}; static const struct column col_os[] = { + { prop_buildnumberW, CIM_STRING }, { prop_captionW, CIM_STRING }, { prop_codesetW, CIM_STRING|COL_FLAG_DYNAMIC }, { prop_countrycodeW, CIM_STRING|COL_FLAG_DYNAMIC }, { prop_csdversionW, CIM_STRING }, + { prop_installdateW, CIM_DATETIME }, { prop_lastbootuptimeW, CIM_DATETIME|COL_FLAG_DYNAMIC }, { prop_localdatetimeW, CIM_DATETIME|COL_FLAG_DYNAMIC }, { prop_localeW, CIM_STRING|COL_FLAG_DYNAMIC }, + { prop_nameW, CIM_STRING }, { prop_osarchitectureW, CIM_STRING }, { prop_oslanguageW, CIM_UINT32, VT_I4 }, { prop_osproductsuiteW, CIM_UINT32, VT_I4 }, { prop_ostypeW, CIM_UINT16, VT_I4 }, + { prop_serialnumberW, CIM_STRING }, { prop_servicepackmajorW, CIM_UINT16, VT_I4 }, { prop_servicepackminorW, CIM_UINT16, VT_I4 }, { prop_suitemaskW, CIM_UINT32, VT_I4 }, @@ -348,6 +399,15 @@ static const struct column col_param[] = { prop_varianttypeW, CIM_UINT32 }, { prop_defaultvalueW, CIM_UINT32 } }; +static const struct column col_physicalmedia[] = +{ + { prop_serialnumberW, CIM_STRING }, + { prop_tagW, CIM_STRING } +}; +static const struct column col_physicalmemory[] = +{ + { prop_capacityW, CIM_UINT64 } +}; static const struct column col_process[] = { { prop_captionW, CIM_STRING|COL_FLAG_DYNAMIC }, @@ -417,6 +477,7 @@ static const struct column col_videocontroller[] = { { prop_adapterdactypeW, CIM_STRING }, { prop_adapterramW, CIM_UINT32, VT_I4 }, + { prop_availabilityW, CIM_UINT16 }, { prop_currentbitsperpixelW, CIM_UINT32 }, { prop_currenthorizontalresW, CIM_UINT32 }, { prop_currentverticalresW, CIM_UINT32 }, @@ -440,8 +501,12 @@ static const WCHAR bios_releasedateW[] = {'2','0','1','2','0','6','0','8','0','0','0','0','0','0','.','0','0','0','0','0','0','+','0','0','0',0}; static const WCHAR bios_serialnumberW[] = {'0',0}; +static const WCHAR bios_smbiosbiosversionW[] = + {'W','i','n','e',0}; static const WCHAR bios_versionW[] = {'W','I','N','E',' ',' ',' ','-',' ','1',0}; +static const WCHAR cdromdrive_mediatypeW[] = + {'C','D','-','R','O','M',0}; static const WCHAR cdromdrive_nameW[] = {'W','i','n','e',' ','C','D','-','R','O','M',' ','A','T','A',' ','D','e','v','i','c','e',0}; static const WCHAR cdromdrive_pnpdeviceidW[]= @@ -457,29 +522,46 @@ static const WCHAR compsys_manufacturerW[] = {'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0}; static const WCHAR compsys_modelW[] = {'W','i','n','e',0}; -static const WCHAR diskdrive_deviceidW[] = - {'\\','\\','\\','\\','.','\\','\\','P','H','Y','S','I','C','A','L','D','R','I','V','E','0',0}; -static const WCHAR diskdrive_modelW[] = - {'W','i','n','e',' ','D','i','s','k',' ','D','r','i','v','e',0}; +static const WCHAR diskdrive_interfacetypeW[] = + {'I','D','E',0}; static const WCHAR diskdrive_manufacturerW[] = {'(','S','t','a','n','d','a','r','d',' ','d','i','s','k',' ','d','r','i','v','e','s',')',0}; +static const WCHAR diskdrive_mediatype_fixedW[] = + {'F','i','x','e','d',' ','h','a','r','d',' ','d','i','s','k',0}; +static const WCHAR diskdrive_mediatype_removableW[] = + {'R','e','m','o','v','a','b','l','e',' ','m','e','d','i','a',0}; +static const WCHAR diskdrive_modelW[] = + {'W','i','n','e',' ','D','i','s','k',' ','D','r','i','v','e',0}; static const WCHAR diskdrive_serialW[] = {'W','I','N','E','H','D','I','S','K',0}; static const WCHAR networkadapter_pnpdeviceidW[]= {'P','C','I','\\','V','E','N','_','8','0','8','6','&','D','E','V','_','1','0','0','E','&', 'S','U','B','S','Y','S','_','0','0','1','E','8','0','8','6','&','R','E','V','_','0','2','\\', '3','&','2','6','7','A','6','1','6','A','&','1','&','1','8',0}; +static const WCHAR os_32bitW[] = + {'3','2','-','b','i','t',0}; +static const WCHAR os_64bitW[] = + {'6','4','-','b','i','t',0}; +static const WCHAR os_buildnumberW[] = + {'2','6','0','0',0}; static const WCHAR os_captionW[] = {'M','i','c','r','o','s','o','f','t',' ','W','i','n','d','o','w','s',' ','X','P',' ', 'V','e','r','s','i','o','n',' ','=',' ','5','.','1','.','2','6','0','0',0}; static const WCHAR os_csdversionW[] = {'S','e','r','v','i','c','e',' ','P','a','c','k',' ','3',0}; -static const WCHAR os_32bitW[] = - {'3','2','-','b','i','t',0}; -static const WCHAR os_64bitW[] = - {'6','4','-','b','i','t',0}; +static const WCHAR os_installdateW[] = + {'2','0','1','4','0','1','0','1','0','0','0','0','0','0','.','0','0','0','0','0','0','+','0','0','0',0}; +static const WCHAR os_nameW[] = + {'M','i','c','r','o','s','o','f','t',' ','W','i','n','d','o','w','s',' ','X','P',' ', + 'P','r','o','f','e','s','s','i','o','n','a','l','|','C',':','\\','W','I','N','D','O','W','S', + '|','\\','D','e','v','i','c','e','\\','H','a','r','d','d','i','s','k','0', + '\\','P','a','r','t','i','t','i','o','n','1',0}; +static const WCHAR os_serialnumberW[] = + {'1','2','3','4','5','-','O','E','M','-','1','2','3','4','5','6','7','-','1','2','3','4','5',0}; static const WCHAR os_versionW[] = {'5','.','1','.','2','6','0','0',0}; +static const WCHAR physicalmedia_tagW[] = + {'\\','\\','.','\\','P','H','Y','S','I','C','A','L','D','R','I','V','E','0',0}; static const WCHAR sounddevice_productnameW[] = {'W','i','n','e',' ','A','u','d','i','o',' ','D','e','v','i','c','e',0}; static const WCHAR videocontroller_dactypeW[] = @@ -491,21 +573,26 @@ static const WCHAR videocontroller_deviceidW[] = struct record_baseboard { const WCHAR *manufacturer; + const WCHAR *model; + const WCHAR *name; const WCHAR *serialnumber; const WCHAR *tag; }; struct record_bios { const WCHAR *description; + const WCHAR *identificationcode; const WCHAR *manufacturer; const WCHAR *releasedate; const WCHAR *serialnumber; + const WCHAR *smbiosbiosversion; const WCHAR *version; }; struct record_cdromdrive { const WCHAR *device_id; const WCHAR *drive; + const WCHAR *mediatype; const WCHAR *name; const WCHAR *pnpdevice_id; }; @@ -535,9 +622,12 @@ struct record_diskdrive { const WCHAR *device_id; UINT32 index; + const WCHAR *interfacetype; const WCHAR *manufacturer; - const WCHAR *name; + const WCHAR *mediatype; + const WCHAR *model; const WCHAR *serialnumber; + UINT64 size; }; struct record_diskpartition { @@ -559,32 +649,46 @@ struct record_logicaldisk UINT64 freespace; const WCHAR *name; UINT64 size; + const WCHAR *volumeserialnumber; }; struct record_networkadapter { const WCHAR *adaptertype; const WCHAR *device_id; - INT32 interface_index; + UINT32 index; + UINT32 interface_index; const WCHAR *mac_address; const WCHAR *manufacturer; + const WCHAR *name; UINT16 netconnection_status; int physicaladapter; const WCHAR *pnpdevice_id; UINT64 speed; }; +struct record_networkadapterconfig +{ + UINT32 index; + UINT32 ipconnectionmetric; + int ipenabled; + const WCHAR *mac_address; +}; struct record_operatingsystem { + const WCHAR *buildnumber; const WCHAR *caption; const WCHAR *codeset; const WCHAR *countrycode; const WCHAR *csdversion; + const WCHAR *installdate; const WCHAR *lastbootuptime; const WCHAR *localdatetime; const WCHAR *locale; + const WCHAR *name; const WCHAR *osarchitecture; UINT32 oslanguage; UINT32 osproductsuite; UINT16 ostype; + const WCHAR *serialnumber; UINT16 servicepackmajor; UINT16 servicepackminor; UINT32 suitemask; @@ -601,6 +705,15 @@ struct record_param UINT32 varianttype; UINT32 defaultvalue; }; +struct record_physicalmedia +{ + const WCHAR *serialnumber; + const WCHAR *tag; +}; +struct record_physicalmemory +{ + UINT64 capacity; +}; struct record_process { const WCHAR *caption; @@ -670,6 +783,7 @@ struct record_videocontroller { const WCHAR *adapter_dactype; UINT32 adapter_ram; + UINT16 availability; UINT32 current_bitsperpixel; UINT32 current_horizontalres; UINT32 current_verticalres; @@ -682,15 +796,12 @@ struct record_videocontroller static const struct record_baseboard data_baseboard[] = { - { baseboard_manufacturerW, baseboard_serialnumberW, baseboard_tagW } + { baseboard_manufacturerW, baseboard_tagW, baseboard_tagW, baseboard_serialnumberW, baseboard_tagW } }; static const struct record_bios data_bios[] = { - { bios_descriptionW, bios_manufacturerW, bios_releasedateW, bios_serialnumberW, bios_versionW } -}; -static const struct record_diskdrive data_diskdrive[] = -{ - { diskdrive_deviceidW, 0, diskdrive_manufacturerW, diskdrive_modelW, diskdrive_serialW } + { bios_descriptionW, bios_descriptionW, bios_manufacturerW, bios_releasedateW, bios_serialnumberW, + bios_smbiosbiosversionW, bios_versionW } }; static const struct record_param data_param[] = { @@ -720,6 +831,10 @@ static const struct record_param data_param[] = #define FLAVOR_ID (WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE | WBEM_FLAVOR_NOT_OVERRIDABLE |\ WBEM_FLAVOR_ORIGIN_PROPAGATED) +static const struct record_physicalmedia data_physicalmedia[] = +{ + { diskdrive_serialW, physicalmedia_tagW } +}; static const struct record_qualifier data_qualifier[] = { { class_process_getowner_outW, param_userW, CIM_SINT32, FLAVOR_ID, prop_idW, 0 }, @@ -738,12 +853,14 @@ static const struct record_stdregprov data_stdregprov[] = static BOOL match_row( const struct table *table, UINT row, const struct expr *cond, enum fill_status *status ) { LONGLONG val; + UINT type; + if (!cond) { *status = FILL_STATUS_UNFILTERED; return TRUE; } - if (eval_cond( table, row, cond, &val ) != S_OK) + if (eval_cond( table, row, cond, &val, &type ) != S_OK) { *status = FILL_STATUS_FAILED; return FALSE; @@ -796,6 +913,7 @@ static enum fill_status fill_cdromdrive( struct table *table, const struct expr rec->device_id = cdromdrive_pnpdeviceidW; sprintfW( drive, fmtW, 'A' + i ); rec->drive = heap_strdupW( drive ); + rec->mediatype = cdromdrive_mediatypeW; rec->name = cdromdrive_nameW; rec->pnpdevice_id = cdromdrive_pnpdeviceidW; if (!match_row( table, row, cond, &status )) @@ -1177,11 +1295,13 @@ static enum fill_status fill_datafile( struct table *table, const struct expr *c DWORD drives = GetLogicalDrives(); WIN32_FIND_DATAW data; HANDLE handle; - struct dirstack *dirstack = alloc_dirstack(2); + struct dirstack *dirstack; enum fill_status status = FILL_STATUS_UNFILTERED; if (!resize_table( table, 8, sizeof(*rec) )) return FILL_STATUS_FAILED; + dirstack = alloc_dirstack(2); + for (i = 0; i < sizeof(drives); i++) { if (!(drives & (1 << i))) continue; @@ -1207,6 +1327,7 @@ static enum fill_status fill_datafile( struct table *table, const struct expr *c if (!resize_table( table, row + 1, sizeof(*rec) )) { status = FILL_STATUS_FAILED; + FindClose( handle ); goto done; } if (!strcmpW( data.cFileName, dotW ) || !strcmpW( data.cFileName, dotdotW )) continue; @@ -1216,6 +1337,7 @@ static enum fill_status fill_datafile( struct table *table, const struct expr *c { if (push_dir( dirstack, new_path, len )) continue; heap_free( new_path ); + FindClose( handle ); status = FILL_STATUS_FAILED; goto done; } @@ -1349,16 +1471,6 @@ done: return status; } -static WCHAR *get_filesystem( const WCHAR *root ) -{ - static const WCHAR ntfsW[] = {'N','T','F','S',0}; - WCHAR buffer[MAX_PATH + 1]; - - if (GetVolumeInformationW( root, NULL, 0, NULL, NULL, NULL, buffer, MAX_PATH + 1 )) - return heap_strdupW( buffer ); - return heap_strdupW( ntfsW ); -} - static UINT64 get_freespace( const WCHAR *dir, UINT64 *disksize ) { WCHAR root[] = {'\\','\\','.','\\','A',':',0}; @@ -1380,6 +1492,69 @@ static UINT64 get_freespace( const WCHAR *dir, UINT64 *disksize ) return free.QuadPart; } +static enum fill_status fill_diskdrive( struct table *table, const struct expr *cond ) +{ + static const WCHAR fmtW[] = + {'\\','\\','\\','\\','.','\\','\\','P','H','Y','S','I','C','A','L','D','R','I','V','E','%','u',0}; + WCHAR device_id[sizeof(fmtW)/sizeof(fmtW[0]) + 10], root[] = {'A',':','\\',0}; + struct record_diskdrive *rec; + UINT i, row = 0, offset = 0, index = 0, type; + UINT64 size = 1024 * 1024 * 1024; + DWORD drives = GetLogicalDrives(); + enum fill_status status = FILL_STATUS_UNFILTERED; + + if (!resize_table( table, 2, sizeof(*rec) )) return FILL_STATUS_FAILED; + + for (i = 0; i < sizeof(drives); i++) + { + if (drives & (1 << i)) + { + root[0] = 'A' + i; + type = GetDriveTypeW( root ); + if (type != DRIVE_FIXED && type != DRIVE_REMOVABLE) + continue; + + if (!resize_table( table, row + 1, sizeof(*rec) )) return FILL_STATUS_FAILED; + + rec = (struct record_diskdrive *)(table->data + offset); + sprintfW( device_id, fmtW, index ); + rec->device_id = heap_strdupW( device_id ); + rec->index = index; + rec->interfacetype = diskdrive_interfacetypeW; + rec->manufacturer = diskdrive_manufacturerW; + if (type == DRIVE_FIXED) + rec->mediatype = diskdrive_mediatype_fixedW; + else + rec->mediatype = diskdrive_mediatype_removableW; + rec->model = diskdrive_modelW; + rec->serialnumber = diskdrive_serialW; + get_freespace( root, &size ); + rec->size = size; + if (!match_row( table, row, cond, &status )) + { + free_row_values( table, row ); + continue; + } + offset += sizeof(*rec); + index++; + row++; + } + } + TRACE("created %u rows\n", row); + table->num_rows = row; + return status; +} + +static WCHAR *get_filesystem( const WCHAR *root ) +{ + static const WCHAR ntfsW[] = {'N','T','F','S',0}; + WCHAR buffer[MAX_PATH + 1]; + + if (GetVolumeInformationW( root, NULL, 0, NULL, NULL, NULL, buffer, MAX_PATH + 1 )) + return heap_strdupW( buffer ); + return heap_strdupW( ntfsW ); +} + static enum fill_status fill_diskpartition( struct table *table, const struct expr *cond ) { static const WCHAR fmtW[] = @@ -1431,6 +1606,17 @@ static enum fill_status fill_diskpartition( struct table *table, const struct ex return status; } +static WCHAR *get_volumeserialnumber( const WCHAR *root ) +{ + static const WCHAR fmtW[] = {'%','0','8','X',0}; + DWORD serial = 0; + WCHAR buffer[9]; + + GetVolumeInformationW( root, NULL, 0, &serial, NULL, NULL, NULL, 0 ); + sprintfW( buffer, fmtW, serial ); + return heap_strdupW( buffer ); +} + static enum fill_status fill_logicaldisk( struct table *table, const struct expr *cond ) { static const WCHAR fmtW[] = {'%','c',':',0}; @@ -1456,12 +1642,13 @@ static enum fill_status fill_logicaldisk( struct table *table, const struct expr rec = (struct record_logicaldisk *)(table->data + offset); sprintfW( device_id, fmtW, 'A' + i ); - rec->device_id = heap_strdupW( device_id ); - rec->drivetype = type; - rec->filesystem = get_filesystem( root ); - rec->freespace = get_freespace( root, &size ); - rec->name = heap_strdupW( device_id ); - rec->size = size; + rec->device_id = heap_strdupW( device_id ); + rec->drivetype = type; + rec->filesystem = get_filesystem( root ); + rec->freespace = get_freespace( root, &size ); + rec->name = heap_strdupW( device_id ); + rec->size = size; + rec->volumeserialnumber = get_volumeserialnumber( root ); if (!match_row( table, row, cond, &status )) { free_row_values( table, row ); @@ -1538,7 +1725,10 @@ static enum fill_status fill_networkadapter( struct table *table, const struct e heap_free( buffer ); return FILL_STATUS_FAILED; } - for (aa = buffer; aa; aa = aa->Next) count++; + for (aa = buffer; aa; aa = aa->Next) + { + if (aa->IfType != IF_TYPE_SOFTWARE_LOOPBACK) count++; + } if (!resize_table( table, count, sizeof(*rec) )) { heap_free( buffer ); @@ -1546,13 +1736,17 @@ static enum fill_status fill_networkadapter( struct table *table, const struct e } for (aa = buffer; aa; aa = aa->Next) { + if (aa->IfType == IF_TYPE_SOFTWARE_LOOPBACK) continue; + rec = (struct record_networkadapter *)(table->data + offset); sprintfW( device_id, fmtW, aa->u.s.IfIndex ); rec->adaptertype = get_adaptertype( aa->IfType, &physical ); rec->device_id = heap_strdupW( device_id ); + rec->index = aa->u.s.IfIndex; rec->interface_index = aa->u.s.IfIndex; rec->mac_address = get_mac_address( aa->PhysicalAddress, aa->PhysicalAddressLength ); rec->manufacturer = compsys_manufacturerW; + rec->name = heap_strdupW( aa->FriendlyName ); rec->netconnection_status = get_connection_status( aa->OperStatus ); rec->physicaladapter = physical; rec->pnpdevice_id = networkadapter_pnpdeviceidW; @@ -1572,6 +1766,74 @@ static enum fill_status fill_networkadapter( struct table *table, const struct e return status; } +static enum fill_status fill_networkadapterconfig( struct table *table, const struct expr *cond ) +{ + struct record_networkadapterconfig *rec; + IP_ADAPTER_ADDRESSES *aa, *buffer; + UINT row = 0, offset = 0, count = 0; + DWORD size = 0, ret; + enum fill_status status = FILL_STATUS_UNFILTERED; + + ret = GetAdaptersAddresses( AF_UNSPEC, 0, NULL, NULL, &size ); + if (ret != ERROR_BUFFER_OVERFLOW) return FILL_STATUS_FAILED; + + if (!(buffer = heap_alloc( size ))) return FILL_STATUS_FAILED; + if (GetAdaptersAddresses( AF_UNSPEC, 0, NULL, buffer, &size )) + { + heap_free( buffer ); + return FILL_STATUS_FAILED; + } + for (aa = buffer; aa; aa = aa->Next) + { + if (aa->IfType != IF_TYPE_SOFTWARE_LOOPBACK) count++; + } + if (!resize_table( table, count, sizeof(*rec) )) + { + heap_free( buffer ); + return FILL_STATUS_FAILED; + } + for (aa = buffer; aa; aa = aa->Next) + { + if (aa->IfType == IF_TYPE_SOFTWARE_LOOPBACK) continue; + + rec = (struct record_networkadapterconfig *)(table->data + offset); + rec->index = aa->u.s.IfIndex; + rec->ipconnectionmetric = 20; + rec->ipenabled = -1; + rec->mac_address = get_mac_address( aa->PhysicalAddress, aa->PhysicalAddressLength ); + if (!match_row( table, row, cond, &status )) + { + free_row_values( table, row ); + continue; + } + offset += sizeof(*rec); + row++; + } + TRACE("created %u rows\n", row); + table->num_rows = row; + + heap_free( buffer ); + return status; +} + +static enum fill_status fill_physicalmemory( struct table *table, const struct expr *cond ) +{ + struct record_physicalmemory *rec; + enum fill_status status = FILL_STATUS_UNFILTERED; + UINT row = 0; + + if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED; + + rec = (struct record_physicalmemory *)table->data; + rec->capacity = get_total_physical_memory(); + if (!match_row( table, row, cond, &status )) free_row_values( table, row ); + else row++; + + TRACE("created %u rows\n", row); + table->num_rows = row; + return status; +} + static WCHAR *get_cmdline( DWORD process_id ) { if (process_id == GetCurrentProcessId()) return heap_strdupW( GetCommandLineW() ); @@ -1835,17 +2097,21 @@ static enum fill_status fill_os( struct table *table, const struct expr *cond ) if (!resize_table( table, 1, sizeof(*rec) )) return FILL_STATUS_FAILED; rec = (struct record_operatingsystem *)table->data; + rec->buildnumber = os_buildnumberW; rec->caption = os_captionW; rec->codeset = get_codeset(); rec->countrycode = get_countrycode(); rec->csdversion = os_csdversionW; + rec->installdate = os_installdateW; rec->lastbootuptime = get_lastbootuptime(); rec->localdatetime = get_localdatetime(); rec->locale = get_locale(); + rec->name = os_nameW; rec->osarchitecture = get_osarchitecture(); rec->oslanguage = GetSystemDefaultLangID(); rec->osproductsuite = 2461140; /* Windows XP Professional */ rec->ostype = 18; /* WINNT */ + rec->serialnumber = os_serialnumberW; rec->servicepackmajor = 3; rec->servicepackminor = 0; rec->suitemask = 272; /* Single User + Terminal */ @@ -2073,6 +2339,7 @@ done: rec = (struct record_videocontroller *)table->data; rec->adapter_dactype = videocontroller_dactypeW; rec->adapter_ram = vidmem; + rec->availability = 3; /* Running or Full Power */ rec->current_bitsperpixel = get_bits_per_pixel( &hres, &vres ); rec->current_horizontalres = hres; rec->current_verticalres = vres; @@ -2099,13 +2366,17 @@ static struct table builtin_classes[] = { class_compsysW, SIZEOF(col_compsys), col_compsys, 0, 0, NULL, fill_compsys }, { class_datafileW, SIZEOF(col_datafile), col_datafile, 0, 0, NULL, fill_datafile }, { class_directoryW, SIZEOF(col_directory), col_directory, 0, 0, NULL, fill_directory }, - { class_diskdriveW, SIZEOF(col_diskdrive), col_diskdrive, SIZEOF(data_diskdrive), 0, (BYTE *)data_diskdrive }, + { class_diskdriveW, SIZEOF(col_diskdrive), col_diskdrive, 0, 0, NULL, fill_diskdrive }, { class_diskpartitionW, SIZEOF(col_diskpartition), col_diskpartition, 0, 0, NULL, fill_diskpartition }, { class_logicaldiskW, SIZEOF(col_logicaldisk), col_logicaldisk, 0, 0, NULL, fill_logicaldisk }, { class_logicaldisk2W, SIZEOF(col_logicaldisk), col_logicaldisk, 0, 0, NULL, fill_logicaldisk }, { class_networkadapterW, SIZEOF(col_networkadapter), col_networkadapter, 0, 0, NULL, fill_networkadapter }, + { class_networkadapterconfigW, SIZEOF(col_networkadapterconfig), col_networkadapterconfig, 0, 0, NULL, + fill_networkadapterconfig }, { class_osW, SIZEOF(col_os), col_os, 0, 0, NULL, fill_os }, { class_paramsW, SIZEOF(col_param), col_param, SIZEOF(data_param), 0, (BYTE *)data_param }, + { class_physicalmediaW, SIZEOF(col_physicalmedia), col_physicalmedia, SIZEOF(data_physicalmedia), 0, (BYTE *)data_physicalmedia }, + { class_physicalmemoryW, SIZEOF(col_physicalmemory), col_physicalmemory, 0, 0, NULL, fill_physicalmemory }, { class_processW, SIZEOF(col_process), col_process, 0, 0, NULL, fill_process }, { class_processorW, SIZEOF(col_processor), col_processor, 0, 0, NULL, fill_processor }, { class_qualifiersW, SIZEOF(col_qualifier), col_qualifier, SIZEOF(data_qualifier), 0, (BYTE *)data_qualifier }, diff --git a/dll/win32/wbemprox/class.c b/dll/win32/wbemprox/class.c index b2970f8601a..aa51816b278 100644 --- a/dll/win32/wbemprox/class.c +++ b/dll/win32/wbemprox/class.c @@ -139,7 +139,7 @@ static HRESULT WINAPI enum_class_object_Clone( TRACE("%p, %p\n", iface, ppEnum); - return EnumWbemClassObject_create( NULL, ec->query, (void **)ppEnum ); + return EnumWbemClassObject_create( ec->query, (void **)ppEnum ); } static HRESULT WINAPI enum_class_object_Skip( @@ -177,12 +177,11 @@ static const IEnumWbemClassObjectVtbl enum_class_object_vtbl = enum_class_object_Skip }; -HRESULT EnumWbemClassObject_create( - IUnknown *pUnkOuter, struct query *query, LPVOID *ppObj ) +HRESULT EnumWbemClassObject_create( struct query *query, LPVOID *ppObj ) { struct enum_class_object *ec; - TRACE("%p, %p\n", pUnkOuter, ppObj); + TRACE("%p\n", ppObj); ec = heap_alloc( sizeof(*ec) ); if (!ec) return E_OUTOFMEMORY; @@ -464,17 +463,17 @@ static HRESULT WINAPI class_object_GetNames( TRACE("%p, %s, %08x, %s, %p\n", iface, debugstr_w(wszQualifierName), lFlags, debugstr_variant(pQualifierVal), pNames); - if (wszQualifierName || pQualifierVal) - { - FIXME("qualifier not supported\n"); - return E_NOTIMPL; - } - if (lFlags != WBEM_FLAG_ALWAYS) + if (lFlags != WBEM_FLAG_ALWAYS && + lFlags != WBEM_FLAG_NONSYSTEM_ONLY && + lFlags != WBEM_FLAG_SYSTEM_ONLY) { FIXME("flags %08x not supported\n", lFlags); return E_NOTIMPL; } - return get_properties( ec->query->view, pNames ); + if (wszQualifierName || pQualifierVal) + FIXME("qualifier not supported\n"); + + return get_properties( ec->query->view, lFlags, pNames ); } static HRESULT WINAPI class_object_BeginEnumeration( @@ -508,7 +507,7 @@ static HRESULT WINAPI class_object_Next( TRACE("%p, %08x, %p, %p, %p, %p\n", iface, lFlags, strName, pVal, pType, plFlavor); if (!(property = get_property_name( co->name, co->index_property ))) return WBEM_S_NO_MORE_DATA; - if ((hr = get_propval( view, co->index, property, pVal, pType, plFlavor ) != S_OK)) + if ((hr = get_propval( view, co->index, property, pVal, pType, plFlavor )) != S_OK) { SysFreeString( property ); return hr; @@ -538,7 +537,7 @@ static HRESULT WINAPI class_object_GetPropertyQualifierSet( TRACE("%p, %s, %p\n", iface, debugstr_w(wszProperty), ppQualSet); - return WbemQualifierSet_create( NULL, co->name, wszProperty, (void **)ppQualSet ); + return WbemQualifierSet_create( co->name, wszProperty, (void **)ppQualSet ); } static HRESULT WINAPI class_object_Clone( diff --git a/dll/win32/wbemprox/main.c b/dll/win32/wbemprox/main.c index 63339d64307..064a497a286 100644 --- a/dll/win32/wbemprox/main.c +++ b/dll/win32/wbemprox/main.c @@ -24,7 +24,7 @@ static HINSTANCE instance; -typedef HRESULT (*fnCreateInstance)( IUnknown *pUnkOuter, LPVOID *ppObj ); +typedef HRESULT (*fnCreateInstance)( LPVOID *ppObj ); typedef struct { @@ -74,14 +74,11 @@ static HRESULT WINAPI wbemprox_cf_CreateInstance( IClassFactory *iface, LPUNKNOW if (pOuter) return CLASS_E_NOAGGREGATION; - r = This->pfnCreateInstance( pOuter, (LPVOID *)&punk ); + r = This->pfnCreateInstance( (LPVOID *)&punk ); if (FAILED(r)) return r; r = IUnknown_QueryInterface( punk, riid, ppobj ); - if (FAILED(r)) - return r; - IUnknown_Release( punk ); return r; } diff --git a/dll/win32/wbemprox/qualifier.c b/dll/win32/wbemprox/qualifier.c index 9b4d1f5a3a9..c14338698c6 100644 --- a/dll/win32/wbemprox/qualifier.c +++ b/dll/win32/wbemprox/qualifier.c @@ -234,12 +234,11 @@ static const IWbemQualifierSetVtbl qualifier_set_vtbl = qualifier_set_EndEnumeration }; -HRESULT WbemQualifierSet_create( - IUnknown *pUnkOuter, const WCHAR *class, const WCHAR *member, LPVOID *ppObj ) +HRESULT WbemQualifierSet_create( const WCHAR *class, const WCHAR *member, LPVOID *ppObj ) { struct qualifier_set *set; - TRACE("%p, %p\n", pUnkOuter, ppObj); + TRACE("%p\n", ppObj); if (!(set = heap_alloc( sizeof(*set) ))) return E_OUTOFMEMORY; diff --git a/dll/win32/wbemprox/query.c b/dll/win32/wbemprox/query.c index 2a6e5744ee9..e7984a4e4ce 100644 --- a/dll/win32/wbemprox/query.c +++ b/dll/win32/wbemprox/query.c @@ -102,16 +102,94 @@ static inline BOOL is_strcmp( const struct complex_expr *expr ) (expr->left->type == EXPR_SVAL && expr->right->type == EXPR_PROPVAL)); } +static inline BOOL is_boolcmp( const struct complex_expr *expr, UINT ltype, UINT rtype ) +{ + if (ltype == CIM_BOOLEAN && expr->left->type == EXPR_PROPVAL && + (expr->right->type == EXPR_SVAL || expr->right->type == EXPR_BVAL)) return TRUE; + else if (rtype == CIM_BOOLEAN && expr->right->type == EXPR_PROPVAL && + (expr->left->type == EXPR_SVAL || expr->left->type == EXPR_BVAL)) return TRUE; + return FALSE; +} + +static HRESULT eval_boolcmp( UINT op, LONGLONG lval, LONGLONG rval, UINT ltype, UINT rtype, LONGLONG *val ) +{ + static const WCHAR trueW[] = {'T','r','u','e',0}; + + if (ltype == CIM_STRING) lval = !strcmpiW( (const WCHAR *)(INT_PTR)lval, trueW ) ? -1 : 0; + else if (rtype == CIM_STRING) rval = !strcmpiW( (const WCHAR *)(INT_PTR)rval, trueW ) ? -1 : 0; + + switch (op) + { + case OP_EQ: + *val = (lval == rval); + break; + case OP_NE: + *val = (lval != rval); + break; + default: + ERR("unhandled operator %u\n", op); + return WBEM_E_INVALID_QUERY; + } + return S_OK; +} + +static UINT resolve_type( UINT left, UINT right ) +{ + switch (left) + { + case CIM_SINT8: + case CIM_SINT16: + case CIM_SINT32: + case CIM_SINT64: + case CIM_UINT8: + case CIM_UINT16: + case CIM_UINT32: + case CIM_UINT64: + switch (right) + { + case CIM_SINT8: + case CIM_SINT16: + case CIM_SINT32: + case CIM_SINT64: + case CIM_UINT8: + case CIM_UINT16: + case CIM_UINT32: + case CIM_UINT64: + return CIM_UINT64; + default: break; + } + break; + + case CIM_STRING: + if (right == CIM_STRING) return CIM_STRING; + break; + + case CIM_BOOLEAN: + if (right == CIM_BOOLEAN) return CIM_BOOLEAN; + break; + + default: + break; + } + return CIM_ILLEGAL; +} + static HRESULT eval_binary( const struct table *table, UINT row, const struct complex_expr *expr, - LONGLONG *val ) + LONGLONG *val, UINT *type ) { HRESULT lret, rret; LONGLONG lval, rval; + UINT ltype, rtype; - lret = eval_cond( table, row, expr->left, &lval ); - rret = eval_cond( table, row, expr->right, &rval ); + lret = eval_cond( table, row, expr->left, &lval, <ype ); + rret = eval_cond( table, row, expr->right, &rval, &rtype ); if (lret != S_OK || rret != S_OK) return WBEM_E_INVALID_QUERY; + *type = resolve_type( ltype, rtype ); + + if (is_boolcmp( expr, ltype, rtype )) + return eval_boolcmp( expr->op, lval, rval, ltype, rtype, val ); + if (is_strcmp( expr )) { const WCHAR *lstr = (const WCHAR *)(INT_PTR)lval; @@ -153,13 +231,22 @@ static HRESULT eval_binary( const struct table *table, UINT row, const struct co } static HRESULT eval_unary( const struct table *table, UINT row, const struct complex_expr *expr, - LONGLONG *val ) + LONGLONG *val, UINT *type ) { HRESULT hr; UINT column; LONGLONG lval; + if (expr->op == OP_NOT) + { + hr = eval_cond( table, row, expr->left, &lval, type ); + if (hr != S_OK) + return hr; + *val = !lval; + return S_OK; + } + hr = get_column_index( table, expr->left->u.propval->name, &column ); if (hr != S_OK) return hr; @@ -180,11 +267,13 @@ static HRESULT eval_unary( const struct table *table, UINT row, const struct com ERR("unknown operator %u\n", expr->op); return WBEM_E_INVALID_QUERY; } + + *type = table->columns[column].type & CIM_TYPE_MASK; return S_OK; } static HRESULT eval_propval( const struct table *table, UINT row, const struct property *propval, - LONGLONG *val ) + LONGLONG *val, UINT *type ) { HRESULT hr; @@ -194,31 +283,44 @@ static HRESULT eval_propval( const struct table *table, UINT row, const struct p if (hr != S_OK) return hr; + *type = table->columns[column].type & CIM_TYPE_MASK; return get_value( table, row, column, val ); } -HRESULT eval_cond( const struct table *table, UINT row, const struct expr *cond, LONGLONG *val ) +HRESULT eval_cond( const struct table *table, UINT row, const struct expr *cond, LONGLONG *val, UINT *type ) { if (!cond) { *val = 1; + *type = CIM_UINT64; return S_OK; } switch (cond->type) { case EXPR_COMPLEX: - return eval_binary( table, row, &cond->u.expr, val ); + return eval_binary( table, row, &cond->u.expr, val, type ); + case EXPR_UNARY: - return eval_unary( table, row, &cond->u.expr, val ); + return eval_unary( table, row, &cond->u.expr, val, type ); + case EXPR_PROPVAL: - return eval_propval( table, row, cond->u.propval, val ); + return eval_propval( table, row, cond->u.propval, val, type ); + case EXPR_SVAL: *val = (INT_PTR)cond->u.sval; + *type = CIM_STRING; return S_OK; + case EXPR_IVAL: + *val = cond->u.ival; + *type = CIM_UINT64; + return S_OK; + case EXPR_BVAL: *val = cond->u.ival; + *type = CIM_BOOLEAN; return S_OK; + default: ERR("invalid expression type\n"); break; @@ -245,6 +347,7 @@ HRESULT execute_view( struct view *view ) { HRESULT hr; LONGLONG val = 0; + UINT type; if (j >= len) { @@ -253,7 +356,7 @@ HRESULT execute_view( struct view *view ) if (!(tmp = heap_realloc( view->result, len * sizeof(UINT) ))) return E_OUTOFMEMORY; view->result = tmp; } - if ((hr = eval_cond( view->table, i, view->cond, &val )) != S_OK) return hr; + if ((hr = eval_cond( view->table, i, view->cond, &val, &type )) != S_OK) return hr; if (val) view->result[j++] = i; } view->count = j; @@ -302,7 +405,7 @@ HRESULT exec_query( const WCHAR *str, IEnumWbemClassObject **result ) if (hr != S_OK) goto done; hr = execute_view( query->view ); if (hr != S_OK) goto done; - hr = EnumWbemClassObject_create( NULL, query, (void **)result ); + hr = EnumWbemClassObject_create( query, (void **)result ); done: release_query( query ); @@ -844,7 +947,7 @@ HRESULT put_propval( const struct view *view, UINT index, const WCHAR *name, VAR return set_value( view->table, row, column, val, type ); } -HRESULT get_properties( const struct view *view, SAFEARRAY **props ) +HRESULT get_properties( const struct view *view, LONG flags, SAFEARRAY **props ) { SAFEARRAY *sa; BSTR str; @@ -855,8 +958,14 @@ HRESULT get_properties( const struct view *view, SAFEARRAY **props ) for (i = 0; i < view->table->num_cols; i++) { + BOOL is_system; + if (is_method( view->table, i )) continue; + is_system = is_system_prop( view->table->columns[i].name ); + if ((flags & WBEM_FLAG_NONSYSTEM_ONLY) && is_system) continue; + else if ((flags & WBEM_FLAG_SYSTEM_ONLY) && !is_system) continue; + str = SysAllocString( view->table->columns[i].name ); if (!str || SafeArrayPutElement( sa, &i, str ) != S_OK) { diff --git a/dll/win32/wbemprox/services.c b/dll/win32/wbemprox/services.c index 23bd894235b..70d1442d8cf 100644 --- a/dll/win32/wbemprox/services.c +++ b/dll/win32/wbemprox/services.c @@ -268,7 +268,7 @@ static HRESULT WINAPI wbem_services_OpenNamespace( if ((strcmpiW( strNamespace, cimv2W ) && strcmpiW( strNamespace, defaultW )) || ws->namespace) return WBEM_E_INVALID_NAMESPACE; - return WbemServices_create( NULL, cimv2W, (void **)ppWorkingNamespace ); + return WbemServices_create( cimv2W, (void **)ppWorkingNamespace ); } static HRESULT WINAPI wbem_services_CancelAsyncCall( @@ -802,7 +802,7 @@ static HRESULT WINAPI wbem_services_ExecMethod( hr = execute_view( query->view ); if (hr != S_OK) goto done; - hr = EnumWbemClassObject_create( NULL, query, (void **)&result ); + hr = EnumWbemClassObject_create( query, (void **)&result ); if (hr != S_OK) goto done; hr = create_class_object( query->view->table->name, result, 0, NULL, &obj ); @@ -865,11 +865,11 @@ static const IWbemServicesVtbl wbem_services_vtbl = wbem_services_ExecMethodAsync }; -HRESULT WbemServices_create( IUnknown *pUnkOuter, const WCHAR *namespace, LPVOID *ppObj ) +HRESULT WbemServices_create( const WCHAR *namespace, LPVOID *ppObj ) { struct wbem_services *ws; - TRACE("(%p,%p)\n", pUnkOuter, ppObj); + TRACE("(%p)\n", ppObj); ws = heap_alloc( sizeof(*ws) ); if (!ws) return E_OUTOFMEMORY; diff --git a/dll/win32/wbemprox/wbemlocator.c b/dll/win32/wbemprox/wbemlocator.c index 1a590a7891e..11ded2f8998 100644 --- a/dll/win32/wbemprox/wbemlocator.c +++ b/dll/win32/wbemprox/wbemlocator.c @@ -180,7 +180,7 @@ static HRESULT WINAPI wbem_locator_ConnectServer( if (SecurityFlags) FIXME("unsupported flags\n"); - hr = WbemServices_create( NULL, namespace, (void **)ppNamespace ); + hr = WbemServices_create( namespace, (void **)ppNamespace ); heap_free( namespace ); heap_free( server ); if (SUCCEEDED( hr )) @@ -197,11 +197,11 @@ static const IWbemLocatorVtbl wbem_locator_vtbl = wbem_locator_ConnectServer }; -HRESULT WbemLocator_create( IUnknown *pUnkOuter, LPVOID *ppObj ) +HRESULT WbemLocator_create( LPVOID *ppObj ) { wbem_locator *wl; - TRACE("(%p,%p)\n", pUnkOuter, ppObj); + TRACE("(%p)\n", ppObj); wl = heap_alloc( sizeof(*wl) ); if (!wl) return E_OUTOFMEMORY; diff --git a/dll/win32/wbemprox/wbemprox.idl b/dll/win32/wbemprox/wbemprox.idl index 4b19384bc7e..5c6255a39dc 100644 --- a/dll/win32/wbemprox/wbemprox.idl +++ b/dll/win32/wbemprox/wbemprox.idl @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma makedep register + [ helpstring("WBEM Locator"), threading(both), diff --git a/dll/win32/wbemprox/wbemprox_private.h b/dll/win32/wbemprox/wbemprox_private.h index 6aee2da7356..6a815ea21cf 100644 --- a/dll/win32/wbemprox/wbemprox_private.h +++ b/dll/win32/wbemprox/wbemprox_private.h @@ -78,7 +78,8 @@ enum operator OP_NE = 8, OP_ISNULL = 9, OP_NOTNULL = 10, - OP_LIKE = 11 + OP_LIKE = 11, + OP_NOT = 12 }; struct expr; @@ -211,7 +212,7 @@ void free_row_values( const struct table *, UINT ) DECLSPEC_HIDDEN; void clear_table( struct table * ) DECLSPEC_HIDDEN; void free_table( struct table * ) DECLSPEC_HIDDEN; UINT get_type_size( CIMTYPE ) DECLSPEC_HIDDEN; -HRESULT eval_cond( const struct table *, UINT, const struct expr *, LONGLONG * ) DECLSPEC_HIDDEN; +HRESULT eval_cond( const struct table *, UINT, const struct expr *, LONGLONG *, UINT * ) DECLSPEC_HIDDEN; HRESULT get_column_index( const struct table *, const WCHAR *, UINT * ) DECLSPEC_HIDDEN; HRESULT get_value( const struct table *, UINT, UINT, LONGLONG * ) DECLSPEC_HIDDEN; BSTR get_value_bstr( const struct table *, UINT, UINT ) DECLSPEC_HIDDEN; @@ -224,7 +225,7 @@ HRESULT to_longlong( VARIANT *, LONGLONG *, CIMTYPE * ) DECLSPEC_HIDDEN; SAFEARRAY *to_safearray( const struct array *, CIMTYPE ) DECLSPEC_HIDDEN; VARTYPE to_vartype( CIMTYPE ) DECLSPEC_HIDDEN; void destroy_array( struct array *, CIMTYPE ) DECLSPEC_HIDDEN; -HRESULT get_properties( const struct view *, SAFEARRAY ** ) DECLSPEC_HIDDEN; +HRESULT get_properties( const struct view *, LONG, SAFEARRAY ** ) DECLSPEC_HIDDEN; HRESULT get_object( const WCHAR *, IWbemClassObject ** ) DECLSPEC_HIDDEN; BSTR get_method_name( const WCHAR *, UINT ) DECLSPEC_HIDDEN; BSTR get_property_name( const WCHAR *, UINT ) DECLSPEC_HIDDEN; @@ -232,12 +233,12 @@ void set_variant( VARTYPE, LONGLONG, void *, VARIANT * ) DECLSPEC_HIDDEN; HRESULT create_signature( const WCHAR *, const WCHAR *, enum param_direction, IWbemClassObject ** ) DECLSPEC_HIDDEN; -HRESULT WbemLocator_create(IUnknown *, LPVOID *) DECLSPEC_HIDDEN; -HRESULT WbemServices_create(IUnknown *, const WCHAR *, LPVOID *) DECLSPEC_HIDDEN; +HRESULT WbemLocator_create(LPVOID *) DECLSPEC_HIDDEN; +HRESULT WbemServices_create(const WCHAR *, LPVOID *) DECLSPEC_HIDDEN; HRESULT create_class_object(const WCHAR *, IEnumWbemClassObject *, UINT, struct record *, IWbemClassObject **) DECLSPEC_HIDDEN; -HRESULT EnumWbemClassObject_create(IUnknown *, struct query *, LPVOID *) DECLSPEC_HIDDEN; -HRESULT WbemQualifierSet_create(IUnknown *, const WCHAR *, const WCHAR *, LPVOID *) DECLSPEC_HIDDEN; +HRESULT EnumWbemClassObject_create(struct query *, LPVOID *) DECLSPEC_HIDDEN; +HRESULT WbemQualifierSet_create(const WCHAR *, const WCHAR *, LPVOID *) DECLSPEC_HIDDEN; HRESULT process_get_owner(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; HRESULT reg_enum_key(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; diff --git a/dll/win32/wbemprox/wql.tab.c b/dll/win32/wbemprox/wql.tab.c index f3512bdf082..86127b41da8 100644 --- a/dll/win32/wbemprox/wql.tab.c +++ b/dll/win32/wbemprox/wql.tab.c @@ -560,16 +560,16 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 9 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 67 +#define YYLAST 68 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 32 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 10 /* YYNRULES -- Number of rules. */ -#define YYNRULES 35 +#define YYNRULES 36 /* YYNRULES -- Number of states. */ -#define YYNSTATES 65 +#define YYNSTATES 67 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 @@ -618,9 +618,9 @@ static const yytype_uint8 yytranslate[] = static const yytype_uint8 yyprhs[] = { 0, 0, 3, 7, 12, 19, 21, 25, 27, 31, - 33, 35, 37, 41, 45, 49, 53, 57, 61, 65, - 69, 73, 77, 81, 85, 89, 93, 97, 101, 105, - 110, 112, 114, 116, 118, 120 + 33, 35, 37, 41, 45, 49, 52, 56, 60, 64, + 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, + 108, 113, 115, 117, 119, 121, 123 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ @@ -630,15 +630,15 @@ static const yytype_int8 yyrhs[] = 36, -1, 3, 34, 4, 36, 15, 38, -1, 35, -1, 35, 6, 34, -1, 5, -1, 36, 7, 36, -1, 36, -1, 21, -1, 14, -1, 9, 38, 10, - -1, 38, 23, 38, -1, 38, 22, 38, -1, 40, - 31, 41, -1, 40, 28, 41, -1, 40, 29, 41, - -1, 40, 27, 41, -1, 40, 26, 41, -1, 40, - 30, 41, -1, 41, 31, 40, -1, 41, 28, 40, - -1, 41, 29, 40, -1, 41, 27, 40, -1, 41, - 26, 40, -1, 41, 30, 40, -1, 40, 25, 39, - -1, 40, 8, 11, -1, 40, 8, 24, 11, -1, - 20, -1, 35, -1, 37, -1, 20, -1, 13, -1, - 12, -1 + -1, 38, 23, 38, -1, 38, 22, 38, -1, 24, + 38, -1, 40, 31, 41, -1, 40, 28, 41, -1, + 40, 29, 41, -1, 40, 27, 41, -1, 40, 26, + 41, -1, 40, 30, 41, -1, 41, 31, 40, -1, + 41, 28, 40, -1, 41, 29, 40, -1, 41, 27, + 40, -1, 41, 26, 40, -1, 41, 30, 40, -1, + 40, 25, 39, -1, 40, 8, 11, -1, 40, 8, + 24, 11, -1, 20, -1, 35, -1, 37, -1, 20, + -1, 13, -1, 12, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ @@ -647,7 +647,7 @@ static const yytype_uint16 yyrline[] = 0, 221, 221, 233, 245, 260, 261, 265, 272, 278, 287, 296, 303, 309, 315, 321, 327, 333, 339, 345, 351, 357, 363, 369, 375, 381, 387, 393, 399, 405, - 414, 423, 432, 438, 444, 450 + 411, 420, 429, 438, 444, 450, 456 }; #endif @@ -684,16 +684,16 @@ static const yytype_uint8 yyr1[] = 0, 32, 33, 33, 33, 34, 34, 34, 35, 35, 36, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 39, 40, 41, 41, 41, 41 + 38, 39, 40, 41, 41, 41, 41 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 3, 4, 6, 1, 3, 1, 3, 1, - 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, - 1, 1, 1, 1, 1, 1 + 1, 1, 3, 3, 3, 2, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 1, 1, 1, 1, 1, 1 }; /* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. @@ -702,38 +702,38 @@ static const yytype_uint8 yyr2[] = static const yytype_uint8 yydefact[] = { 0, 0, 0, 0, 7, 10, 0, 5, 9, 1, - 2, 0, 0, 0, 3, 6, 8, 0, 0, 35, - 34, 11, 33, 31, 32, 4, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 12, 14, 13, 28, 0, - 30, 27, 19, 18, 16, 17, 20, 15, 25, 24, - 22, 23, 26, 21, 29 + 2, 0, 0, 0, 3, 6, 8, 0, 0, 36, + 35, 11, 34, 0, 32, 33, 4, 0, 0, 0, + 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 12, 14, 13, + 29, 0, 31, 28, 20, 19, 17, 18, 21, 16, + 26, 25, 23, 24, 27, 22, 30 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 2, 6, 23, 8, 24, 25, 51, 26, 27 + -1, 2, 6, 24, 8, 25, 26, 53, 27, 28 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -20 +#define YYPACT_NINF -18 static const yytype_int8 yypact[] = { - 2, 3, 6, -10, -20, -20, 24, 31, 33, -20, - -20, -10, 4, -10, 26, -20, -20, 18, 18, -20, - -20, -20, -20, -20, -20, -19, -8, 20, -9, 18, - 18, 5, 23, 22, 22, 22, 22, 22, 22, -10, - -10, -10, -10, -10, -10, -20, 41, -20, -20, 54, - -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, - -20, -20, -20, -20, -20 + 7, 3, 12, -5, -18, -18, 31, 30, 21, -18, + -18, -5, 4, -5, 28, -18, -18, 17, 17, -18, + -18, -18, -18, 17, -18, -18, 11, -8, 24, 22, + -18, 17, 17, 16, 26, -9, -9, -9, -9, -9, + -9, -5, -5, -5, -5, -5, -5, -18, 19, -18, + -18, 37, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, -18, -18, -18, -18 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -20, -20, 55, 14, -1, -20, 15, -20, 13, 25 + -18, -18, 56, 1, 36, -18, -17, -18, 15, 27 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If @@ -742,30 +742,30 @@ static const yytype_int8 yypgoto[] = #define YYTABLE_NINF -1 static const yytype_uint8 yytable[] = { - 31, 45, 10, 29, 30, 1, 9, 3, 4, 4, - 14, 5, 16, 29, 30, 7, 48, 32, 33, 34, - 35, 36, 37, 38, 5, 5, 7, 18, 11, 49, - 19, 20, 21, 28, 19, 20, 21, 12, 22, 5, - 13, 17, 22, 50, 46, 47, 39, 40, 41, 42, - 43, 44, 58, 59, 60, 61, 62, 63, 52, 53, - 54, 55, 56, 57, 30, 64, 0, 15 + 33, 29, 7, 19, 20, 21, 30, 3, 4, 4, + 1, 22, 9, 7, 48, 49, 5, 34, 35, 36, + 37, 38, 39, 40, 5, 5, 18, 50, 13, 19, + 20, 21, 47, 31, 32, 11, 12, 22, 5, 10, + 51, 23, 32, 17, 31, 32, 52, 14, 66, 16, + 41, 42, 43, 44, 45, 46, 60, 61, 62, 63, + 64, 65, 54, 55, 56, 57, 58, 59, 15 }; #define yypact_value_is_default(yystate) \ - ((yystate) == (-20)) + ((yystate) == (-18)) #define yytable_value_is_error(yytable_value) \ YYID (0) -static const yytype_int8 yycheck[] = +static const yytype_uint8 yycheck[] = { - 8, 10, 3, 22, 23, 3, 0, 4, 5, 5, - 11, 21, 13, 22, 23, 1, 11, 25, 26, 27, - 28, 29, 30, 31, 21, 21, 12, 9, 4, 24, - 12, 13, 14, 18, 12, 13, 14, 6, 20, 21, - 7, 15, 20, 20, 29, 30, 26, 27, 28, 29, - 30, 31, 39, 40, 41, 42, 43, 44, 33, 34, - 35, 36, 37, 38, 23, 11, -1, 12 + 8, 18, 1, 12, 13, 14, 23, 4, 5, 5, + 3, 20, 0, 12, 31, 32, 21, 25, 26, 27, + 28, 29, 30, 31, 21, 21, 9, 11, 7, 12, + 13, 14, 10, 22, 23, 4, 6, 20, 21, 3, + 24, 24, 23, 15, 22, 23, 20, 11, 11, 13, + 26, 27, 28, 29, 30, 31, 41, 42, 43, 44, + 45, 46, 35, 36, 37, 38, 39, 40, 12 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -774,11 +774,11 @@ static const yytype_uint8 yystos[] = { 0, 3, 33, 4, 5, 21, 34, 35, 36, 0, 36, 4, 6, 7, 36, 34, 36, 15, 9, 12, - 13, 14, 20, 35, 37, 38, 40, 41, 38, 22, - 23, 8, 25, 26, 27, 28, 29, 30, 31, 26, - 27, 28, 29, 30, 31, 10, 38, 38, 11, 24, - 20, 39, 41, 41, 41, 41, 41, 41, 40, 40, - 40, 40, 40, 40, 11 + 13, 14, 20, 24, 35, 37, 38, 40, 41, 38, + 38, 22, 23, 8, 25, 26, 27, 28, 29, 30, + 31, 26, 27, 28, 29, 30, 31, 10, 38, 38, + 11, 24, 20, 39, 41, 41, 41, 41, 41, 41, + 40, 40, 40, 40, 40, 40, 11 }; #define yyerrok (yyerrstatus = 0) @@ -1766,7 +1766,7 @@ yyreduce: /* Line 1806 of yacc.c */ #line 322 "wql.y" { - (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_EQ, (yyvsp[(3) - (3)].expr) ); + (yyval.expr) = expr_unary( ctx, (yyvsp[(2) - (2)].expr), OP_NOT ); if (!(yyval.expr)) YYABORT; } @@ -1777,7 +1777,7 @@ yyreduce: /* Line 1806 of yacc.c */ #line 328 "wql.y" { - (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_GT, (yyvsp[(3) - (3)].expr) ); + (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_EQ, (yyvsp[(3) - (3)].expr) ); if (!(yyval.expr)) YYABORT; } @@ -1788,7 +1788,7 @@ yyreduce: /* Line 1806 of yacc.c */ #line 334 "wql.y" { - (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_LT, (yyvsp[(3) - (3)].expr) ); + (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_GT, (yyvsp[(3) - (3)].expr) ); if (!(yyval.expr)) YYABORT; } @@ -1799,7 +1799,7 @@ yyreduce: /* Line 1806 of yacc.c */ #line 340 "wql.y" { - (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_LE, (yyvsp[(3) - (3)].expr) ); + (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_LT, (yyvsp[(3) - (3)].expr) ); if (!(yyval.expr)) YYABORT; } @@ -1810,7 +1810,7 @@ yyreduce: /* Line 1806 of yacc.c */ #line 346 "wql.y" { - (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_GE, (yyvsp[(3) - (3)].expr) ); + (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_LE, (yyvsp[(3) - (3)].expr) ); if (!(yyval.expr)) YYABORT; } @@ -1821,7 +1821,7 @@ yyreduce: /* Line 1806 of yacc.c */ #line 352 "wql.y" { - (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_NE, (yyvsp[(3) - (3)].expr) ); + (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_GE, (yyvsp[(3) - (3)].expr) ); if (!(yyval.expr)) YYABORT; } @@ -1832,7 +1832,7 @@ yyreduce: /* Line 1806 of yacc.c */ #line 358 "wql.y" { - (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_EQ, (yyvsp[(3) - (3)].expr) ); + (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_NE, (yyvsp[(3) - (3)].expr) ); if (!(yyval.expr)) YYABORT; } @@ -1843,7 +1843,7 @@ yyreduce: /* Line 1806 of yacc.c */ #line 364 "wql.y" { - (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_GT, (yyvsp[(3) - (3)].expr) ); + (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_EQ, (yyvsp[(3) - (3)].expr) ); if (!(yyval.expr)) YYABORT; } @@ -1854,7 +1854,7 @@ yyreduce: /* Line 1806 of yacc.c */ #line 370 "wql.y" { - (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_LT, (yyvsp[(3) - (3)].expr) ); + (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_GT, (yyvsp[(3) - (3)].expr) ); if (!(yyval.expr)) YYABORT; } @@ -1865,7 +1865,7 @@ yyreduce: /* Line 1806 of yacc.c */ #line 376 "wql.y" { - (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_LE, (yyvsp[(3) - (3)].expr) ); + (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_LT, (yyvsp[(3) - (3)].expr) ); if (!(yyval.expr)) YYABORT; } @@ -1876,7 +1876,7 @@ yyreduce: /* Line 1806 of yacc.c */ #line 382 "wql.y" { - (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_GE, (yyvsp[(3) - (3)].expr) ); + (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_LE, (yyvsp[(3) - (3)].expr) ); if (!(yyval.expr)) YYABORT; } @@ -1887,7 +1887,7 @@ yyreduce: /* Line 1806 of yacc.c */ #line 388 "wql.y" { - (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_NE, (yyvsp[(3) - (3)].expr) ); + (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_GE, (yyvsp[(3) - (3)].expr) ); if (!(yyval.expr)) YYABORT; } @@ -1898,7 +1898,7 @@ yyreduce: /* Line 1806 of yacc.c */ #line 394 "wql.y" { - (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_LIKE, (yyvsp[(3) - (3)].expr) ); + (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_NE, (yyvsp[(3) - (3)].expr) ); if (!(yyval.expr)) YYABORT; } @@ -1909,7 +1909,7 @@ yyreduce: /* Line 1806 of yacc.c */ #line 400 "wql.y" { - (yyval.expr) = expr_unary( ctx, (yyvsp[(1) - (3)].expr), OP_ISNULL ); + (yyval.expr) = expr_complex( ctx, (yyvsp[(1) - (3)].expr), OP_LIKE, (yyvsp[(3) - (3)].expr) ); if (!(yyval.expr)) YYABORT; } @@ -1920,7 +1920,7 @@ yyreduce: /* Line 1806 of yacc.c */ #line 406 "wql.y" { - (yyval.expr) = expr_unary( ctx, (yyvsp[(1) - (4)].expr), OP_NOTNULL ); + (yyval.expr) = expr_unary( ctx, (yyvsp[(1) - (3)].expr), OP_ISNULL ); if (!(yyval.expr)) YYABORT; } @@ -1929,9 +1929,9 @@ yyreduce: case 30: /* Line 1806 of yacc.c */ -#line 415 "wql.y" +#line 412 "wql.y" { - (yyval.expr) = expr_sval( ctx, &(yyvsp[(1) - (1)].str) ); + (yyval.expr) = expr_unary( ctx, (yyvsp[(1) - (4)].expr), OP_NOTNULL ); if (!(yyval.expr)) YYABORT; } @@ -1940,9 +1940,9 @@ yyreduce: case 31: /* Line 1806 of yacc.c */ -#line 424 "wql.y" +#line 421 "wql.y" { - (yyval.expr) = expr_propval( ctx, (yyvsp[(1) - (1)].proplist) ); + (yyval.expr) = expr_sval( ctx, &(yyvsp[(1) - (1)].str) ); if (!(yyval.expr)) YYABORT; } @@ -1951,9 +1951,9 @@ yyreduce: case 32: /* Line 1806 of yacc.c */ -#line 433 "wql.y" +#line 430 "wql.y" { - (yyval.expr) = expr_ival( ctx, (yyvsp[(1) - (1)].integer) ); + (yyval.expr) = expr_propval( ctx, (yyvsp[(1) - (1)].proplist) ); if (!(yyval.expr)) YYABORT; } @@ -1964,7 +1964,7 @@ yyreduce: /* Line 1806 of yacc.c */ #line 439 "wql.y" { - (yyval.expr) = expr_sval( ctx, &(yyvsp[(1) - (1)].str) ); + (yyval.expr) = expr_ival( ctx, (yyvsp[(1) - (1)].integer) ); if (!(yyval.expr)) YYABORT; } @@ -1975,7 +1975,7 @@ yyreduce: /* Line 1806 of yacc.c */ #line 445 "wql.y" { - (yyval.expr) = expr_bval( ctx, -1 ); + (yyval.expr) = expr_sval( ctx, &(yyvsp[(1) - (1)].str) ); if (!(yyval.expr)) YYABORT; } @@ -1985,6 +1985,17 @@ yyreduce: /* Line 1806 of yacc.c */ #line 451 "wql.y" + { + (yyval.expr) = expr_bval( ctx, -1 ); + if (!(yyval.expr)) + YYABORT; + } + break; + + case 36: + +/* Line 1806 of yacc.c */ +#line 457 "wql.y" { (yyval.expr) = expr_bval( ctx, 0 ); if (!(yyval.expr)) @@ -1995,7 +2006,7 @@ yyreduce: /* Line 1806 of yacc.c */ -#line 2011 "wql.tab.c" +#line 2022 "wql.tab.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -2226,7 +2237,7 @@ yyreturn: /* Line 2067 of yacc.c */ -#line 458 "wql.y" +#line 464 "wql.y" HRESULT parse_query( const WCHAR *str, struct view **view, struct list *mem ) diff --git a/dll/win32/wbemprox/wql.y b/dll/win32/wbemprox/wql.y index 58663d0d8b8..6eabe19e1ef 100644 --- a/dll/win32/wbemprox/wql.y +++ b/dll/win32/wbemprox/wql.y @@ -318,6 +318,12 @@ expr: if (!$$) YYABORT; } + | TK_NOT expr + { + $$ = expr_unary( ctx, $2, OP_NOT ); + if (!$$) + YYABORT; + } | prop_val TK_EQ const_val { $$ = expr_complex( ctx, $1, OP_EQ, $3 ); diff --git a/dll/win32/winhttp/cookie.c b/dll/win32/winhttp/cookie.c index e340dbedc5d..7ada9546110 100644 --- a/dll/win32/winhttp/cookie.c +++ b/dll/win32/winhttp/cookie.c @@ -122,10 +122,6 @@ static cookie_t *parse_cookie( const WCHAR *string ) const WCHAR *p; int len; - if (!(cookie = heap_alloc_zero( sizeof(cookie_t) ))) return NULL; - - list_init( &cookie->entry ); - if (!(p = strchrW( string, '=' ))) { WARN("no '=' in %s\n", debugstr_w(string)); @@ -136,6 +132,11 @@ static cookie_t *parse_cookie( const WCHAR *string ) WARN("empty cookie name in %s\n", debugstr_w(string)); return NULL; } + + if (!(cookie = heap_alloc_zero( sizeof(cookie_t) ))) return NULL; + + list_init( &cookie->entry ); + len = p - string; if (!(cookie->name = heap_alloc( (len + 1) * sizeof(WCHAR) ))) { diff --git a/dll/win32/winhttp/main.c b/dll/win32/winhttp/main.c index 1707a345e91..60625fac2af 100644 --- a/dll/win32/winhttp/main.c +++ b/dll/win32/winhttp/main.c @@ -42,7 +42,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) return TRUE; } -typedef HRESULT (*fnCreateInstance)( IUnknown *outer, void **obj ); +typedef HRESULT (*fnCreateInstance)( void **obj ); struct winhttp_cf { @@ -99,14 +99,11 @@ static HRESULT WINAPI requestcf_CreateInstance( if (outer) return CLASS_E_NOAGGREGATION; - hr = cf->pfnCreateInstance( outer, (void **)&unknown ); + hr = cf->pfnCreateInstance( (void **)&unknown ); if (FAILED(hr)) return hr; hr = IUnknown_QueryInterface( unknown, riid, obj ); - if (FAILED(hr)) - return hr; - IUnknown_Release( unknown ); return hr; } diff --git a/dll/win32/winhttp/net.c b/dll/win32/winhttp/net.c index 0f5dc7f0d35..225442dec47 100644 --- a/dll/win32/winhttp/net.c +++ b/dll/win32/winhttp/net.c @@ -705,24 +705,23 @@ BOOL netconn_recv( netconn_t *conn, void *buf, size_t len, int flags, int *recvd return TRUE; } -BOOL netconn_query_data_available( netconn_t *conn, DWORD *available ) +ULONG netconn_query_data_available( netconn_t *conn ) { -#ifdef FIONREAD - int ret; - ULONG unread; -#endif - *available = 0; - if (!netconn_connected( conn )) return FALSE; + if(!netconn_connected(conn)) + return 0; - if (conn->secure) - { - *available = conn->peek_len; - return TRUE; - } + if(conn->secure) { + return conn->peek_len; + }else { #ifdef FIONREAD - if (!(ret = ioctlsocket( conn->socket, FIONREAD, &unread ))) *available = unread; + ULONG unread; + + if(!ioctlsocket(conn->socket, FIONREAD, &unread)) + return unread; #endif - return TRUE; + } + + return 0; } DWORD netconn_set_timeout( netconn_t *netconn, BOOL send, int value ) diff --git a/dll/win32/winhttp/request.c b/dll/win32/winhttp/request.c index fd113d44b43..e1e650bdfb7 100644 --- a/dll/win32/winhttp/request.c +++ b/dll/win32/winhttp/request.c @@ -25,6 +25,7 @@ # include #endif +#include #include #include @@ -852,7 +853,7 @@ static LPWSTR build_header_request_string( request_t *request, LPCWSTR verb, /* * Set (header) termination string for request - * Make sure there's exactly two new lines at the end of the request + * Make sure there are exactly two new lines at the end of the request */ p = &requestString[strlenW(requestString)-1]; while ( (*p == '\n') || (*p == '\r') ) @@ -995,6 +996,8 @@ static BOOL open_connection( request_t *request ) done: request->read_pos = request->read_size = 0; request->read_chunked = FALSE; + request->read_chunked_size = ~0u; + request->read_chunked_eof = FALSE; heap_free( addressW ); return TRUE; } @@ -1121,7 +1124,7 @@ static BOOL send_request( request_t *request, LPCWSTR headers, DWORD headers_len request->optional_len = optional_len; len += optional_len; } - send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_REQUEST_SENT, &len, sizeof(DWORD) ); + send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_REQUEST_SENT, &len, sizeof(len) ); end: if (async) @@ -1374,7 +1377,7 @@ static unsigned int decode_base64( const WCHAR *base64, unsigned int len, char * char c0, c1, c2, c3; const WCHAR *p = base64; - while (len >= 4) + while (len > 4) { if ((c0 = decode_char( p[0] )) > 63) return 0; if ((c1 = decode_char( p[1] )) > 63) return 0; @@ -1412,6 +1415,21 @@ static unsigned int decode_base64( const WCHAR *base64, unsigned int len, char * } i += 2; } + else + { + if ((c0 = decode_char( p[0] )) > 63) return 0; + if ((c1 = decode_char( p[1] )) > 63) return 0; + if ((c2 = decode_char( p[2] )) > 63) return 0; + if ((c3 = decode_char( p[3] )) > 63) return 0; + + if (buf) + { + buf[i + 0] = (c0 << 2) | (c1 >> 4); + buf[i + 1] = (c1 << 4) | (c2 >> 2); + buf[i + 2] = (c2 << 6) | c3; + } + i += 3; + } return i; } @@ -1600,7 +1618,11 @@ static BOOL do_authorization( request_t *request, DWORD target, DWORD scheme_fla { int len = strlenW( ++p ); in.cbBuffer = decode_base64( p, len, NULL ); - if (!(in.pvBuffer = heap_alloc( in.cbBuffer ))) return FALSE; + if (!(in.pvBuffer = heap_alloc( in.cbBuffer ))) { + destroy_authinfo( authinfo ); + *auth_ptr = NULL; + return FALSE; + } decode_base64( p, len, in.pvBuffer ); } out.BufferType = SECBUFFER_TOKEN; @@ -1608,6 +1630,8 @@ static BOOL do_authorization( request_t *request, DWORD target, DWORD scheme_fla if (!(out.pvBuffer = heap_alloc( authinfo->max_token ))) { heap_free( in.pvBuffer ); + destroy_authinfo( authinfo ); + *auth_ptr = NULL; return FALSE; } out_desc.ulVersion = 0; @@ -1783,15 +1807,20 @@ static DWORD set_content_length( request_t *request ) { request->content_length = ~0u; request->read_chunked = TRUE; + request->read_chunked_size = ~0u; + request->read_chunked_eof = FALSE; } request->content_read = 0; return request->content_length; } /* read some more data into the read buffer */ -static BOOL read_more_data( request_t *request, int maxlen ) +static BOOL read_more_data( request_t *request, int maxlen, BOOL notify ) { int len; + BOOL ret; + + if (request->read_chunked_eof) return FALSE; if (request->read_size && request->read_pos) { @@ -1800,10 +1829,16 @@ static BOOL read_more_data( request_t *request, int maxlen ) request->read_pos = 0; } if (maxlen == -1) maxlen = sizeof(request->read_buf); - if (!netconn_recv( &request->netconn, request->read_buf + request->read_size, - maxlen - request->read_size, 0, &len )) return FALSE; + + if (notify) send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE, NULL, 0 ); + + ret = netconn_recv( &request->netconn, request->read_buf + request->read_size, + maxlen - request->read_size, 0, &len ); + + if (notify) send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED, &len, sizeof(len) ); + request->read_size += len; - return TRUE; + return ret; } /* remove some amount of data from the read buffer */ @@ -1833,7 +1868,7 @@ static BOOL read_line( request_t *request, char *buffer, DWORD *len ) remove_data( request, bytes_read ); if (eol) break; - if (!read_more_data( request, -1 )) return FALSE; + if (!read_more_data( request, -1, TRUE )) return FALSE; if (!request->read_size) { *len = 0; @@ -1852,7 +1887,7 @@ static BOOL read_line( request_t *request, char *buffer, DWORD *len ) } /* discard data contents until we reach end of line */ -static BOOL discard_eol( request_t *request ) +static BOOL discard_eol( request_t *request, BOOL notify ) { do { @@ -1863,24 +1898,23 @@ static BOOL discard_eol( request_t *request ) break; } request->read_pos = request->read_size = 0; /* discard everything */ - if (!read_more_data( request, -1 )) return FALSE; + if (!read_more_data( request, -1, notify )) return FALSE; } while (request->read_size); return TRUE; } /* read the size of the next chunk */ -static BOOL start_next_chunk( request_t *request ) +static BOOL start_next_chunk( request_t *request, BOOL notify ) { DWORD chunk_size = 0; - if (!request->content_length) return TRUE; - if (request->content_length == request->content_read) - { - /* read terminator for the previous chunk */ - if (!discard_eol( request )) return FALSE; - request->content_length = ~0u; - request->content_read = 0; - } + assert(!request->read_chunked_size || request->read_chunked_size == ~0u); + + if (request->read_chunked_eof) return FALSE; + + /* read terminator for the previous chunk */ + if (!request->read_chunked_size && !discard_eol( request, notify )) return FALSE; + for (;;) { while (request->read_size) @@ -1892,17 +1926,22 @@ static BOOL start_next_chunk( request_t *request ) else if (ch == ';' || ch == '\r' || ch == '\n') { TRACE("reading %u byte chunk\n", chunk_size); - request->content_length = chunk_size; - request->content_read = 0; - if (!discard_eol( request )) return FALSE; - return TRUE; + + if (request->content_length == ~0u) request->content_length = chunk_size; + else request->content_length += chunk_size; + + request->read_chunked_size = chunk_size; + if (!chunk_size) request->read_chunked_eof = TRUE; + + return discard_eol( request, notify ); } remove_data( request, 1 ); } - if (!read_more_data( request, -1 )) return FALSE; + if (!read_more_data( request, -1, notify )) return FALSE; if (!request->read_size) { request->content_length = request->content_read = 0; + request->read_chunked_size = 0; return TRUE; } } @@ -1911,32 +1950,34 @@ static BOOL start_next_chunk( request_t *request ) /* return the size of data available to be read immediately */ static DWORD get_available_data( request_t *request ) { - if (request->read_chunked && - (request->content_length == ~0u || request->content_length == request->content_read)) - return 0; - return min( request->read_size, request->content_length - request->content_read ); + if (request->read_chunked) return min( request->read_chunked_size, request->read_size ); + return request->read_size; } /* check if we have reached the end of the data to read */ static BOOL end_of_read_data( request_t *request ) { - if (request->read_chunked) return (request->content_length == 0); + if (request->read_chunked) return request->read_chunked_eof; if (request->content_length == ~0u) return FALSE; return (request->content_length == request->content_read); } -static BOOL refill_buffer( request_t *request ) +static BOOL refill_buffer( request_t *request, BOOL notify ) { int len = sizeof(request->read_buf); - if (request->read_chunked && - (request->content_length == ~0u || request->content_length == request->content_read)) + if (request->read_chunked) { - if (!start_next_chunk( request )) return FALSE; + if (request->read_chunked_eof) return FALSE; + if (request->read_chunked_size == ~0u || !request->read_chunked_size) + { + if (!start_next_chunk( request, notify )) return FALSE; + } } - if (request->content_length != ~0u) len = min( len, request->content_length - request->content_read ); + if (!request->read_chunked && request->content_length != ~0u) + len = min( len, request->content_length - request->content_read ); if (len <= request->read_size) return TRUE; - if (!read_more_data( request, len )) return FALSE; + if (!read_more_data( request, len, notify )) return FALSE; if (!request->read_size) request->content_length = request->content_read = 0; return TRUE; } @@ -1956,8 +1997,6 @@ static BOOL read_reply( request_t *request ) if (!netconn_connected( &request->netconn )) return FALSE; - send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE, NULL, 0 ); - received_len = 0; do { @@ -2013,7 +2052,7 @@ static BOOL read_reply( request_t *request ) header_t *header; buflen = MAX_REPLY_LEN; - if (!read_line( request, buffer, &buflen )) goto end; + if (!read_line( request, buffer, &buflen )) return TRUE; received_len += buflen; if (!*buffer) break; @@ -2038,9 +2077,6 @@ static BOOL read_reply( request_t *request ) } TRACE("raw headers: %s\n", debugstr_w(raw_headers)); - -end: - send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED, &received_len, sizeof(DWORD) ); return TRUE; } @@ -2064,46 +2100,35 @@ static void finished_reading( request_t *request ) static BOOL read_data( request_t *request, void *buffer, DWORD size, DWORD *read, BOOL async ) { - BOOL ret = TRUE; - int len, bytes_read = 0; + int count, bytes_read = 0; - if (request->read_chunked && - (request->content_length == ~0u || request->content_length == request->content_read)) - { - if (!start_next_chunk( request )) goto done; - } - if (request->content_length != ~0u) size = min( size, request->content_length - request->content_read ); + if (end_of_read_data( request )) goto done; - if (request->read_size) + while (size) { - bytes_read = min( request->read_size, size ); - memcpy( buffer, request->read_buf + request->read_pos, bytes_read ); - remove_data( request, bytes_read ); - } - if (size > bytes_read && (!bytes_read || !async)) - { - if ((ret = netconn_recv( &request->netconn, (char *)buffer + bytes_read, size - bytes_read, - async ? 0 : MSG_WAITALL, &len ))) - bytes_read += len; + if (!(count = get_available_data( request ))) + { + if (!refill_buffer( request, async )) goto done; + if (!(count = get_available_data( request ))) goto done; + } + count = min( count, size ); + memcpy( (char *)buffer + bytes_read, request->read_buf + request->read_pos, count ); + remove_data( request, count ); + if (request->read_chunked) request->read_chunked_size -= count; + size -= count; + bytes_read += count; + request->content_read += count; + if (end_of_read_data( request )) goto done; } + if (request->read_chunked && !request->read_chunked_size) refill_buffer( request, async ); done: - request->content_read += bytes_read; TRACE( "retrieved %u bytes (%u/%u)\n", bytes_read, request->content_read, request->content_length ); - if (async) - { - if (ret) send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_READ_COMPLETE, buffer, bytes_read ); - else - { - WINHTTP_ASYNC_RESULT result; - result.dwResult = API_READ_DATA; - result.dwError = get_last_error(); - send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_REQUEST_ERROR, &result, sizeof(result) ); - } - } + + if (async) send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_READ_COMPLETE, buffer, bytes_read ); if (read) *read = bytes_read; - if (!bytes_read && request->content_read == request->content_length) finished_reading( request ); - return ret; + if (end_of_read_data( request )) finished_reading( request ); + return TRUE; } /* read any content returned by the server so that the connection can be reused */ @@ -2112,11 +2137,6 @@ static void drain_content( request_t *request ) DWORD bytes_read; char buffer[2048]; - if (request->content_length == ~0u) - { - finished_reading( request ); - return; - } for (;;) { if (!read_data( request, buffer, sizeof(buffer), &bytes_read, FALSE ) || !bytes_read) return; @@ -2218,6 +2238,7 @@ static BOOL handle_redirect( request_t *request, DWORD status ) if (!(ret = netconn_init( &request->netconn ))) goto end; request->read_pos = request->read_size = 0; request->read_chunked = FALSE; + request->read_chunked_eof = FALSE; } if (!(ret = add_host_header( request, WINHTTP_ADDREQ_FLAG_REPLACE ))) goto end; if (!(ret = open_connection( request ))) goto end; @@ -2300,6 +2321,8 @@ static BOOL receive_response( request_t *request, BOOL async ) break; } + if (ret) refill_buffer( request, FALSE ); + if (async) { if (ret) send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE, NULL, 0 ); @@ -2362,45 +2385,22 @@ BOOL WINAPI WinHttpReceiveResponse( HINTERNET hrequest, LPVOID reserved ) static BOOL query_data_available( request_t *request, DWORD *available, BOOL async ) { - BOOL ret = TRUE; - DWORD count; + DWORD count = get_available_data( request ); - if (!(count = get_available_data( request ))) + if (!request->read_chunked) + count += netconn_query_data_available( &request->netconn ); + if (!count) { - if (end_of_read_data( request )) - { - if (available) *available = 0; - return TRUE; - } + refill_buffer( request, async ); + count = get_available_data( request ); + if (!request->read_chunked) + count += netconn_query_data_available( &request->netconn ); } - refill_buffer( request ); - count = get_available_data( request ); - if (count == sizeof(request->read_buf)) /* check if we have even more pending in the socket */ - { - DWORD extra; - if ((ret = netconn_query_data_available( &request->netconn, &extra ))) - { - count = min( count + extra, request->content_length - request->content_read ); - } - } - if (async) - { - if (ret) send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE, &count, sizeof(count) ); - else - { - WINHTTP_ASYNC_RESULT result; - result.dwResult = API_QUERY_DATA_AVAILABLE; - result.dwError = get_last_error(); - send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_REQUEST_ERROR, &result, sizeof(result) ); - } - } - if (ret) - { - TRACE("%u bytes available\n", count); - if (available) *available = count; - } - return ret; + if (async) send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE, &count, sizeof(count) ); + TRACE("%u bytes available\n", count); + if (available) *available = count; + return TRUE; } static void task_query_data_available( task_header_t *task ) @@ -2508,7 +2508,7 @@ static BOOL write_data( request_t *request, LPCVOID buffer, DWORD to_write, LPDW if (async) { - if (ret) send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE, &num_bytes, sizeof(DWORD) ); + if (ret) send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE, &num_bytes, sizeof(num_bytes) ); else { WINHTTP_ASYNC_RESULT result; @@ -3810,11 +3810,11 @@ static const struct IWinHttpRequestVtbl winhttp_request_vtbl = winhttp_request_SetAutoLogonPolicy }; -HRESULT WinHttpRequest_create( IUnknown *unknown, void **obj ) +HRESULT WinHttpRequest_create( void **obj ) { struct winhttp_request *request; - TRACE("%p, %p\n", unknown, obj); + TRACE("%p\n", obj); if (!(request = heap_alloc( sizeof(*request) ))) return E_OUTOFMEMORY; request->IWinHttpRequest_iface.lpVtbl = &winhttp_request_vtbl; diff --git a/dll/win32/winhttp/session.c b/dll/win32/winhttp/session.c index 9f23a8d5196..789397e0033 100644 --- a/dll/win32/winhttp/session.c +++ b/dll/win32/winhttp/session.c @@ -1354,7 +1354,11 @@ BOOL WINAPI WinHttpDetectAutoProxyConfigUrl( DWORD flags, LPWSTR *url ) FIXME("getaddrinfo not found at build time\n"); #endif } - if (!ret) set_last_error( ERROR_WINHTTP_AUTODETECTION_FAILED ); + if (!ret) + { + set_last_error( ERROR_WINHTTP_AUTODETECTION_FAILED ); + *url = NULL; + } return ret; } @@ -1597,11 +1601,11 @@ done: heap_free( hdr ); if (!ret) { - heap_free( config->lpszAutoConfigUrl ); + GlobalFree( config->lpszAutoConfigUrl ); config->lpszAutoConfigUrl = NULL; - heap_free( config->lpszProxy ); + GlobalFree( config->lpszProxy ); config->lpszProxy = NULL; - heap_free( config->lpszProxyBypass ); + GlobalFree( config->lpszProxyBypass ); config->lpszProxyBypass = NULL; } return ret; diff --git a/dll/win32/winhttp/winhttp_private.h b/dll/win32/winhttp/winhttp_private.h index e1ca4a79313..af66a286d35 100644 --- a/dll/win32/winhttp/winhttp_private.h +++ b/dll/win32/winhttp/winhttp_private.h @@ -202,9 +202,11 @@ typedef struct int send_timeout; int recv_timeout; LPWSTR status_text; - DWORD content_length; /* total number of bytes to be read (per chunk) */ + DWORD content_length; /* total number of bytes to be read */ DWORD content_read; /* bytes read so far */ BOOL read_chunked; /* are we reading in chunked mode? */ + BOOL read_chunked_eof; /* end of stream in chunked mode */ + BOOL read_chunked_size; /* chunk size remaining */ DWORD read_pos; /* current read position in read_buf */ DWORD read_size; /* valid data size in read_buf */ char read_buf[4096]; /* buffer for already read but not returned data */ @@ -279,7 +281,7 @@ BOOL netconn_connected( netconn_t * ) DECLSPEC_HIDDEN; BOOL netconn_create( netconn_t *, int, int, int ) DECLSPEC_HIDDEN; BOOL netconn_init( netconn_t * ) DECLSPEC_HIDDEN; void netconn_unload( void ) DECLSPEC_HIDDEN; -BOOL netconn_query_data_available( netconn_t *, DWORD * ) DECLSPEC_HIDDEN; +ULONG netconn_query_data_available( netconn_t * ) DECLSPEC_HIDDEN; BOOL netconn_recv( netconn_t *, void *, size_t, int, int * ) DECLSPEC_HIDDEN; BOOL netconn_resolve( WCHAR *, INTERNET_PORT, struct sockaddr *, socklen_t *, int ) DECLSPEC_HIDDEN; BOOL netconn_secure_connect( netconn_t *, WCHAR * ) DECLSPEC_HIDDEN; @@ -295,7 +297,7 @@ void delete_domain( domain_t * ) DECLSPEC_HIDDEN; BOOL set_server_for_hostname( connect_t *, LPCWSTR, INTERNET_PORT ) DECLSPEC_HIDDEN; void destroy_authinfo( struct authinfo * ) DECLSPEC_HIDDEN; -extern HRESULT WinHttpRequest_create( IUnknown *, void ** ) DECLSPEC_HIDDEN; +extern HRESULT WinHttpRequest_create( void ** ) DECLSPEC_HIDDEN; static inline const char *debugstr_variant( const VARIANT *v ) { diff --git a/dll/win32/winhttp/winhttp_tlb.idl b/dll/win32/winhttp/winhttp_tlb.idl index 74beb57e31e..673ee63e330 100644 --- a/dll/win32/winhttp/winhttp_tlb.idl +++ b/dll/win32/winhttp/winhttp_tlb.idl @@ -18,4 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma makedep regtypelib + #include "httprequest.idl" diff --git a/dll/win32/wininet/dialogs.c b/dll/win32/wininet/dialogs.c index 872022f82e8..b849d470cb7 100644 --- a/dll/win32/wininet/dialogs.c +++ b/dll/win32/wininet/dialogs.c @@ -433,7 +433,7 @@ static INT_PTR WINAPI WININET_InvalidCertificateDialog( /* FIXME: Use helper function */ flags |= SECURITY_FLAG_SECURE; req->security_flags |= flags; - if(req->netconn) + if(is_valid_netconn(req->netconn)) req->netconn->security_flags |= flags; } diff --git a/dll/win32/wininet/ftp.c b/dll/win32/wininet/ftp.c index 21d086342ef..df7becf2392 100644 --- a/dll/win32/wininet/ftp.c +++ b/dll/win32/wininet/ftp.c @@ -489,7 +489,7 @@ static BOOL FTP_FtpSetCurrentDirectoryW(ftp_session_t *lpwfs, LPCWSTR lpszDirect { INT nResCode; appinfo_t *hIC = NULL; - DWORD bSuccess = FALSE; + BOOL bSuccess = FALSE; TRACE("lpszDirectory(%s)\n", debugstr_w(lpszDirectory)); @@ -1004,7 +1004,7 @@ static BOOL FTP_FtpGetCurrentDirectoryW(ftp_session_t *lpwfs, LPWSTR lpszCurrent { INT nResCode; appinfo_t *hIC = NULL; - DWORD bSuccess = FALSE; + BOOL bSuccess = FALSE; /* Clear any error information */ INTERNET_SetLastError(0); @@ -1249,6 +1249,12 @@ static DWORD FTPFILE_QueryDataAvailable(object_header_t *hdr, DWORD *available, return ERROR_SUCCESS; } +static DWORD FTPFILE_LockRequestFile(object_header_t *hdr, req_file_t **ret) +{ + ftp_file_t *file = (ftp_file_t*)hdr; + FIXME("%p\n", file); + return ERROR_NOT_SUPPORTED; +} static const object_vtbl_t FTPFILEVtbl = { FTPFILE_Destroy, @@ -1259,7 +1265,8 @@ static const object_vtbl_t FTPFILEVtbl = { FTPFILE_ReadFileEx, FTPFILE_WriteFile, FTPFILE_QueryDataAvailable, - NULL + NULL, + FTPFILE_LockRequestFile }; /*********************************************************************** diff --git a/dll/win32/wininet/http.c b/dll/win32/wininet/http.c index 240533cc9bf..7e7bd33efab 100644 --- a/dll/win32/wininet/http.c +++ b/dll/win32/wininet/http.c @@ -351,16 +351,10 @@ static LPHTTPHEADERW HTTP_GetHeader(http_request_t *req, LPCWSTR head) return &req->custHeaders[HeaderIndex]; } -typedef enum { - READMODE_SYNC, - READMODE_ASYNC, - READMODE_NOBLOCK -} read_mode_t; - struct data_stream_vtbl_t { DWORD (*get_avail_data)(data_stream_t*,http_request_t*); BOOL (*end_of_data)(data_stream_t*,http_request_t*); - DWORD (*read)(data_stream_t*,http_request_t*,BYTE*,DWORD,DWORD*,read_mode_t); + DWORD (*read)(data_stream_t*,http_request_t*,BYTE*,DWORD,DWORD*,blocking_mode_t); BOOL (*drain_content)(data_stream_t*,http_request_t*); void (*destroy)(data_stream_t*); }; @@ -372,6 +366,7 @@ typedef struct { DWORD buf_size; DWORD buf_pos; DWORD chunk_size; + BOOL end_of_data; } chunked_stream_t; static inline void destroy_data_stream(data_stream_t *stream) @@ -408,47 +403,45 @@ static DWORD gzip_get_avail_data(data_stream_t *stream, http_request_t *req) static BOOL gzip_end_of_data(data_stream_t *stream, http_request_t *req) { gzip_stream_t *gzip_stream = (gzip_stream_t*)stream; - return gzip_stream->end_of_data; + return gzip_stream->end_of_data + || (!gzip_stream->buf_size && gzip_stream->parent_stream->vtbl->end_of_data(gzip_stream->parent_stream, req)); } static DWORD gzip_read(data_stream_t *stream, http_request_t *req, BYTE *buf, DWORD size, - DWORD *read, read_mode_t read_mode) + DWORD *read, blocking_mode_t blocking_mode) { gzip_stream_t *gzip_stream = (gzip_stream_t*)stream; z_stream *zstream = &gzip_stream->zstream; DWORD current_read, ret_read = 0; - BOOL end; int zres; DWORD res = ERROR_SUCCESS; - while(size && !gzip_stream->end_of_data) { - end = gzip_stream->parent_stream->vtbl->end_of_data(gzip_stream->parent_stream, req); + TRACE("(%d %d)\n", size, blocking_mode); - if(gzip_stream->buf_size <= 64 && !end) { + while(size && !gzip_stream->end_of_data) { + if(!gzip_stream->buf_size) { if(gzip_stream->buf_pos) { if(gzip_stream->buf_size) memmove(gzip_stream->buf, gzip_stream->buf+gzip_stream->buf_pos, gzip_stream->buf_size); gzip_stream->buf_pos = 0; } res = gzip_stream->parent_stream->vtbl->read(gzip_stream->parent_stream, req, gzip_stream->buf+gzip_stream->buf_size, - sizeof(gzip_stream->buf)-gzip_stream->buf_size, ¤t_read, read_mode); + sizeof(gzip_stream->buf)-gzip_stream->buf_size, ¤t_read, blocking_mode); gzip_stream->buf_size += current_read; if(res != ERROR_SUCCESS) break; - end = gzip_stream->parent_stream->vtbl->end_of_data(gzip_stream->parent_stream, req); - if(!current_read && !end) { - if(read_mode != READMODE_NOBLOCK) { + + if(!current_read) { + if(blocking_mode != BLOCKING_DISALLOW) { WARN("unexpected end of data\n"); gzip_stream->end_of_data = TRUE; } break; } - if(gzip_stream->buf_size <= 64 && !end) - continue; } zstream->next_in = gzip_stream->buf+gzip_stream->buf_pos; - zstream->avail_in = gzip_stream->buf_size-(end ? 0 : 64); + zstream->avail_in = gzip_stream->buf_size; zstream->next_out = buf+ret_read; zstream->avail_out = size; zres = inflate(&gzip_stream->zstream, 0); @@ -468,8 +461,8 @@ static DWORD gzip_read(data_stream_t *stream, http_request_t *req, BYTE *buf, DW break; } - if(ret_read && read_mode == READMODE_ASYNC) - read_mode = READMODE_NOBLOCK; + if(ret_read && blocking_mode == BLOCKING_ALLOW) + blocking_mode = BLOCKING_DISALLOW; } TRACE("read %u bytes\n", ret_read); @@ -512,7 +505,7 @@ static void wininet_zfree(voidpf opaque, voidpf address) heap_free(address); } -static DWORD init_gzip_stream(http_request_t *req) +static DWORD init_gzip_stream(http_request_t *req, BOOL is_gzip) { gzip_stream_t *gzip_stream; int index, zres; @@ -525,7 +518,7 @@ static DWORD init_gzip_stream(http_request_t *req) gzip_stream->zstream.zalloc = wininet_zalloc; gzip_stream->zstream.zfree = wininet_zfree; - zres = inflateInit2(&gzip_stream->zstream, 0x1f); + zres = inflateInit2(&gzip_stream->zstream, is_gzip ? 0x1f : -15); if(zres != Z_OK) { ERR("inflateInit failed: %d\n", zres); heap_free(gzip_stream); @@ -550,7 +543,7 @@ static DWORD init_gzip_stream(http_request_t *req) #else -static DWORD init_gzip_stream(http_request_t *req) +static DWORD init_gzip_stream(http_request_t *req, BOOL is_gzip) { ERR("gzip stream not supported, missing zlib.\n"); return ERROR_SUCCESS; @@ -1422,7 +1415,7 @@ HINTERNET WINAPI HttpOpenRequestA(HINTERNET hHttpSession, { LPWSTR szVerb = NULL, szObjectName = NULL; LPWSTR szVersion = NULL, szReferrer = NULL, *szAcceptTypes = NULL; - HINTERNET rc = FALSE; + HINTERNET rc = NULL; TRACE("(%p, %s, %s, %s, %s, %p, %08x, %08lx)\n", hHttpSession, debugstr_a(lpszVerb), debugstr_a(lpszObjectName), @@ -1883,11 +1876,10 @@ static void HTTPREQ_Destroy(object_header_t *hdr) TRACE("\n"); - if(request->hCacheFile) { + if(request->hCacheFile) CloseHandle(request->hCacheFile); - DeleteFileW(request->cacheFile); - } - heap_free(request->cacheFile); + if(request->req_file) + req_file_release(request->req_file); request->read_section.DebugInfo->Spare[0] = 0; DeleteCriticalSection( &request->read_section ); @@ -1917,9 +1909,9 @@ static void HTTPREQ_Destroy(object_header_t *hdr) static void http_release_netconn(http_request_t *req, BOOL reuse) { - TRACE("%p %p\n",req, req->netconn); + TRACE("%p %p %x\n",req, req->netconn, reuse); - if(!req->netconn) + if(!is_valid_netconn(req->netconn)) return; #ifndef __REACTOS__ @@ -1965,8 +1957,7 @@ static void http_release_netconn(http_request_t *req, BOOL reuse) INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_CLOSING_CONNECTION, 0, 0); - free_netconn(req->netconn); - req->netconn = NULL; + close_netconn(req->netconn); INTERNET_SendCallback(&req->hdr, req->hdr.dwContext, INTERNET_STATUS_CONNECTION_CLOSED, 0, 0); @@ -2069,7 +2060,7 @@ static DWORD HTTPREQ_QueryOption(object_header_t *hdr, DWORD option, void *buffe info->Flags |= IDSI_FLAG_KEEP_ALIVE; if (req->proxy) info->Flags |= IDSI_FLAG_PROXY; - if (req->netconn && req->netconn->secure) + if (is_valid_netconn(req->netconn) && req->netconn->secure) info->Flags |= IDSI_FLAG_SECURE; return ERROR_SUCCESS; @@ -2086,7 +2077,7 @@ static DWORD HTTPREQ_QueryOption(object_header_t *hdr, DWORD option, void *buffe return ERROR_INSUFFICIENT_BUFFER; *size = sizeof(DWORD); - flags = req->netconn ? req->netconn->security_flags : req->security_flags | req->server->security_flags; + flags = is_valid_netconn(req->netconn) ? req->netconn->security_flags : req->security_flags | req->server->security_flags; *(DWORD *)buffer = flags; TRACE("INTERNET_OPTION_SECURITY_FLAGS %x\n", flags); @@ -2170,25 +2161,25 @@ static DWORD HTTPREQ_QueryOption(object_header_t *hdr, DWORD option, void *buffe TRACE("INTERNET_OPTION_DATAFILE_NAME\n"); - if(!req->cacheFile) { + if(!req->req_file) { *size = 0; return ERROR_INTERNET_ITEM_NOT_FOUND; } if(unicode) { - req_size = (lstrlenW(req->cacheFile)+1) * sizeof(WCHAR); + req_size = (lstrlenW(req->req_file->file_name)+1) * sizeof(WCHAR); if(*size < req_size) return ERROR_INSUFFICIENT_BUFFER; *size = req_size; - memcpy(buffer, req->cacheFile, *size); + memcpy(buffer, req->req_file->file_name, *size); return ERROR_SUCCESS; }else { - req_size = WideCharToMultiByte(CP_ACP, 0, req->cacheFile, -1, NULL, 0, NULL, NULL); + req_size = WideCharToMultiByte(CP_ACP, 0, req->req_file->file_name, -1, NULL, 0, NULL, NULL); if (req_size > *size) return ERROR_INSUFFICIENT_BUFFER; - *size = WideCharToMultiByte(CP_ACP, 0, req->cacheFile, + *size = WideCharToMultiByte(CP_ACP, 0, req->req_file->file_name, -1, buffer, *size, NULL, NULL); return ERROR_SUCCESS; } @@ -2291,7 +2282,7 @@ static DWORD HTTPREQ_SetOption(object_header_t *hdr, DWORD option, void *buffer, TRACE("INTERNET_OPTION_SECURITY_FLAGS %08x\n", flags); flags &= SECURITY_SET_MASK; req->security_flags |= flags; - if(req->netconn) + if(is_valid_netconn(req->netconn)) req->netconn->security_flags |= flags; return ERROR_SUCCESS; } @@ -2352,12 +2343,17 @@ static void commit_cache_entry(http_request_t *req) if(HTTP_GetRequestURL(req, url)) { WCHAR *header; DWORD header_len; + BOOL res; header = build_response_header(req, TRUE); header_len = (header ? strlenW(header) : 0); - CommitUrlCacheEntryW(url, req->cacheFile, req->expires, + res = CommitUrlCacheEntryW(url, req->req_file->file_name, req->expires, req->last_modified, NORMAL_CACHE_ENTRY, header, header_len, NULL, 0); + if(res) + req->req_file->is_committed = TRUE; + else + WARN("CommitUrlCacheEntry failed: %u\n", GetLastError()); heap_free(header); } } @@ -2372,9 +2368,14 @@ static void create_cache_entry(http_request_t *req) BOOL b = TRUE; /* FIXME: We should free previous cache file earlier */ - heap_free(req->cacheFile); - CloseHandle(req->hCacheFile); - req->hCacheFile = NULL; + if(req->req_file) { + req_file_release(req->req_file); + req->req_file = NULL; + } + if(req->hCacheFile) { + CloseHandle(req->hCacheFile); + req->hCacheFile = NULL; + } if(req->hdr.dwFlags & INTERNET_FLAG_NO_CACHE_WRITE) b = FALSE; @@ -2426,8 +2427,9 @@ static void create_cache_entry(http_request_t *req) return; } - req->cacheFile = heap_strdupW(file_name); - req->hCacheFile = CreateFileW(req->cacheFile, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, + create_req_file(file_name, &req->req_file); + + req->hCacheFile = CreateFileW(file_name, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(req->hCacheFile == INVALID_HANDLE_VALUE) { WARN("Could not create file: %u\n", GetLastError()); @@ -2464,7 +2466,7 @@ static DWORD read_more_data( http_request_t *req, int maxlen ) if (maxlen == -1) maxlen = sizeof(req->read_buf); res = NETCON_recv( req->netconn, req->read_buf + req->read_size, - maxlen - req->read_size, 0, &len ); + maxlen - req->read_size, BLOCKING_ALLOW, &len ); if(res == ERROR_SUCCESS) req->read_size += len; @@ -2533,11 +2535,11 @@ static BOOL end_of_read_data( http_request_t *req ) return !req->read_size && req->data_stream->vtbl->end_of_data(req->data_stream, req); } -static DWORD read_http_stream(http_request_t *req, BYTE *buf, DWORD size, DWORD *read, read_mode_t read_mode) +static DWORD read_http_stream(http_request_t *req, BYTE *buf, DWORD size, DWORD *read, blocking_mode_t blocking_mode) { DWORD res; - res = req->data_stream->vtbl->read(req->data_stream, req, buf, size, read, read_mode); + res = req->data_stream->vtbl->read(req->data_stream, req, buf, size, read, blocking_mode); assert(*read <= size); if(req->hCacheFile) { @@ -2558,7 +2560,7 @@ static DWORD read_http_stream(http_request_t *req, BYTE *buf, DWORD size, DWORD } /* fetch some more data into the read buffer (the read section must be held) */ -static DWORD refill_read_buffer(http_request_t *req, read_mode_t read_mode, DWORD *read_bytes) +static DWORD refill_read_buffer(http_request_t *req, blocking_mode_t blocking_mode, DWORD *read_bytes) { DWORD res, read=0; @@ -2572,7 +2574,7 @@ static DWORD refill_read_buffer(http_request_t *req, read_mode_t read_mode, DWOR } res = read_http_stream(req, req->read_buf+req->read_size, sizeof(req->read_buf) - req->read_size, - &read, read_mode); + &read, blocking_mode); req->read_size += read; TRACE("read %u bytes, read_size %u\n", read, req->read_size); @@ -2592,7 +2594,7 @@ static DWORD netconn_get_avail_data(data_stream_t *stream, http_request_t *req) netconn_stream_t *netconn_stream = (netconn_stream_t*)stream; DWORD avail = 0; - if(req->netconn) + if(is_valid_netconn(req->netconn)) NETCON_query_data_available(req->netconn, &avail); return netconn_stream->content_length == ~0u ? avail @@ -2602,11 +2604,11 @@ static DWORD netconn_get_avail_data(data_stream_t *stream, http_request_t *req) static BOOL netconn_end_of_data(data_stream_t *stream, http_request_t *req) { netconn_stream_t *netconn_stream = (netconn_stream_t*)stream; - return netconn_stream->content_read == netconn_stream->content_length || !req->netconn; + return netconn_stream->content_read == netconn_stream->content_length || !is_valid_netconn(req->netconn); } static DWORD netconn_read(data_stream_t *stream, http_request_t *req, BYTE *buf, DWORD size, - DWORD *read, read_mode_t read_mode) + DWORD *read, blocking_mode_t blocking_mode) { netconn_stream_t *netconn_stream = (netconn_stream_t*)stream; DWORD res = ERROR_SUCCESS; @@ -2614,17 +2616,16 @@ static DWORD netconn_read(data_stream_t *stream, http_request_t *req, BYTE *buf, size = min(size, netconn_stream->content_length-netconn_stream->content_read); - if(read_mode == READMODE_NOBLOCK) { - DWORD avail = netconn_get_avail_data(stream, req); - if (size > avail) - size = avail; - } - - if(size && req->netconn) { - if((res = NETCON_recv(req->netconn, buf, size, read_mode == READMODE_SYNC ? MSG_WAITALL : 0, &len))) + if(size && is_valid_netconn(req->netconn)) { + if((res = NETCON_recv(req->netconn, buf, size, blocking_mode, &len))) { len = 0; - if(!len) + if(blocking_mode == BLOCKING_DISALLOW && res == WSAEWOULDBLOCK) + res = ERROR_SUCCESS; + else + netconn_stream->content_length = netconn_stream->content_read; + }else if(!len) { netconn_stream->content_length = netconn_stream->content_read; + } } netconn_stream->content_read += *read = len; @@ -2636,18 +2637,13 @@ static BOOL netconn_drain_content(data_stream_t *stream, http_request_t *req) { netconn_stream_t *netconn_stream = (netconn_stream_t*)stream; BYTE buf[1024]; - DWORD avail; int len; if(netconn_end_of_data(stream, req)) return TRUE; do { - avail = netconn_get_avail_data(stream, req); - if(!avail) - return FALSE; - - if(NETCON_recv(req->netconn, buf, min(avail, sizeof(buf)), 0, &len) != ERROR_SUCCESS) + if(NETCON_recv(req->netconn, buf, sizeof(buf), BLOCKING_DISALLOW, &len) != ERROR_SUCCESS) return FALSE; netconn_stream->content_read += len; @@ -2674,6 +2670,8 @@ static DWORD read_more_chunked_data(chunked_stream_t *stream, http_request_t *re DWORD res; int len; + assert(!stream->end_of_data); + if (stream->buf_pos) { /* move existing data to the start of the buffer */ @@ -2685,7 +2683,7 @@ static DWORD read_more_chunked_data(chunked_stream_t *stream, http_request_t *re if (maxlen == -1) maxlen = sizeof(stream->buf); res = NETCON_recv( req->netconn, stream->buf + stream->buf_size, - maxlen - stream->buf_size, 0, &len ); + maxlen - stream->buf_size, BLOCKING_ALLOW, &len ); if(res == ERROR_SUCCESS) stream->buf_size += len; @@ -2721,10 +2719,14 @@ static DWORD discard_chunked_eol(chunked_stream_t *stream, http_request_t *req) /* read the size of the next chunk (the read section must be held) */ static DWORD start_next_chunk(chunked_stream_t *stream, http_request_t *req) { - /* TODOO */ DWORD chunk_size = 0, res; - if(stream->chunk_size != ~0u && (res = discard_chunked_eol(stream, req)) != ERROR_SUCCESS) + assert(!stream->chunk_size || stream->chunk_size == ~0u); + + if (stream->end_of_data) return ERROR_SUCCESS; + + /* read terminator for the previous chunk */ + if(!stream->chunk_size && (res = discard_chunked_eol(stream, req)) != ERROR_SUCCESS) return res; for (;;) @@ -2739,7 +2741,10 @@ static DWORD start_next_chunk(chunked_stream_t *stream, http_request_t *req) { TRACE( "reading %u byte chunk\n", chunk_size ); stream->chunk_size = chunk_size; - req->contentLength += chunk_size; + if (req->contentLength == ~0u) req->contentLength = chunk_size; + else req->contentLength += chunk_size; + + if (!chunk_size) stream->end_of_data = TRUE; return discard_chunked_eol(stream, req); } remove_chunked_data(stream, 1); @@ -2762,27 +2767,27 @@ static DWORD chunked_get_avail_data(data_stream_t *stream, http_request_t *req) static BOOL chunked_end_of_data(data_stream_t *stream, http_request_t *req) { chunked_stream_t *chunked_stream = (chunked_stream_t*)stream; - return !chunked_stream->chunk_size; + return chunked_stream->end_of_data; } static DWORD chunked_read(data_stream_t *stream, http_request_t *req, BYTE *buf, DWORD size, - DWORD *read, read_mode_t read_mode) + DWORD *read, blocking_mode_t blocking_mode) { chunked_stream_t *chunked_stream = (chunked_stream_t*)stream; DWORD read_bytes = 0, ret_read = 0, res = ERROR_SUCCESS; - if(chunked_stream->chunk_size == ~0u) { + if(!chunked_stream->chunk_size || chunked_stream->chunk_size == ~0u) { res = start_next_chunk(chunked_stream, req); if(res != ERROR_SUCCESS) return res; } - while(size && chunked_stream->chunk_size) { + while(size && chunked_stream->chunk_size && !chunked_stream->end_of_data) { if(chunked_stream->buf_size) { read_bytes = min(size, min(chunked_stream->buf_size, chunked_stream->chunk_size)); /* this could block */ - if(read_mode == READMODE_NOBLOCK && read_bytes == chunked_stream->chunk_size) + if(blocking_mode == BLOCKING_DISALLOW && read_bytes == chunked_stream->chunk_size) break; memcpy(buf+ret_read, chunked_stream->buf+chunked_stream->buf_pos, read_bytes); @@ -2790,10 +2795,10 @@ static DWORD chunked_read(data_stream_t *stream, http_request_t *req, BYTE *buf, }else { read_bytes = min(size, chunked_stream->chunk_size); - if(read_mode == READMODE_NOBLOCK) { + if(blocking_mode == BLOCKING_DISALLOW) { DWORD avail; - if(!req->netconn || !NETCON_query_data_available(req->netconn, &avail) || !avail) + if(!is_valid_netconn(req->netconn) || !NETCON_query_data_available(req->netconn, &avail) || !avail) break; if(read_bytes > avail) read_bytes = avail; @@ -2803,7 +2808,7 @@ static DWORD chunked_read(data_stream_t *stream, http_request_t *req, BYTE *buf, break; } - res = NETCON_recv(req->netconn, (char *)buf+ret_read, read_bytes, 0, (int*)&read_bytes); + res = NETCON_recv(req->netconn, (char *)buf+ret_read, read_bytes, BLOCKING_ALLOW, (int*)&read_bytes); if(res != ERROR_SUCCESS) break; } @@ -2811,15 +2816,15 @@ static DWORD chunked_read(data_stream_t *stream, http_request_t *req, BYTE *buf, chunked_stream->chunk_size -= read_bytes; size -= read_bytes; ret_read += read_bytes; - if(!chunked_stream->chunk_size) { - assert(read_mode != READMODE_NOBLOCK); + if(size && !chunked_stream->chunk_size) { + assert(blocking_mode != BLOCKING_DISALLOW); res = start_next_chunk(chunked_stream, req); if(res != ERROR_SUCCESS) break; } - if(read_mode == READMODE_ASYNC) - read_mode = READMODE_NOBLOCK; + if(blocking_mode == BLOCKING_ALLOW) + blocking_mode = BLOCKING_DISALLOW; } TRACE("read %u bytes\n", ret_read); @@ -2831,8 +2836,8 @@ static BOOL chunked_drain_content(data_stream_t *stream, http_request_t *req) { chunked_stream_t *chunked_stream = (chunked_stream_t*)stream; - /* FIXME: we can do better */ - return !chunked_stream->chunk_size; + remove_chunked_data(chunked_stream, chunked_stream->buf_size); + return chunked_stream->end_of_data; } static void chunked_destroy(data_stream_t *stream) @@ -2881,6 +2886,7 @@ static DWORD set_content_length(http_request_t *request) chunked_stream->data_stream.vtbl = &chunked_stream_vtbl; chunked_stream->buf_size = chunked_stream->buf_pos = 0; chunked_stream->chunk_size = ~0u; + chunked_stream->end_of_data = FALSE; if(request->read_size) { memcpy(chunked_stream->buf, request->read_buf+request->read_pos, request->read_size); @@ -2896,12 +2902,19 @@ static DWORD set_content_length(http_request_t *request) if(request->decoding) { int encoding_idx; + static const WCHAR deflateW[] = {'d','e','f','l','a','t','e',0}; static const WCHAR gzipW[] = {'g','z','i','p',0}; encoding_idx = HTTP_GetCustomHeaderIndex(request, szContent_Encoding, 0, FALSE); - if(encoding_idx != -1 && !strcmpiW(request->custHeaders[encoding_idx].lpszValue, gzipW)) { - HTTP_DeleteCustomHeader(request, encoding_idx); - return init_gzip_stream(request); + if(encoding_idx != -1) { + if(!strcmpiW(request->custHeaders[encoding_idx].lpszValue, gzipW)) { + HTTP_DeleteCustomHeader(request, encoding_idx); + return init_gzip_stream(request, TRUE); + } + if(!strcmpiW(request->custHeaders[encoding_idx].lpszValue, deflateW)) { + HTTP_DeleteCustomHeader(request, encoding_idx); + return init_gzip_stream(request, FALSE); + } } } @@ -2922,20 +2935,20 @@ static void send_request_complete(http_request_t *req, DWORD_PTR result, DWORD e static void HTTP_ReceiveRequestData(http_request_t *req, BOOL first_notif, DWORD *ret_size) { DWORD res, read = 0, avail = 0; - read_mode_t mode; + blocking_mode_t mode; TRACE("%p\n", req); EnterCriticalSection( &req->read_section ); - mode = first_notif && req->read_size ? READMODE_NOBLOCK : READMODE_ASYNC; + mode = first_notif && req->read_size ? BLOCKING_DISALLOW : BLOCKING_ALLOW; res = refill_read_buffer(req, mode, &read); if(res == ERROR_SUCCESS) avail = get_avail_data(req); LeaveCriticalSection( &req->read_section ); - if(res != ERROR_SUCCESS || (mode != READMODE_NOBLOCK && !read)) { + if(res != ERROR_SUCCESS || (mode != BLOCKING_DISALLOW && !read)) { WARN("res %u read %u, closing connection\n", res, read); http_release_netconn(req, FALSE); } @@ -2957,10 +2970,10 @@ static void HTTP_ReceiveRequestData(http_request_t *req, BOOL first_notif, DWORD static DWORD HTTPREQ_Read(http_request_t *req, void *buffer, DWORD size, DWORD *read, BOOL sync) { DWORD current_read = 0, ret_read = 0; - read_mode_t read_mode; + blocking_mode_t blocking_mode; DWORD res = ERROR_SUCCESS; - read_mode = req->session->appInfo->hdr.dwFlags & INTERNET_FLAG_ASYNC ? READMODE_ASYNC : READMODE_SYNC; + blocking_mode = req->session->appInfo->hdr.dwFlags & INTERNET_FLAG_ASYNC ? BLOCKING_ALLOW : BLOCKING_WAITALL; EnterCriticalSection( &req->read_section ); @@ -2969,12 +2982,12 @@ static DWORD HTTPREQ_Read(http_request_t *req, void *buffer, DWORD size, DWORD * memcpy(buffer, req->read_buf+req->read_pos, ret_read); req->read_size -= ret_read; req->read_pos += ret_read; - if(read_mode == READMODE_ASYNC) - read_mode = READMODE_NOBLOCK; + if(blocking_mode == BLOCKING_ALLOW) + blocking_mode = BLOCKING_DISALLOW; } if(ret_read < size) { - res = read_http_stream(req, (BYTE*)buffer+ret_read, size-ret_read, ¤t_read, read_mode); + res = read_http_stream(req, (BYTE*)buffer+ret_read, size-ret_read, ¤t_read, blocking_mode); ret_read += current_read; } @@ -2993,7 +3006,7 @@ static BOOL drain_content(http_request_t *req, BOOL blocking) { BOOL ret; - if(!req->netconn || req->contentLength == -1) + if(!is_valid_netconn(req->netconn) || req->contentLength == -1) return FALSE; if(!strcmpW(req->verb, szHEAD)) @@ -3181,7 +3194,7 @@ static DWORD HTTPREQ_QueryDataAvailable(object_header_t *hdr, DWORD *available, /* never wait, if we can't enter the section we queue an async request right away */ if (TryEnterCriticalSection( &req->read_section )) { - refill_read_buffer(req, READMODE_NOBLOCK, NULL); + refill_read_buffer(req, BLOCKING_DISALLOW, NULL); if ((*available = get_avail_data( req ))) goto done; if (end_of_read_data( req )) goto done; LeaveCriticalSection( &req->read_section ); @@ -3197,7 +3210,7 @@ static DWORD HTTPREQ_QueryDataAvailable(object_header_t *hdr, DWORD *available, if (!(*available = get_avail_data( req )) && !end_of_read_data( req )) { - refill_read_buffer( req, READMODE_ASYNC, NULL ); + refill_read_buffer( req, BLOCKING_ALLOW, NULL ); *available = get_avail_data( req ); } @@ -3208,6 +3221,21 @@ done: return ERROR_SUCCESS; } +static DWORD HTTPREQ_LockRequestFile(object_header_t *hdr, req_file_t **ret) +{ + http_request_t *req = (http_request_t*)hdr; + + TRACE("(%p)\n", req); + + if(!req->req_file) { + WARN("No cache file name available\n"); + return ERROR_FILE_NOT_FOUND; + } + + *ret = req_file_addref(req->req_file); + return ERROR_SUCCESS; +} + static const object_vtbl_t HTTPREQVtbl = { HTTPREQ_Destroy, HTTPREQ_CloseConnection, @@ -3217,7 +3245,8 @@ static const object_vtbl_t HTTPREQVtbl = { HTTPREQ_ReadFileEx, HTTPREQ_WriteFile, HTTPREQ_QueryDataAvailable, - NULL + NULL, + HTTPREQ_LockRequestFile }; /*********************************************************************** @@ -3237,7 +3266,7 @@ static DWORD HTTP_HttpOpenRequestW(http_session_t *session, { appinfo_t *hIC = session->appInfo; http_request_t *request; - DWORD len, res = ERROR_SUCCESS; + DWORD len; TRACE("-->\n"); @@ -3326,13 +3355,7 @@ static DWORD HTTP_HttpOpenRequestW(http_session_t *session, INTERNET_STATUS_HANDLE_CREATED, &request->hdr.hInternet, sizeof(HINTERNET)); - TRACE("<-- %u (%p)\n", res, request); - - if(res != ERROR_SUCCESS) { - WININET_Release( &request->hdr ); - *ret = NULL; - return res; - } + TRACE("<-- (%p)\n", request); *ret = request->hdr.hInternet; return ERROR_SUCCESS; @@ -3999,8 +4022,8 @@ static DWORD HTTP_HandleRedirect(http_request_t *request, LPCWSTR lpszUrl) WCHAR userName[INTERNET_MAX_USER_NAME_LENGTH]; BOOL custom_port = FALSE; - static WCHAR httpW[] = {'h','t','t','p',0}; - static WCHAR httpsW[] = {'h','t','t','p','s',0}; + static const WCHAR httpW[] = {'h','t','t','p',0}; + static const WCHAR httpsW[] = {'h','t','t','p','s',0}; userName[0] = 0; hostName[0] = 0; @@ -4726,9 +4749,22 @@ static DWORD open_http_connection(http_request_t *request, BOOL *reusing) netconn_t *netconn = NULL; DWORD res; - assert(!request->netconn); reset_data_stream(request); + if (request->netconn) + { + if (is_valid_netconn(request->netconn) && NETCON_is_alive(request->netconn)) + { + *reusing = TRUE; + return ERROR_SUCCESS; + } + else + { + free_netconn(request->netconn); + request->netconn = NULL; + } + } + res = HTTP_ResolveName(request); if(res != ERROR_SUCCESS) return res; @@ -4739,7 +4775,7 @@ static DWORD open_http_connection(http_request_t *request, BOOL *reusing) netconn = LIST_ENTRY(list_head(&request->server->conn_pool), netconn_t, pool_entry); list_remove(&netconn->pool_entry); - if(NETCON_is_alive(netconn)) + if(is_valid_netconn(netconn) && NETCON_is_alive(netconn)) break; TRACE("connection %p closed during idle\n", netconn); @@ -4875,7 +4911,6 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders, char *ascii_req; loop_next = FALSE; - reusing_connection = request->netconn != NULL; if(redirected) { request->contentLength = ~0u; @@ -4911,7 +4946,8 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders, TRACE("Request header -> %s\n", debugstr_w(requestString) ); - if (!reusing_connection && (res = open_http_connection(request, &reusing_connection)) != ERROR_SUCCESS) + res = open_http_connection(request, &reusing_connection); + if (res != ERROR_SUCCESS) break; /* send the request as ASCII, tack on the optional data */ @@ -5146,7 +5182,7 @@ static DWORD HTTP_HttpEndRequestW(http_request_t *request, DWORD dwFlags, DWORD_ INT responseLen; DWORD res = ERROR_SUCCESS; - if(!request->netconn) { + if(!is_valid_netconn(request->netconn)) { WARN("Not connected\n"); send_request_complete(request, 0, ERROR_INTERNET_OPERATION_CANCELLED); return ERROR_INTERNET_OPERATION_CANCELLED; @@ -5818,7 +5854,7 @@ static DWORD HTTP_GetResponseHeaders(http_request_t *request, INT *len) TRACE("-->\n"); - if(!request->netconn) + if(!is_valid_netconn(request->netconn)) goto lend; /* clear old response headers (eg. from a redirect response) */ diff --git a/dll/win32/wininet/internet.c b/dll/win32/wininet/internet.c index 84adb264e1e..b78e44f2e13 100644 --- a/dll/win32/wininet/internet.c +++ b/dll/win32/wininet/internet.c @@ -1177,7 +1177,7 @@ BOOL WINAPI InternetGetConnectedStateExW(LPDWORD lpdwStatus, LPWSTR lpszConnecti WARN("always returning LAN connection.\n"); *lpdwStatus = INTERNET_CONNECTION_LAN; } - return LoadStringW(WININET_hModule, IDS_LANCONNECTION, lpszConnectionName, dwNameLen); + return LoadStringW(WININET_hModule, IDS_LANCONNECTION, lpszConnectionName, dwNameLen) > 0; } @@ -1723,7 +1723,7 @@ BOOL WINAPI InternetCrackUrlW(LPCWSTR lpszUrl_orig, DWORD dwUrlLength_orig, DWOR if(!found_colon){ SetLastError(ERROR_INTERNET_UNRECOGNIZED_SCHEME); - return 0; + return FALSE; } lpUC->nScheme = INTERNET_SCHEME_UNKNOWN; @@ -2870,13 +2870,17 @@ BOOL WINAPI InternetSetOptionW(HINTERNET hInternet, DWORD dwOption, } break; + case INTERNET_PER_CONN_PROXY_BYPASS: + heap_free(pi.proxyBypass); + pi.proxyBypass = heap_strdupW(option->Value.pszValue); + break; + case INTERNET_PER_CONN_AUTOCONFIG_URL: case INTERNET_PER_CONN_AUTODISCOVERY_FLAGS: case INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL: case INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS: case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_TIME: case INTERNET_PER_CONN_AUTOCONFIG_LAST_DETECT_URL: - case INTERNET_PER_CONN_PROXY_BYPASS: FIXME("Unhandled dwOption %d\n", option->dwOption); break; @@ -3863,21 +3867,84 @@ BOOL WINAPI InternetQueryDataAvailable( HINTERNET hFile, return res == ERROR_SUCCESS; } +DWORD create_req_file(const WCHAR *file_name, req_file_t **ret) +{ + req_file_t *req_file; + + req_file = heap_alloc_zero(sizeof(*req_file)); + if(!req_file) + return ERROR_NOT_ENOUGH_MEMORY; + + req_file->ref = 1; + + req_file->file_name = heap_strdupW(file_name); + if(!req_file->file_name) { + heap_free(req_file); + return ERROR_NOT_ENOUGH_MEMORY; + } + + req_file->file_handle = CreateFileW(req_file->file_name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if(req_file->file_handle == INVALID_HANDLE_VALUE) { + req_file_release(req_file); + return GetLastError(); + } + + *ret = req_file; + return ERROR_SUCCESS; +} + +void req_file_release(req_file_t *req_file) +{ + if(InterlockedDecrement(&req_file->ref)) + return; + + if(!req_file->is_committed) + DeleteFileW(req_file->file_name); + if(req_file->file_handle && req_file->file_handle != INVALID_HANDLE_VALUE) + CloseHandle(req_file->file_handle); + heap_free(req_file->file_name); + heap_free(req_file); +} /*********************************************************************** * InternetLockRequestFile (WININET.@) */ -BOOL WINAPI InternetLockRequestFile( HINTERNET hInternet, HANDLE -*lphLockReqHandle) +BOOL WINAPI InternetLockRequestFile(HINTERNET hInternet, HANDLE *lphLockReqHandle) { - FIXME("STUB\n"); - return FALSE; + req_file_t *req_file = NULL; + object_header_t *hdr; + DWORD res; + + TRACE("(%p %p)\n", hInternet, lphLockReqHandle); + + hdr = get_handle_object(hInternet); + if (!hdr) { + SetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } + + if(hdr->vtbl->LockRequestFile) { + res = hdr->vtbl->LockRequestFile(hdr, &req_file); + }else { + WARN("wrong handle\n"); + res = ERROR_INTERNET_INCORRECT_HANDLE_TYPE; + } + + WININET_Release(hdr); + + *lphLockReqHandle = req_file; + if(res != ERROR_SUCCESS) + SetLastError(res); + return res == ERROR_SUCCESS; } -BOOL WINAPI InternetUnlockRequestFile( HANDLE hLockHandle) +BOOL WINAPI InternetUnlockRequestFile(HANDLE hLockHandle) { - FIXME("STUB\n"); - return FALSE; + TRACE("(%p)\n", hLockHandle); + + req_file_release(hLockHandle); + return TRUE; } @@ -4526,7 +4593,7 @@ BOOL WINAPI ResumeSuspendedDownload( HINTERNET hInternet, DWORD dwError ) BOOL WINAPI InternetQueryFortezzaStatus(DWORD *a, DWORD_PTR b) { FIXME("(%p, %08lx) stub\n", a, b); - return 0; + return FALSE; } DWORD WINAPI ShowClientAuthCerts(HWND parent) diff --git a/dll/win32/wininet/internet.h b/dll/win32/wininet/internet.h index 85d4652aeb1..08a0ccf6a14 100644 --- a/dll/win32/wininet/internet.h +++ b/dll/win32/wininet/internet.h @@ -146,6 +146,9 @@ typedef struct struct list pool_entry; } netconn_t; +BOOL is_valid_netconn(netconn_t *) DECLSPEC_HIDDEN; +void close_netconn(netconn_t *) DECLSPEC_HIDDEN; + static inline void * __WINE_ALLOC_SIZE(1) heap_alloc(size_t len) { return HeapAlloc(GetProcessHeap(), 0, len); @@ -285,6 +288,14 @@ typedef enum #define INET_OPENURL 0x0001 #define INET_CALLBACKW 0x0002 +typedef struct +{ + LONG ref; + HANDLE file_handle; + WCHAR *file_name; + BOOL is_committed; +} req_file_t; + typedef struct _object_header_t object_header_t; typedef struct { @@ -297,6 +308,7 @@ typedef struct { DWORD (*WriteFile)(object_header_t*,const void*,DWORD,DWORD*); DWORD (*QueryDataAvailable)(object_header_t*,DWORD*,DWORD,DWORD_PTR); DWORD (*FindNextFileW)(object_header_t*,void*); + DWORD (*LockRequestFile)(object_header_t*,req_file_t**); } object_vtbl_t; #define INTERNET_HANDLE_IN_USE 1 @@ -318,7 +330,6 @@ struct _object_header_t struct list children; }; - typedef struct { object_header_t hdr; @@ -395,7 +406,7 @@ typedef struct DWORD nCustHeaders; FILETIME last_modified; HANDLE hCacheFile; - LPWSTR cacheFile; + req_file_t *req_file; FILETIME expires; struct HttpAuthInfo *authInfo; struct HttpAuthInfo *proxyAuthInfo; @@ -465,14 +476,19 @@ VOID INTERNET_SendCallback(object_header_t *hdr, DWORD_PTR dwContext, DWORD dwStatusInfoLength) DECLSPEC_HIDDEN; BOOL INTERNET_FindProxyForProtocol(LPCWSTR szProxy, LPCWSTR proto, WCHAR *foundProxy, DWORD *foundProxyLen) DECLSPEC_HIDDEN; +typedef enum { + BLOCKING_ALLOW, + BLOCKING_DISALLOW, + BLOCKING_WAITALL +} blocking_mode_t; + DWORD create_netconn(BOOL,server_t*,DWORD,BOOL,DWORD,netconn_t**) DECLSPEC_HIDDEN; void free_netconn(netconn_t*) DECLSPEC_HIDDEN; void NETCON_unload(void) DECLSPEC_HIDDEN; DWORD NETCON_secure_connect(netconn_t*,server_t*) DECLSPEC_HIDDEN; DWORD NETCON_send(netconn_t *connection, const void *msg, size_t len, int flags, int *sent /* out */) DECLSPEC_HIDDEN; -DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, int flags, - int *recvd /* out */) DECLSPEC_HIDDEN; +DWORD NETCON_recv(netconn_t*,void*,size_t,blocking_mode_t,int*) DECLSPEC_HIDDEN; BOOL NETCON_query_data_available(netconn_t *connection, DWORD *available) DECLSPEC_HIDDEN; BOOL NETCON_is_alive(netconn_t*) DECLSPEC_HIDDEN; LPCVOID NETCON_GetCert(netconn_t *connection) DECLSPEC_HIDDEN; @@ -505,6 +521,15 @@ static inline int unix_getsockopt(int socket, int level, int option_name, void * server_t *get_server(const WCHAR*,INTERNET_PORT,BOOL,BOOL); +DWORD create_req_file(const WCHAR*,req_file_t**) DECLSPEC_HIDDEN; +void req_file_release(req_file_t*) DECLSPEC_HIDDEN; + +static inline req_file_t *req_file_addref(req_file_t *req_file) +{ + InterlockedIncrement(&req_file->ref); + return req_file; +} + BOOL init_urlcache(void) DECLSPEC_HIDDEN; void free_urlcache(void) DECLSPEC_HIDDEN; void free_cookie(void) DECLSPEC_HIDDEN; diff --git a/dll/win32/wininet/netconnection.c b/dll/win32/wininet/netconnection.c index d7c6c613ba3..f58c553abf7 100644 --- a/dll/win32/wininet/netconnection.c +++ b/dll/win32/wininet/netconnection.c @@ -34,8 +34,16 @@ # include #endif +#include + #define RESPONSE_TIMEOUT 30 /* FROM internet.c */ +#ifdef MSG_DONTWAIT +#define WINE_MSG_DONTWAIT MSG_DONTWAIT +#else +#define WINE_MSG_DONTWAIT 0 +#endif + /* FIXME!!!!!! * This should use winsock - To use winsock the functions will have to change a bit * as they are designed for unix sockets. @@ -284,7 +292,10 @@ static DWORD create_netconn_socket(server_t *server, netconn_t *netconn, DWORD t } } if(result == -1) + { closesocket(netconn->socket); + netconn->socket = -1; + } else { flag = 0; ioctlsocket(netconn->socket, FIONBIO, &flag); @@ -316,6 +327,7 @@ DWORD create_netconn(BOOL useSSL, server_t *server, DWORD security_flags, BOOL m netconn->security_flags = security_flags | server->security_flags; netconn->mask_errors = mask_errors; list_init(&netconn->pool_entry); + SecInvalidateHandle(&netconn->ssl_ctx); result = create_netconn_socket(server, netconn, timeout); if (result != ERROR_SUCCESS) { @@ -329,6 +341,17 @@ DWORD create_netconn(BOOL useSSL, server_t *server, DWORD security_flags, BOOL m return result; } +BOOL is_valid_netconn(netconn_t *netconn) +{ + return netconn && netconn->socket != -1; +} + +void close_netconn(netconn_t *netconn) +{ + closesocket(netconn->socket); + netconn->socket = -1; +} + void free_netconn(netconn_t *netconn) { server_release(netconn->server); @@ -343,10 +366,10 @@ void free_netconn(netconn_t *netconn) heap_free(netconn->extra_buf); netconn->extra_buf = NULL; netconn->extra_len = 0; - DeleteSecurityContext(&netconn->ssl_ctx); + if (SecIsValidHandle(&netconn->ssl_ctx)) + DeleteSecurityContext(&netconn->ssl_ctx); } - closesocket(netconn->socket); heap_free(netconn); } @@ -428,6 +451,14 @@ int sock_get_error( int err ) } #endif +static void set_socket_blocking(int socket, blocking_mode_t mode) +{ +#if defined(__MINGW32__) || defined (_MSC_VER) + ULONG arg = mode == BLOCKING_DISALLOW; + ioctlsocket(socket, FIONBIO, &arg); +#endif +} + static DWORD netcon_secure_connect_setup(netconn_t *connection, BOOL compat_mode) { SecBuffer out_buf = {0, SECBUFFER_TOKEN, NULL}, in_bufs[2] = {{0, SECBUFFER_TOKEN}, {0, SECBUFFER_EMPTY}}; @@ -447,7 +478,7 @@ static DWORD netcon_secure_connect_setup(netconn_t *connection, BOOL compat_mode |ISC_REQ_SEQUENCE_DETECT|ISC_REQ_REPLAY_DETECT|ISC_REQ_MANUAL_CRED_VALIDATION; if(!ensure_cred_handle()) - return FALSE; + return ERROR_INTERNET_SECURITY_CHANNEL_ERROR; if(compat_mode) { if(!have_compat_cred_handle) @@ -525,6 +556,10 @@ static DWORD netcon_secure_connect_setup(netconn_t *connection, BOOL compat_mode TRACE("InitializeSecurityContext ret %08x\n", status); if(status == SEC_E_OK) { + if(SecIsValidHandle(&connection->ssl_ctx)) + DeleteSecurityContext(&connection->ssl_ctx); + connection->ssl_ctx = ctx; + if(in_bufs[1].BufferType == SECBUFFER_EXTRA) FIXME("SECBUFFER_EXTRA not supported\n"); @@ -556,19 +591,14 @@ static DWORD netcon_secure_connect_setup(netconn_t *connection, BOOL compat_mode } } - if(status != SEC_E_OK || res != ERROR_SUCCESS) { - WARN("Failed to initialize security context failed: %08x\n", status); + WARN("Failed to establish SSL connection: %08x (%u)\n", status, res); heap_free(connection->ssl_buf); connection->ssl_buf = NULL; - DeleteSecurityContext(&ctx); return res ? res : ERROR_INTERNET_SECURITY_CHANNEL_ERROR; } - TRACE("established SSL connection\n"); - connection->ssl_ctx = ctx; - connection->secure = TRUE; connection->security_flags |= SECURITY_FLAG_SECURE; @@ -685,37 +715,53 @@ DWORD NETCON_send(netconn_t *connection, const void *msg, size_t len, int flags, } } -static BOOL read_ssl_chunk(netconn_t *conn, void *buf, SIZE_T buf_size, SIZE_T *ret_size, BOOL *eof) +static BOOL read_ssl_chunk(netconn_t *conn, void *buf, SIZE_T buf_size, blocking_mode_t mode, SIZE_T *ret_size, BOOL *eof) { const SIZE_T ssl_buf_size = conn->ssl_sizes.cbHeader+conn->ssl_sizes.cbMaximumMessage+conn->ssl_sizes.cbTrailer; SecBuffer bufs[4]; SecBufferDesc buf_desc = {SECBUFFER_VERSION, sizeof(bufs)/sizeof(*bufs), bufs}; - SSIZE_T size, buf_len; + SSIZE_T size, buf_len = 0; + blocking_mode_t tmp_mode; int i; SECURITY_STATUS res; assert(conn->extra_len < ssl_buf_size); + /* BLOCKING_WAITALL is handled by caller */ + if(mode == BLOCKING_WAITALL) + mode = BLOCKING_ALLOW; + if(conn->extra_len) { memcpy(conn->ssl_buf, conn->extra_buf, conn->extra_len); buf_len = conn->extra_len; conn->extra_len = 0; heap_free(conn->extra_buf); conn->extra_buf = NULL; - }else { - buf_len = recv(conn->socket, conn->ssl_buf+conn->extra_len, ssl_buf_size-conn->extra_len, 0); - if(buf_len < 0) { - WARN("recv failed\n"); - return FALSE; - } - - if(!buf_len) { - *eof = TRUE; - return TRUE; - } } - *ret_size = 0; + tmp_mode = buf_len ? BLOCKING_DISALLOW : mode; + set_socket_blocking(conn->socket, tmp_mode); + size = recv(conn->socket, conn->ssl_buf+buf_len, ssl_buf_size-buf_len, tmp_mode == BLOCKING_ALLOW ? 0 : WINE_MSG_DONTWAIT); + if(size < 0) { + if(!buf_len) { + if(errno == EAGAIN || errno == EWOULDBLOCK) { + TRACE("would block\n"); + return WSAEWOULDBLOCK; + } + WARN("recv failed\n"); + return ERROR_INTERNET_CONNECTION_ABORTED; + } + }else { + buf_len += size; + } + + *ret_size = buf_len; + + if(!buf_len) { + *eof = TRUE; + return ERROR_SUCCESS; + } + *eof = FALSE; do { @@ -731,19 +777,34 @@ static BOOL read_ssl_chunk(netconn_t *conn, void *buf, SIZE_T buf_size, SIZE_T * case SEC_I_CONTEXT_EXPIRED: TRACE("context expired\n"); *eof = TRUE; - return TRUE; + return ERROR_SUCCESS; case SEC_E_INCOMPLETE_MESSAGE: assert(buf_len < ssl_buf_size); - size = recv(conn->socket, conn->ssl_buf+buf_len, ssl_buf_size-buf_len, 0); - if(size < 1) - return FALSE; + set_socket_blocking(conn->socket, mode); + size = recv(conn->socket, conn->ssl_buf+buf_len, ssl_buf_size-buf_len, mode == BLOCKING_ALLOW ? 0 : WINE_MSG_DONTWAIT); + if(size < 1) { + if(size < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) { + TRACE("would block\n"); + + /* FIXME: Optimize extra_buf usage. */ + conn->extra_buf = heap_alloc(buf_len); + if(!conn->extra_buf) + return ERROR_NOT_ENOUGH_MEMORY; + + conn->extra_len = buf_len; + memcpy(conn->extra_buf, conn->ssl_buf, conn->extra_len); + return WSAEWOULDBLOCK; + } + + return ERROR_INTERNET_CONNECTION_ABORTED; + } buf_len += size; continue; default: WARN("failed: %08x\n", res); - return FALSE; + return ERROR_INTERNET_CONNECTION_ABORTED; } } while(res != SEC_E_OK); @@ -755,7 +816,7 @@ static BOOL read_ssl_chunk(netconn_t *conn, void *buf, SIZE_T buf_size, SIZE_T * assert(!conn->peek_len); conn->peek_msg_mem = conn->peek_msg = heap_alloc(bufs[i].cbBuffer - size); if(!conn->peek_msg) - return FALSE; + return ERROR_NOT_ENOUGH_MEMORY; conn->peek_len = bufs[i].cbBuffer-size; memcpy(conn->peek_msg, (char*)bufs[i].pvBuffer+size, conn->peek_len); } @@ -768,14 +829,14 @@ static BOOL read_ssl_chunk(netconn_t *conn, void *buf, SIZE_T buf_size, SIZE_T * if(bufs[i].BufferType == SECBUFFER_EXTRA) { conn->extra_buf = heap_alloc(bufs[i].cbBuffer); if(!conn->extra_buf) - return FALSE; + return ERROR_NOT_ENOUGH_MEMORY; conn->extra_len = bufs[i].cbBuffer; memcpy(conn->extra_buf, bufs[i].pvBuffer, conn->extra_len); } } - return TRUE; + return ERROR_SUCCESS; } /****************************************************************************** @@ -783,7 +844,7 @@ static BOOL read_ssl_chunk(netconn_t *conn, void *buf, SIZE_T buf_size, SIZE_T * * Basically calls 'recv()' unless we should use SSL * number of chars received is put in *recvd */ -DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, int flags, int *recvd) +DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, blocking_mode_t mode, int *recvd) { *recvd = 0; if (!len) @@ -791,13 +852,28 @@ DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, int flags, int * if (!connection->secure) { + int flags = 0; + + switch(mode) { + case BLOCKING_ALLOW: + break; + case BLOCKING_DISALLOW: + flags = WINE_MSG_DONTWAIT; + break; + case BLOCKING_WAITALL: + flags = MSG_WAITALL; + break; + } + + set_socket_blocking(connection->socket, mode); *recvd = recv(connection->socket, buf, len, flags); return *recvd == -1 ? sock_get_error(errno) : ERROR_SUCCESS; } else { SIZE_T size = 0, cread; - BOOL res, eof; + BOOL eof; + DWORD res; if(connection->peek_msg) { size = min(len, connection->peek_len); @@ -810,18 +886,23 @@ DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, int flags, int * connection->peek_msg_mem = connection->peek_msg = NULL; } /* check if we have enough data from the peek buffer */ - if(!(flags & MSG_WAITALL) || size == len) { + if(mode != BLOCKING_WAITALL || size == len) { *recvd = size; return ERROR_SUCCESS; } + + mode = BLOCKING_DISALLOW; } do { - res = read_ssl_chunk(connection, (BYTE*)buf+size, len-size, &cread, &eof); - if(!res) { - WARN("read_ssl_chunk failed\n"); - if(!size) - return ERROR_INTERNET_CONNECTION_ABORTED; + res = read_ssl_chunk(connection, (BYTE*)buf+size, len-size, mode, &cread, &eof); + if(res != ERROR_SUCCESS) { + if(res == WSAEWOULDBLOCK) { + if(size) + res = ERROR_SUCCESS; + }else { + WARN("read_ssl_chunk failed\n"); + } break; } @@ -831,11 +912,11 @@ DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, int flags, int * } size += cread; - }while(!size || ((flags & MSG_WAITALL) && size < len)); + }while(!size || (mode == BLOCKING_WAITALL && size < len)); TRACE("received %ld bytes\n", size); *recvd = size; - return ERROR_SUCCESS; + return res; } } @@ -902,9 +983,6 @@ LPCVOID NETCON_GetCert(netconn_t *connection) const CERT_CONTEXT *ret; SECURITY_STATUS res; - if (!connection->secure) - return NULL; - res = QueryContextAttributesW(&connection->ssl_ctx, SECPKG_ATTR_REMOTE_CERT_CONTEXT, (void*)&ret); return res == SEC_E_OK ? ret : NULL; } diff --git a/dll/win32/wininet/utility.c b/dll/win32/wininet/utility.c index b3783959a1a..826418daefd 100644 --- a/dll/win32/wininet/utility.c +++ b/dll/win32/wininet/utility.c @@ -141,7 +141,7 @@ BOOL GetAddress(LPCWSTR lpszServerName, INTERNET_PORT nServerPort, TRACE("%s\n", debugstr_w(lpszServerName)); /* Validate server name first - * Check if there is sth. like + * Check if there is something like * pinger.macromedia.com:80 * if yes, eliminate the :80.... */ diff --git a/dll/win32/ws2help/context.c b/dll/win32/ws2help/context.c index 876446e344d..05230d16465 100644 --- a/dll/win32/ws2help/context.c +++ b/dll/win32/ws2help/context.c @@ -45,8 +45,8 @@ typedef VLONG *PVLONG; /* FUNCTIONS *****************************************************************/ -VOID static __inline +VOID AcquireReadLock(IN PWAH_SEARCH_TABLE Table, IN PVLONG *Count) { @@ -70,8 +70,8 @@ AcquireReadLock(IN PWAH_SEARCH_TABLE Table, } while (TRUE); } -VOID static __inline +VOID ReleaseReadLock(IN PWAH_SEARCH_TABLE Table, IN PVLONG Count) { @@ -139,8 +139,8 @@ DoWaitForReaders(IN PWAH_SEARCH_TABLE Table, } } -VOID static __inline +VOID TryWaitForReaders(IN PWAH_SEARCH_TABLE Table) { PVLONG OldCount = Table->CurrentCount; diff --git a/dll/win32/wtsapi32/wtsapi32.c b/dll/win32/wtsapi32/wtsapi32.c index f3410f91bf0..067aae69615 100644 --- a/dll/win32/wtsapi32/wtsapi32.c +++ b/dll/win32/wtsapi32/wtsapi32.c @@ -87,7 +87,11 @@ BOOL WINAPI WTSEnumerateProcessesW(HANDLE hServer, DWORD Reserved, DWORD Version FIXME("Stub %p 0x%08x 0x%08x %p %p\n", hServer, Reserved, Version, ppProcessInfo, pCount); - if (!ppProcessInfo || !pCount) return FALSE; + if (!ppProcessInfo || !pCount || Reserved != 0 || Version != 1) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } *pCount = 0; *ppProcessInfo = NULL; @@ -120,7 +124,9 @@ BOOL WINAPI WTSEnumerateServersW(LPWSTR pDomainName, DWORD Reserved, DWORD Versi BOOL WINAPI WTSEnumerateSessionsA(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_SESSION_INFOA* ppSessionInfo, DWORD* pCount) { - FIXME("Stub %p 0x%08x 0x%08x %p %p\n", hServer, Reserved, Version, + static int once; + + if (!once++) FIXME("Stub %p 0x%08x 0x%08x %p %p\n", hServer, Reserved, Version, ppSessionInfo, pCount); if (!ppSessionInfo || !pCount) return FALSE; @@ -153,7 +159,9 @@ BOOL WINAPI WTSEnumerateSessionsW(HANDLE hServer, DWORD Reserved, DWORD Version, */ void WINAPI WTSFreeMemory(PVOID pMemory) { - FIXME("Stub %p\n", pMemory); + static int once; + + if (!once++) FIXME("Stub %p\n", pMemory); } /************************************************************ diff --git a/dll/win32/wuapi/downloader.c b/dll/win32/wuapi/downloader.c index 5749ed88ce4..9fd6e849ad0 100644 --- a/dll/win32/wuapi/downloader.c +++ b/dll/win32/wuapi/downloader.c @@ -234,11 +234,11 @@ static const struct IUpdateDownloaderVtbl update_downloader_vtbl = update_downloader_EndDownload }; -HRESULT UpdateDownloader_create( IUnknown *pUnkOuter, LPVOID *ppObj ) +HRESULT UpdateDownloader_create( LPVOID *ppObj ) { update_downloader *downloader; - TRACE("(%p,%p)\n", pUnkOuter, ppObj); + TRACE("(%p)\n", ppObj); downloader = HeapAlloc( GetProcessHeap(), 0, sizeof(*downloader) ); if (!downloader) return E_OUTOFMEMORY; diff --git a/dll/win32/wuapi/installer.c b/dll/win32/wuapi/installer.c index ae2e5ae638e..e2f41e839a8 100644 --- a/dll/win32/wuapi/installer.c +++ b/dll/win32/wuapi/installer.c @@ -329,11 +329,11 @@ static const struct IUpdateInstallerVtbl update_installer_vtbl = update_installer_get_RebootRequiredBeforeInstallation }; -HRESULT UpdateInstaller_create( IUnknown *pUnkOuter, LPVOID *ppObj ) +HRESULT UpdateInstaller_create( LPVOID *ppObj ) { update_installer *installer; - TRACE("(%p,%p)\n", pUnkOuter, ppObj); + TRACE("(%p)\n", ppObj); installer = HeapAlloc( GetProcessHeap(), 0, sizeof(*installer) ); if (!installer) return E_OUTOFMEMORY; diff --git a/dll/win32/wuapi/main.c b/dll/win32/wuapi/main.c index 9449abdf0b1..104bfe1a791 100644 --- a/dll/win32/wuapi/main.c +++ b/dll/win32/wuapi/main.c @@ -22,7 +22,7 @@ #include -typedef HRESULT (*fnCreateInstance)( IUnknown *pUnkOuter, LPVOID *ppObj ); +typedef HRESULT (*fnCreateInstance)( LPVOID *ppObj ); typedef struct _wucf { @@ -72,14 +72,11 @@ static HRESULT WINAPI wucf_CreateInstance( IClassFactory *iface, LPUNKNOWN pOute if (pOuter) return CLASS_E_NOAGGREGATION; - r = This->pfnCreateInstance( pOuter, (LPVOID *)&punk ); + r = This->pfnCreateInstance( (LPVOID *)&punk ); if (FAILED(r)) return r; r = IUnknown_QueryInterface( punk, riid, ppobj ); - if (FAILED(r)) - return r; - IUnknown_Release( punk ); return r; } diff --git a/dll/win32/wuapi/searcher.c b/dll/win32/wuapi/searcher.c index 50253fefeb0..bf9d0c187e0 100644 --- a/dll/win32/wuapi/searcher.c +++ b/dll/win32/wuapi/searcher.c @@ -301,11 +301,11 @@ static const struct IUpdateSearcherVtbl update_searcher_vtbl = update_searcher_put_ServiceID }; -HRESULT UpdateSearcher_create( IUnknown *pUnkOuter, LPVOID *ppObj ) +HRESULT UpdateSearcher_create( LPVOID *ppObj ) { update_searcher *searcher; - TRACE("(%p,%p)\n", pUnkOuter, ppObj); + TRACE("(%p)\n", ppObj); searcher = HeapAlloc( GetProcessHeap(), 0, sizeof(*searcher) ); if (!searcher) return E_OUTOFMEMORY; diff --git a/dll/win32/wuapi/session.c b/dll/win32/wuapi/session.c index 59d3f6cf2d6..48cdee9fd58 100644 --- a/dll/win32/wuapi/session.c +++ b/dll/win32/wuapi/session.c @@ -165,7 +165,7 @@ static HRESULT WINAPI update_session_CreateUpdateSearcher( IUpdateSearcher **retval ) { TRACE("%p\n", This); - return UpdateSearcher_create( NULL, (LPVOID *)retval ); + return UpdateSearcher_create( (LPVOID *)retval ); } static HRESULT WINAPI update_session_CreateUpdateDownloader( @@ -173,7 +173,7 @@ static HRESULT WINAPI update_session_CreateUpdateDownloader( IUpdateDownloader **retval ) { TRACE("%p\n", This); - return UpdateDownloader_create( NULL, (LPVOID *)retval ); + return UpdateDownloader_create( (LPVOID *)retval ); } static HRESULT WINAPI update_session_CreateUpdateInstaller( @@ -181,7 +181,7 @@ static HRESULT WINAPI update_session_CreateUpdateInstaller( IUpdateInstaller **retval ) { TRACE("%p\n", This); - return UpdateInstaller_create( NULL, (LPVOID *)retval ); + return UpdateInstaller_create( (LPVOID *)retval ); } static const struct IUpdateSessionVtbl update_session_vtbl = @@ -203,11 +203,11 @@ static const struct IUpdateSessionVtbl update_session_vtbl = update_session_CreateUpdateInstaller }; -HRESULT UpdateSession_create( IUnknown *pUnkOuter, LPVOID *ppObj ) +HRESULT UpdateSession_create( LPVOID *ppObj ) { update_session *session; - TRACE("(%p,%p)\n", pUnkOuter, ppObj); + TRACE("(%p)\n", ppObj); session = HeapAlloc( GetProcessHeap(), 0, sizeof(*session) ); if (!session) return E_OUTOFMEMORY; diff --git a/dll/win32/wuapi/systeminfo.c b/dll/win32/wuapi/systeminfo.c index 680f02fd85b..a30879f623e 100644 --- a/dll/win32/wuapi/systeminfo.c +++ b/dll/win32/wuapi/systeminfo.c @@ -130,11 +130,11 @@ static const struct ISystemInformationVtbl systeminfo_vtbl = systeminfo_get_RebootRequired }; -HRESULT SystemInformation_create(IUnknown *pUnkOuter, LPVOID *ppObj) +HRESULT SystemInformation_create(LPVOID *ppObj) { systeminfo *info; - TRACE("(%p,%p)\n", pUnkOuter, ppObj); + TRACE("(%p)\n", ppObj); info = HeapAlloc(GetProcessHeap(), 0, sizeof(*info)); if (!info) diff --git a/dll/win32/wuapi/updates.c b/dll/win32/wuapi/updates.c index dad6ac146a6..fd3ad42d267 100644 --- a/dll/win32/wuapi/updates.c +++ b/dll/win32/wuapi/updates.c @@ -189,11 +189,11 @@ static const struct IAutomaticUpdatesVtbl automatic_updates_vtbl = automatic_updates_EnableService }; -HRESULT AutomaticUpdates_create( IUnknown *pUnkOuter, LPVOID *ppObj ) +HRESULT AutomaticUpdates_create( LPVOID *ppObj ) { automatic_updates *updates; - TRACE("(%p,%p)\n", pUnkOuter, ppObj); + TRACE("(%p)\n", ppObj); updates = HeapAlloc( GetProcessHeap(), 0, sizeof(*updates) ); if (!updates) return E_OUTOFMEMORY; diff --git a/dll/win32/wuapi/wuapi_private.h b/dll/win32/wuapi/wuapi_private.h index 5b18dad07c9..4ef2f5115be 100644 --- a/dll/win32/wuapi/wuapi_private.h +++ b/dll/win32/wuapi/wuapi_private.h @@ -36,11 +36,11 @@ #include WINE_DEFAULT_DEBUG_CHANNEL(wuapi); -extern HRESULT AutomaticUpdates_create( IUnknown *pUnkOuter, LPVOID *ppObj ) DECLSPEC_HIDDEN; -extern HRESULT UpdateSession_create( IUnknown *pUnkOuter, LPVOID *ppObj ) DECLSPEC_HIDDEN; -extern HRESULT UpdateSearcher_create( IUnknown *pUnkOuter, LPVOID *ppObj ) DECLSPEC_HIDDEN; -extern HRESULT UpdateDownloader_create( IUnknown *pUnkOuter, LPVOID *ppObj ) DECLSPEC_HIDDEN; -extern HRESULT UpdateInstaller_create( IUnknown *pUnkOuter, LPVOID *ppObj ) DECLSPEC_HIDDEN; -extern HRESULT SystemInformation_create(IUnknown *pUnkOuter, LPVOID *ppObj) DECLSPEC_HIDDEN; +extern HRESULT AutomaticUpdates_create( LPVOID *ppObj ) DECLSPEC_HIDDEN; +extern HRESULT UpdateSession_create( LPVOID *ppObj ) DECLSPEC_HIDDEN; +extern HRESULT UpdateSearcher_create( LPVOID *ppObj ) DECLSPEC_HIDDEN; +extern HRESULT UpdateDownloader_create( LPVOID *ppObj ) DECLSPEC_HIDDEN; +extern HRESULT UpdateInstaller_create( LPVOID *ppObj ) DECLSPEC_HIDDEN; +extern HRESULT SystemInformation_create( LPVOID *ppObj ) DECLSPEC_HIDDEN; #endif /* _WUAPI_PRIVATE_H_ */ diff --git a/dll/win32/wuapi/wuapi_tlb.idl b/dll/win32/wuapi/wuapi_tlb.idl index 120e36402c3..1f2e0475ab9 100644 --- a/dll/win32/wuapi/wuapi_tlb.idl +++ b/dll/win32/wuapi/wuapi_tlb.idl @@ -18,4 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#pragma makedep regtypelib + #include "wuapi.idl" diff --git a/drivers/base/bootvid/i386/vga.c b/drivers/base/bootvid/i386/vga.c index add073fd76d..71754c5fb77 100644 --- a/drivers/base/bootvid/i386/vga.c +++ b/drivers/base/bootvid/i386/vga.c @@ -95,8 +95,8 @@ ReadWriteMode(UCHAR Mode) } -VOID FORCEINLINE +VOID SetPixel(IN ULONG Left, IN ULONG Top, IN UCHAR Color) diff --git a/drivers/base/nmidebug/nmidebug.c b/drivers/base/nmidebug/nmidebug.c index 4aa279130eb..9400fd416fc 100644 --- a/drivers/base/nmidebug/nmidebug.c +++ b/drivers/base/nmidebug/nmidebug.c @@ -15,8 +15,8 @@ PCHAR NmiBegin = "NMI4NMI@"; -VOID FORCEINLINE +VOID NmiClearFlag(VOID) { ((PCHAR)&KiBugCheckData[4])[0] -= (NmiBegin[3] | NmiBegin[7]); diff --git a/drivers/filesystems/fastfat/create.c b/drivers/filesystems/fastfat/create.c index 76967dd6d73..468b902977c 100644 --- a/drivers/filesystems/fastfat/create.c +++ b/drivers/filesystems/fastfat/create.c @@ -352,6 +352,7 @@ VfatOpenFile( PUNICODE_STRING PathNameU, PFILE_OBJECT FileObject, ULONG RequestedDisposition, + BOOLEAN OpenTargetDir, PVFATFCB *ParentFcb) { PVFATFCB Fcb; @@ -402,6 +403,14 @@ VfatOpenFile( DPRINT ("Could not make a new FCB, status: %x\n", Status); return Status; } + + /* In case we're to open target, just check whether file exist, but don't open it */ + if (OpenTargetDir) + { + vfatReleaseFCB(DeviceExt, Fcb); + return STATUS_OBJECT_NAME_COLLISION; + } + if (Fcb->Flags & FCB_DELETE_PENDING) { vfatReleaseFCB(DeviceExt, Fcb); @@ -443,6 +452,7 @@ VfatCreateFile( PWCHAR c, last; BOOLEAN PagingFileCreate = FALSE; BOOLEAN Dots; + BOOLEAN OpenTargetDir = FALSE; UNICODE_STRING FileNameU; UNICODE_STRING PathNameU; ULONG Attributes; @@ -452,6 +462,11 @@ VfatCreateFile( RequestedDisposition = ((Stack->Parameters.Create.Options >> 24) & 0xff); RequestedOptions = Stack->Parameters.Create.Options & FILE_VALID_OPTION_FLAGS; PagingFileCreate = (Stack->Flags & SL_OPEN_PAGING_FILE) ? TRUE : FALSE; +#if 0 + OpenTargetDir = (Stack->Flags & SL_OPEN_TARGET_DIRECTORY) ? TRUE : FALSE; +#else + OpenTargetDir = FALSE; +#endif FileObject = Stack->FileObject; DeviceExt = DeviceObject->DeviceExtension; @@ -485,6 +500,11 @@ VfatCreateFile( } #endif + if (OpenTargetDir) + { + return STATUS_INVALID_PARAMETER; + } + pFcb = DeviceExt->VolumeFcb; vfatAttachFCBToFileObject(DeviceExt, pFcb, FileObject); pFcb->RefCount++; @@ -520,6 +540,13 @@ VfatCreateFile( } } + /* Check if we try to open target directory of root dir */ + if (OpenTargetDir && FileObject->RelatedFileObject == NULL && PathNameU.Length == sizeof(WCHAR) && + PathNameU.Buffer[0] == L'\\') + { + return STATUS_INVALID_PARAMETER; + } + if (FileObject->RelatedFileObject && PathNameU.Length >= sizeof(WCHAR) && PathNameU.Buffer[0] == L'\\') { return STATUS_OBJECT_NAME_INVALID; @@ -531,7 +558,86 @@ VfatCreateFile( } /* Try opening the file. */ - Status = VfatOpenFile(DeviceExt, &PathNameU, FileObject, RequestedDisposition, &ParentFcb); + Status = VfatOpenFile(DeviceExt, &PathNameU, FileObject, RequestedDisposition, OpenTargetDir, &ParentFcb); + + if (OpenTargetDir) + { + LONG idx, FileNameLen; + + if (Status == STATUS_OBJECT_NAME_COLLISION) + { + Irp->IoStatus.Information = FILE_EXISTS; + } + else + { + Irp->IoStatus.Information = FILE_DOES_NOT_EXIST; + } + + idx = FileObject->FileName.Length / sizeof(WCHAR) - 1; + + /* Skip tailing \ - if any */ + if (PathNameU.Buffer[idx] == L'\\') + { + --idx; + PathNameU.Length -= sizeof(WCHAR); + } + + /* Get file name */ + while (idx >= 0 && PathNameU.Buffer[idx] != L'\\') + { + --idx; + } + + if (idx > 0 || PathNameU.Buffer[0] == L'\\') + { + /* We don't want to include / in the name */ + FileNameLen = PathNameU.Length - ((idx + 1) * sizeof(WCHAR)); + + /* Try to open parent */ + PathNameU.Length -= (PathNameU.Length - idx * sizeof(WCHAR)); + Status = VfatOpenFile(DeviceExt, &PathNameU, FileObject, RequestedDisposition, FALSE, &ParentFcb); + + /* Update FO just to keep file name */ + /* Skip first slash */ + ++idx; + FileObject->FileName.Length = FileNameLen; + RtlMoveMemory(&PathNameU.Buffer[0], &PathNameU.Buffer[idx], FileObject->FileName.Length); + } + else + { + /* This is a relative open and we have only the filename, so open the parent directory + * It is in RelatedFileObject + */ + BOOLEAN Chomp = FALSE; + PFILE_OBJECT RelatedFileObject = FileObject->RelatedFileObject; + + DPRINT("%wZ\n", &PathNameU); + + ASSERT(RelatedFileObject != NULL); + + DPRINT("Relative opening\n"); + DPRINT("FileObject->RelatedFileObject->FileName: %wZ\n", &RelatedFileObject->FileName); + + /* VfatOpenFile() doesn't like our name ends with \, so chomp it if there's one */ + if (RelatedFileObject->FileName.Buffer[RelatedFileObject->FileName.Length / sizeof(WCHAR) - 1] == L'\\') + { + Chomp = TRUE; + RelatedFileObject->FileName.Length -= sizeof(WCHAR); + } + + /* Tricky part - fake our FO. It's NOT relative, we want to open the complete file path */ + FileObject->RelatedFileObject = NULL; + Status = VfatOpenFile(DeviceExt, &RelatedFileObject->FileName, FileObject, RequestedDisposition, FALSE, &ParentFcb); + + /* We're done opening, restore what we broke */ + FileObject->RelatedFileObject = RelatedFileObject; + if (Chomp) RelatedFileObject->FileName.Length += sizeof(WCHAR); + + /* No need to modify the FO, it already has the name */ + } + + return Status; + } /* * If the directory containing the file to open doesn't exist then diff --git a/drivers/filesystems/fs_rec/fs_rec.c b/drivers/filesystems/fs_rec/fs_rec.c index 17293013dfc..9c2bb744f59 100644 --- a/drivers/filesystems/fs_rec/fs_rec.c +++ b/drivers/filesystems/fs_rec/fs_rec.c @@ -380,7 +380,7 @@ DriverEntry(IN PDRIVER_OBJECT DriverObject, L"\\FileSystem\\Ext2Recognizer", FS_TYPE_EXT2, FILE_DEVICE_DISK_FILE_SYSTEM); - if (NT_SUCCESS(Status)){ DeviceCount++; DPRINT1("2 Ext2FS!!!!!\n");} + if (NT_SUCCESS(Status)) DeviceCount++; /* Return appropriate Status */ return (DeviceCount > 0) ? STATUS_SUCCESS : STATUS_IMAGE_ALREADY_LOADED; diff --git a/drivers/filesystems/npfs/npfs.h b/drivers/filesystems/npfs/npfs.h index 28e773f1732..e13adbf60d2 100644 --- a/drivers/filesystems/npfs/npfs.h +++ b/drivers/filesystems/npfs/npfs.h @@ -351,8 +351,8 @@ NpReleaseVcb(VOID) // Function to process deferred IRPs outside the VCB lock but still within the // critical region // -VOID FORCEINLINE +VOID NpCompleteDeferredIrps(IN PLIST_ENTRY DeferredList) { PLIST_ENTRY ThisEntry, NextEntry; diff --git a/drivers/input/i8042prt/i8042prt.c b/drivers/input/i8042prt/i8042prt.c index d9c792b2d90..e3b0bf7ee0a 100644 --- a/drivers/input/i8042prt/i8042prt.c +++ b/drivers/input/i8042prt/i8042prt.c @@ -19,8 +19,14 @@ static DRIVER_STARTIO i8042StartIo; static DRIVER_DISPATCH IrpStub; +_Dispatch_type_(IRP_MJ_DEVICE_CONTROL) static DRIVER_DISPATCH i8042DeviceControl; +_Dispatch_type_(IRP_MJ_INTERNAL_DEVICE_CONTROL) static DRIVER_DISPATCH i8042InternalDeviceControl; +_Dispatch_type_(IRP_MJ_SYSTEM_CONTROL) +static DRIVER_DISPATCH i8042SystemControl; +_Dispatch_type_(IRP_MJ_POWER) +static DRIVER_DISPATCH i8042Power; DRIVER_INITIALIZE DriverEntry; NTSTATUS NTAPI @@ -466,6 +472,27 @@ i8042InternalDeviceControl( return Status; } +static NTSTATUS NTAPI +i8042Power( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PFDO_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; + PDEVICE_OBJECT LowerDevice = DeviceExtension->LowerDevice; + + PoStartNextPowerIrp(Irp); + IoSkipCurrentIrpStackLocation(Irp); + return PoCallDriver(LowerDevice, Irp); +} + +static NTSTATUS NTAPI +i8042SystemControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + return ForwardIrpAndForget(DeviceObject, Irp); +} + NTSTATUS NTAPI DriverEntry( IN PDRIVER_OBJECT DriverObject, @@ -529,6 +556,8 @@ DriverEntry( DriverObject->MajorFunction[IRP_MJ_CLOSE] = i8042Close; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = i8042DeviceControl; DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = i8042InternalDeviceControl; + DriverObject->MajorFunction[IRP_MJ_POWER] = i8042Power; + DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = i8042SystemControl; DriverObject->MajorFunction[IRP_MJ_PNP] = i8042Pnp; return STATUS_SUCCESS; diff --git a/drivers/input/i8042prt/i8042prt.h b/drivers/input/i8042prt/i8042prt.h index 92478010e6c..6c60ae3bc10 100644 --- a/drivers/input/i8042prt/i8042prt.h +++ b/drivers/input/i8042prt/i8042prt.h @@ -292,10 +292,13 @@ typedef struct _I8042_HOOK_WORKITEM IO_WORKITEM_ROUTINE i8042SendHookWorkItem; +_Dispatch_type_(IRP_MJ_CREATE) DRIVER_DISPATCH i8042Create; +_Dispatch_type_(IRP_MJ_CLEANUP) DRIVER_DISPATCH i8042Cleanup; +_Dispatch_type_(IRP_MJ_CLOSE) DRIVER_DISPATCH i8042Close; /* keyboard.c */ @@ -371,6 +374,7 @@ i8042ChangeMode( IN UCHAR FlagsToDisable, IN UCHAR FlagsToEnable); +_Dispatch_type_(IRP_MJ_PNP) DRIVER_DISPATCH i8042Pnp; /* ps2pp.c */ diff --git a/drivers/input/i8042prt/keyboard.c b/drivers/input/i8042prt/keyboard.c index e59af0955a6..0827a2f5b56 100644 --- a/drivers/input/i8042prt/keyboard.c +++ b/drivers/input/i8042prt/keyboard.c @@ -21,6 +21,7 @@ /* GLOBALS *******************************************************************/ static IO_WORKITEM_ROUTINE i8042PowerWorkItem; +static KDEFERRED_ROUTINE i8042KbdDpcRoutine; /* This structure starts with the same layout as KEYBOARD_INDICATOR_TRANSLATION */ typedef struct _LOCAL_KEYBOARD_INDICATOR_TRANSLATION { @@ -196,10 +197,11 @@ i8042PowerWorkItem( PIRP WaitingIrp; NTSTATUS Status; - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)Context; - UNREFERENCED_PARAMETER(DeviceObject); + __analysis_assume(Context != NULL); + DeviceExtension = Context; + /* See http://blogs.msdn.com/doronh/archive/2006/09/08/746961.aspx */ /* Register GUID_DEVICE_SYS_BUTTON interface and report capability */ @@ -331,7 +333,8 @@ i8042KbdDpcRoutine( UNREFERENCED_PARAMETER(SystemArgument1); UNREFERENCED_PARAMETER(SystemArgument2); - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)DeferredContext; + __analysis_assume(DeferredContext != NULL); + DeviceExtension = DeferredContext; PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; if (HandlePowerKeys(DeviceExtension)) @@ -652,9 +655,6 @@ cleanup: Irp->IoStatus.Information = sizeof(KEYBOARD_ATTRIBUTES); Status = STATUS_SUCCESS; break; - - Status = STATUS_NOT_IMPLEMENTED; - break; } case IOCTL_KEYBOARD_QUERY_TYPEMATIC: { @@ -745,9 +745,9 @@ cleanup: } /* - * Call the customization hook. The ToReturn parameter is about wether + * Call the customization hook. The ToReturn parameter is about whether * we should go on with the interrupt. The return value is what - * we should return (indicating to the system wether someone else + * we should return (indicating to the system whether someone else * should try to handle the interrupt) */ static BOOLEAN @@ -796,7 +796,8 @@ i8042KbdInterruptService( UNREFERENCED_PARAMETER(Interrupt); - DeviceExtension = (PI8042_KEYBOARD_EXTENSION)Context; + __analysis_assume(Context != NULL); + DeviceExtension = Context; PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; InputData = DeviceExtension->KeyboardBuffer + DeviceExtension->KeysInBuffer; Counter = PortDeviceExtension->Settings.PollStatusIterations; diff --git a/drivers/input/i8042prt/misc.c b/drivers/input/i8042prt/misc.c index 6b6ad572e89..3adb2d48782 100644 --- a/drivers/input/i8042prt/misc.c +++ b/drivers/input/i8042prt/misc.c @@ -23,8 +23,9 @@ ForwardIrpAndWaitCompletion( IN PVOID Context) { UNREFERENCED_PARAMETER(DeviceObject); + __analysis_assume(Context != NULL); if (Irp->PendingReturned) - KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE); + KeSetEvent(Context, IO_NO_INCREMENT, FALSE); return STATUS_MORE_PROCESSING_REQUIRED; } diff --git a/drivers/input/i8042prt/mouse.c b/drivers/input/i8042prt/mouse.c index cb66c353ada..966b0801fc7 100644 --- a/drivers/input/i8042prt/mouse.c +++ b/drivers/input/i8042prt/mouse.c @@ -18,6 +18,9 @@ /* FUNCTIONS *****************************************************************/ +static KDEFERRED_ROUTINE i8042MouDpcRoutine; +static KDEFERRED_ROUTINE i8042DpcRoutineMouseTimeout; + /* * These functions are callbacks for filter driver custom interrupt * service routines. @@ -269,7 +272,8 @@ i8042MouDpcRoutine( UNREFERENCED_PARAMETER(SystemArgument1); UNREFERENCED_PARAMETER(SystemArgument2); - DeviceExtension = (PI8042_MOUSE_EXTENSION)DeferredContext; + __analysis_assume(DeferredContext != NULL); + DeviceExtension = DeferredContext; PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; switch (DeviceExtension->MouseTimeoutState) @@ -358,7 +362,8 @@ i8042DpcRoutineMouseTimeout( UNREFERENCED_PARAMETER(SystemArgument1); UNREFERENCED_PARAMETER(SystemArgument2); - DeviceExtension = (PI8042_MOUSE_EXTENSION)DeferredContext; + __analysis_assume(DeferredContext != NULL); + DeviceExtension = DeferredContext; PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; Irql = KeAcquireInterruptSpinLock(PortDeviceExtension->HighestDIRQLInterrupt); @@ -906,7 +911,8 @@ i8042MouInterruptService( UNREFERENCED_PARAMETER(Interrupt); - DeviceExtension = (PI8042_MOUSE_EXTENSION)Context; + __analysis_assume(Context != NULL); + DeviceExtension = Context; PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension; Counter = PortDeviceExtension->Settings.PollStatusIterations; diff --git a/drivers/input/i8042prt/pnp.c b/drivers/input/i8042prt/pnp.c index 3cb70cab767..b0c67eccbed 100644 --- a/drivers/input/i8042prt/pnp.c +++ b/drivers/input/i8042prt/pnp.c @@ -112,7 +112,7 @@ i8042BasicDetect( } else if (Value == KBD_RESEND) { - TRACE_(I8042PRT, "Resending...\n", Value); + TRACE_(I8042PRT, "Resending...\n"); KeStallExecutionProcessor(50); } else @@ -390,7 +390,7 @@ static NTSTATUS StartProcedure( IN PPORT_DEVICE_EXTENSION DeviceExtension) { - NTSTATUS Status; + NTSTATUS Status = STATUS_UNSUCCESSFUL; UCHAR FlagsToDisable = 0; UCHAR FlagsToEnable = 0; KIRQL Irql; @@ -479,7 +479,10 @@ StartProcedure( /* Start the mouse */ Irql = KeAcquireInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt); - i8042IsrWritePort(DeviceExtension, MOU_CMD_RESET, CTRL_WRITE_MOUSE); + /* HACK: the mouse has already been reset in i8042DetectMouse. This second + reset prevents some touchpads/mice from working (Dell D531, D600). + See CORE-6901 + i8042IsrWritePort(DeviceExtension, MOU_CMD_RESET, CTRL_WRITE_MOUSE); */ KeReleaseInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt, Irql); } @@ -495,7 +498,7 @@ i8042PnpStartDevice( PFDO_DEVICE_EXTENSION DeviceExtension; PPORT_DEVICE_EXTENSION PortDeviceExtension; PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor, ResourceDescriptorTranslated; - INTERRUPT_DATA InterruptData; + INTERRUPT_DATA InterruptData = { NULL }; BOOLEAN FoundDataPort = FALSE; BOOLEAN FoundControlPort = FALSE; BOOLEAN FoundIrq = FALSE; @@ -682,19 +685,8 @@ i8042Pnp( { case BusRelations: { - PDEVICE_RELATIONS DeviceRelations; - TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n"); - DeviceRelations = ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS)); - if (DeviceRelations) - { - DeviceRelations->Count = 0; - Information = (ULONG_PTR)DeviceRelations; - Status = STATUS_SUCCESS; - } - else - Status = STATUS_INSUFFICIENT_RESOURCES; - break; + return ForwardIrpAndForget(DeviceObject, Irp); } case RemovalRelations: { @@ -704,7 +696,6 @@ i8042Pnp( default: ERR_(I8042PRT, "IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n", Stack->Parameters.QueryDeviceRelations.Type); - ASSERT(FALSE); return ForwardIrpAndForget(DeviceObject, Irp); } break; @@ -712,17 +703,12 @@ i8042Pnp( case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: /* (optional) 0x0d */ { TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n"); - /* Nothing to do */ - Status = Irp->IoStatus.Status; - break; + return ForwardIrpAndForget(DeviceObject, Irp); } case IRP_MN_QUERY_PNP_DEVICE_STATE: /* 0x14 */ { TRACE_(I8042PRT, "IRP_MJ_PNP / IRP_MN_QUERY_PNP_DEVICE_STATE\n"); - /* Nothing much to tell */ - Information = 0; - Status = STATUS_SUCCESS; - break; + return ForwardIrpAndForget(DeviceObject, Irp); } default: { diff --git a/hal/halx86/apic/apic.c b/hal/halx86/apic/apic.c index dc0e4b83a55..1e98060c3d0 100644 --- a/hal/halx86/apic/apic.c +++ b/hal/halx86/apic/apic.c @@ -89,8 +89,8 @@ HalVectorToIRQL[16] = /* PRIVATE FUNCTIONS **********************************************************/ -ULONG FORCEINLINE +ULONG IOApicRead(UCHAR Register) { /* Select the register, then do the read */ @@ -98,8 +98,8 @@ IOApicRead(UCHAR Register) return *(volatile ULONG *)(IOAPIC_BASE + IOAPIC_IOWIN); } -VOID FORCEINLINE +VOID IOApicWrite(UCHAR Register, ULONG Value) { /* Select the register, then do the write */ @@ -107,8 +107,8 @@ IOApicWrite(UCHAR Register, ULONG Value) *(volatile ULONG *)(IOAPIC_BASE + IOAPIC_IOWIN) = Value; } -VOID FORCEINLINE +VOID ApicWriteIORedirectionEntry( UCHAR Index, IOAPIC_REDIRECTION_REGISTER ReDirReg) @@ -117,8 +117,8 @@ ApicWriteIORedirectionEntry( IOApicWrite(IOAPIC_REDTBL + 2 * Index + 1, ReDirReg.Long1); } -IOAPIC_REDIRECTION_REGISTER FORCEINLINE +IOAPIC_REDIRECTION_REGISTER ApicReadIORedirectionEntry( UCHAR Index) { @@ -130,8 +130,8 @@ ApicReadIORedirectionEntry( return ReDirReg; } -VOID FORCEINLINE +VOID ApicRequestInterrupt(IN UCHAR Vector, UCHAR TriggerMode) { APIC_COMMAND_REGISTER CommandRegister; @@ -147,24 +147,24 @@ ApicRequestInterrupt(IN UCHAR Vector, UCHAR TriggerMode) ApicWrite(APIC_ICR0, CommandRegister.Long0); } -VOID FORCEINLINE +VOID ApicSendEOI(void) { //ApicWrite(APIC_EOI, 0); HackEoi(); } -KIRQL FORCEINLINE +KIRQL ApicGetProcessorIrql(VOID) { /* Read the TPR and convert it to an IRQL */ return TprToIrql(ApicRead(APIC_PPR)); } -KIRQL FORCEINLINE +KIRQL ApicGetCurrentIrql(VOID) { #ifdef _M_AMD64 @@ -184,8 +184,8 @@ ApicGetCurrentIrql(VOID) #endif } -VOID FORCEINLINE +VOID ApicSetIrql(KIRQL Irql) { #ifdef _M_AMD64 @@ -200,8 +200,8 @@ ApicSetIrql(KIRQL Irql) #define ApicRaiseIrql ApicSetIrql #ifdef APIC_LAZY_IRQL -VOID FORCEINLINE +VOID ApicLowerIrql(KIRQL Irql) { __writefsbyte(FIELD_OFFSET(KPCR, Irql), Irql); diff --git a/hal/halx86/apic/apic.h b/hal/halx86/apic/apic.h index e016599c097..68c0ca6dcd4 100644 --- a/hal/halx86/apic/apic.h +++ b/hal/halx86/apic/apic.h @@ -258,15 +258,15 @@ typedef union _IOAPIC_REDIRECTION_REGISTER }; } IOAPIC_REDIRECTION_REGISTER; -ULONG FORCEINLINE +ULONG ApicRead(ULONG Offset) { return *(volatile ULONG *)(APIC_BASE + Offset); } -VOID FORCEINLINE +VOID ApicWrite(ULONG Offset, ULONG Value) { *(volatile ULONG *)(APIC_BASE + Offset) = Value; diff --git a/hal/halx86/apic/rtctimer.c b/hal/halx86/apic/rtctimer.c index 5b86a1682a5..654db2baf75 100644 --- a/hal/halx86/apic/rtctimer.c +++ b/hal/halx86/apic/rtctimer.c @@ -25,8 +25,8 @@ static UCHAR RtcMinimumClockRate = 6; /* Minimum rate 6: 16 Hz / 62.5 ms */ static UCHAR RtcMaximumClockRate = 10; /* Maximum rate 10: 256 Hz / 3.9 ms */ -ULONG FORCEINLINE +ULONG RtcClockRateToIncrement(UCHAR Rate) { ULONG Freqency = ((32768 << 1) >> Rate); diff --git a/hal/halx86/up/pic.c b/hal/halx86/up/pic.c index 8c9a2379265..052dc1bb5f9 100644 --- a/hal/halx86/up/pic.c +++ b/hal/halx86/up/pic.c @@ -782,8 +782,8 @@ HalpEndSoftwareInterrupt(IN KIRQL OldIrql, /* EDGE INTERRUPT DISMISSAL FUNCTIONS *****************************************/ -BOOLEAN FORCEINLINE +BOOLEAN _HalpDismissIrqGeneric(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql) @@ -925,8 +925,8 @@ HalpDismissIrq07(IN KIRQL Irql, /* LEVEL INTERRUPT DISMISSAL FUNCTIONS ****************************************/ -BOOLEAN FORCEINLINE +BOOLEAN _HalpDismissIrqLevel(IN KIRQL Irql, IN ULONG Irq, OUT PKIRQL OldIrql) @@ -1248,8 +1248,8 @@ HalEndSystemInterrupt(IN KIRQL OldIrql, /* SOFTWARE INTERRUPT TRAPS ***************************************************/ -VOID FORCEINLINE +VOID DECLSPEC_NORETURN _HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame) { @@ -1304,8 +1304,8 @@ HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame) _HalpApcInterruptHandler(TrapFrame); } -KIRQL FORCEINLINE +KIRQL _HalpDispatchInterruptHandler(VOID) { KIRQL CurrentIrql; diff --git a/include/crt/errno.h b/include/crt/errno.h index 8e8917b5458..48f749f6d64 100644 --- a/include/crt/errno.h +++ b/include/crt/errno.h @@ -69,6 +69,8 @@ extern "C" { #define EDEADLOCK EDEADLK +#define EWOULDBLOCK 140 + #ifdef __cplusplus } #endif diff --git a/include/psdk/CMakeLists.txt b/include/psdk/CMakeLists.txt index cc91fd0872c..6c915b08f72 100644 --- a/include/psdk/CMakeLists.txt +++ b/include/psdk/CMakeLists.txt @@ -18,6 +18,7 @@ list(APPEND SOURCE # binres.idl bits.idl bits1_5.idl + bits3_0.idl # cmdbas.idl # cmdtxt.idl comcat.idl diff --git a/include/psdk/bits.idl b/include/psdk/bits.idl index 89b916d0a2c..0e3362cc956 100644 --- a/include/psdk/bits.idl +++ b/include/psdk/bits.idl @@ -29,6 +29,7 @@ cpp_quote("#define BG_NOTIFY_JOB_TRANSFERRED 0x0001") cpp_quote("#define BG_NOTIFY_JOB_ERROR 0x0002") cpp_quote("#define BG_NOTIFY_DISABLE 0x0004") cpp_quote("#define BG_NOTIFY_JOB_MODIFICATION 0x0008") +cpp_quote("#define BG_NOTIFY_FILE_TRANSFERRED 0x0010") cpp_quote("#ifdef WINE_NO_UNICODE_MACROS") cpp_quote("#undef EnumJobs") @@ -413,3 +414,5 @@ library BackgroundCopyManager interface IBackgroundCopyCallback; } + +cpp_quote("#include \"bits1_5.h\"") diff --git a/include/psdk/bits3_0.idl b/include/psdk/bits3_0.idl new file mode 100644 index 00000000000..6cf48b7e193 --- /dev/null +++ b/include/psdk/bits3_0.idl @@ -0,0 +1,34 @@ +/* + * Background Intelligent Transfer Service (BITS) 3.0 interface + * + * Copyright 2013 Nikolay Sivov for CodeWeavers + * + * 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 + * + */ + +#ifndef DO_NO_IMPORTS +import "bits.idl"; +#endif + +[ + uuid(659cdeac-489e-11d9-a9cd-000d56965251), + odl +] +interface IBackgroundCopyCallback2 : IBackgroundCopyCallback +{ + HRESULT FileTransferred([in] IBackgroundCopyJob *job, + [in] IBackgroundCopyFile *file); +} diff --git a/include/psdk/driverspecs.h b/include/psdk/driverspecs.h index 162e8ec669c..783d9a36429 100644 --- a/include/psdk/driverspecs.h +++ b/include/psdk/driverspecs.h @@ -85,10 +85,10 @@ #define __drv_isCancelIRQL _IRQL_is_cancel_ #define __drv_isObjectPointer #define __drv_KMDF -#define __drv_maxFunctionIRQL -#define __drv_maxIRQL -#define __drv_minFunctionIRQL -#define __drv_minIRQL +#define __drv_maxFunctionIRQL(irql) +#define __drv_maxIRQL(irql) +#define __drv_minFunctionIRQL(irql) +#define __drv_minIRQL(irql) #define __drv_Mode_impl(x) #define __drv_mustHold(kind) #define __drv_mustHoldCancelSpinLock @@ -107,7 +107,7 @@ #define __drv_out_deref(annotes) #define __drv_out(annotes) #define __drv_preferredFunction(func,why) -#define __drv_raisesIRQL +#define __drv_raisesIRQL(irql) #define __drv_releasesCancelSpinLock #define __drv_releasesCriticalRegion #define __drv_releasesExclusiveResource(kind) @@ -116,7 +116,7 @@ #define __drv_releasesResource(kind) #define __drv_releasesResourceGlobal(kind,param) #define __drv_reportError(why) -#define __drv_requiresIRQL +#define __drv_requiresIRQL(irql) #define __drv_restoresIRQL #define __drv_restoresIRQLGlobal #define __drv_ret(annotes) @@ -159,7 +159,7 @@ __ANNOTATION(SAL_IoGetDmaAdapter(void);) #else /* Dummys */ -#define _Dispatch_type_ +#define _Dispatch_type_(type) #define _IRQL_always_function_max_(irql) #define _IRQL_always_function_min_(irql) #define _IRQL_is_cancel_ @@ -222,10 +222,10 @@ __ANNOTATION(SAL_IoGetDmaAdapter(void);) #define __drv_isCancelIRQL #define __drv_isObjectPointer #define __drv_KMDF -#define __drv_maxFunctionIRQL -#define __drv_maxIRQL -#define __drv_minFunctionIRQL -#define __drv_minIRQL +#define __drv_maxFunctionIRQL(irql) +#define __drv_maxIRQL(irql) +#define __drv_minFunctionIRQL(irql) +#define __drv_minIRQL(irql) #define __drv_Mode_impl(x) #define __drv_mustHold(kind) #define __drv_mustHoldCancelSpinLock @@ -244,7 +244,7 @@ __ANNOTATION(SAL_IoGetDmaAdapter(void);) #define __drv_out_deref(annotes) #define __drv_out(annotes) #define __drv_preferredFunction(func,why) -#define __drv_raisesIRQL +#define __drv_raisesIRQL(irql) #define __drv_releasesCancelSpinLock #define __drv_releasesCriticalRegion #define __drv_releasesExclusiveResource(kind) @@ -253,7 +253,7 @@ __ANNOTATION(SAL_IoGetDmaAdapter(void);) #define __drv_releasesResource(kind) #define __drv_releasesResourceGlobal(kind,param) #define __drv_reportError(why) -#define __drv_requiresIRQL +#define __drv_requiresIRQL(irql) #define __drv_restoresIRQL #define __drv_restoresIRQLGlobal #define __drv_ret(annotes) diff --git a/include/psdk/ks.h b/include/psdk/ks.h index d698620056b..eb5d2f5b2d6 100644 --- a/include/psdk/ks.h +++ b/include/psdk/ks.h @@ -2792,8 +2792,8 @@ struct _KSGATE { _IRQL_requires_max_(HIGH_LEVEL) static -void __inline +void KsGateTurnInputOn( _In_opt_ PKSGATE Gate) { @@ -2805,8 +2805,8 @@ KsGateTurnInputOn( _IRQL_requires_max_(HIGH_LEVEL) static -void __inline +void KsGateTurnInputOff( _In_opt_ PKSGATE Gate) { @@ -2818,8 +2818,8 @@ KsGateTurnInputOff( _IRQL_requires_max_(HIGH_LEVEL) static -BOOLEAN __inline +BOOLEAN KsGateGetStateUnsafe( _In_ PKSGATE Gate) { @@ -2829,8 +2829,8 @@ KsGateGetStateUnsafe( _IRQL_requires_max_(HIGH_LEVEL) static -BOOLEAN __inline +BOOLEAN KsGateCaptureThreshold( _In_ PKSGATE Gate) { @@ -2850,8 +2850,8 @@ KsGateCaptureThreshold( _IRQL_requires_max_(HIGH_LEVEL) static -void __inline +void KsGateInitialize( _In_ PKSGATE Gate, _In_ LONG InitialCount, @@ -2883,8 +2883,8 @@ KsGateInitialize( _IRQL_requires_max_(HIGH_LEVEL) static -void __inline +void KsGateInitializeAnd( _In_ PKSGATE AndGate, _In_opt_ PKSGATE NextOrGate) @@ -2894,8 +2894,8 @@ KsGateInitializeAnd( _IRQL_requires_max_(HIGH_LEVEL) static -void __inline +void KsGateInitializeOr( _In_ PKSGATE OrGate, _In_opt_ PKSGATE NextAndGate) @@ -2905,8 +2905,8 @@ KsGateInitializeOr( _IRQL_requires_max_(HIGH_LEVEL) static -void __inline +void KsGateAddOnInputToAnd( _In_ PKSGATE AndGate) { @@ -2915,8 +2915,8 @@ KsGateAddOnInputToAnd( _IRQL_requires_max_(HIGH_LEVEL) static -void __inline +void KsGateAddOffInputToAnd( _In_ PKSGATE AndGate) { @@ -2925,8 +2925,8 @@ KsGateAddOffInputToAnd( _IRQL_requires_max_(HIGH_LEVEL) static -void __inline +void KsGateRemoveOnInputFromAnd( _In_ PKSGATE AndGate) { @@ -2935,8 +2935,8 @@ KsGateRemoveOnInputFromAnd( _IRQL_requires_max_(HIGH_LEVEL) static -void __inline +void KsGateRemoveOffInputFromAnd( _In_ PKSGATE AndGate) { @@ -2945,8 +2945,8 @@ KsGateRemoveOffInputFromAnd( _IRQL_requires_max_(HIGH_LEVEL) static -void __inline +void KsGateAddOnInputToOr( _In_ PKSGATE OrGate) { @@ -2955,8 +2955,8 @@ KsGateAddOnInputToOr( _IRQL_requires_max_(HIGH_LEVEL) static -void __inline +void KsGateAddOffInputToOr( _In_ PKSGATE OrGate) { @@ -2965,8 +2965,8 @@ KsGateAddOffInputToOr( _IRQL_requires_max_(HIGH_LEVEL) static -void __inline +void KsGateRemoveOnInputFromOr( _In_ PKSGATE OrGate) { @@ -2975,8 +2975,8 @@ KsGateRemoveOnInputFromOr( _IRQL_requires_max_(HIGH_LEVEL) static -void __inline +void KsGateRemoveOffInputFromOr( _In_ PKSGATE OrGate) { @@ -2985,8 +2985,8 @@ KsGateRemoveOffInputFromOr( _IRQL_requires_max_(HIGH_LEVEL) static -void __inline +void KsGateTerminateAnd( _In_ PKSGATE AndGate) { @@ -3003,8 +3003,8 @@ KsGateTerminateAnd( _IRQL_requires_max_(HIGH_LEVEL) static -void __inline +void KsGateTerminateOr( _In_ PKSGATE OrGate) { @@ -4705,8 +4705,8 @@ KsGetParent( _IRQL_requires_max_(PASSIVE_LEVEL) static -PKSFILTERFACTORY __inline +PKSFILTERFACTORY KsFilterGetParentFilterFactory( _In_ PKSFILTER Filter) { @@ -4715,8 +4715,8 @@ KsFilterGetParentFilterFactory( _IRQL_requires_max_(PASSIVE_LEVEL) static -PKSDEVICE __inline +PKSDEVICE KsFilterFactoryGetParentDevice( _In_ PKSFILTERFACTORY FilterFactory) { @@ -4939,8 +4939,8 @@ KsFilterCreatePinFactory( _IRQL_requires_max_(PASSIVE_LEVEL) KSDDKAPI -PKSDEVICE __inline +PKSDEVICE KsFilterFactoryGetDevice( _In_ PKSFILTERFACTORY FilterFactory); diff --git a/include/psdk/mshtmdid.h b/include/psdk/mshtmdid.h index e57a3f81699..e65a049e749 100644 --- a/include/psdk/mshtmdid.h +++ b/include/psdk/mshtmdid.h @@ -112,6 +112,8 @@ #define DISPID_RULESAPPLIED_COLLECTION DISPID_NORMAL_FIRST #define DISPID_STYLESHEETRULESAPPLIED_COLLECTION DISPID_NORMAL_FIRST #define DISPID_PROCESSINGINSTRUCTION DISPID_NORMAL_FIRST +#define DISPID_HTMLSELECTION DISPID_NORMAL_FIRST +#define DISPID_DOMRANGE DISPID_NORMAL_FIRST #define DISPID_DOMEVENT DISPID_NORMAL_FIRST #define DISPID_DOMUIEVENT (DISPID_DOMEVENT+25) @@ -169,6 +171,10 @@ #define DISPID_IE8_OBJECTMAX (DISPID_STYLE-1) #define DISPID_IE8_OBJECT DISPID_IE8_OBJECTBASE +#define DISPID_IE9_ELEMENTBASE (DISPID_IE8_ELEMENTMAX + 10) +#define DISPID_IE9_ELEMENTMAX (DISPID_IE9_ELEMENTBASE + 35) +#define DISPID_IE9_ELEMENT DISPID_IE9_ELEMENTBASE + #define DISPID_COLLECTION (DISPID_NORMAL_FIRST+500) #define DISPID_OPTIONS_COL (DISPID_NORMAL_FIRST+500) #define DISPID_IMG (DISPID_IMGBASE+1000) @@ -1075,6 +1081,70 @@ #define DISPID_IHTMLDOCUMENT6_IE8_GETELEMENTBYID DISPID_OMDOCUMENT+105 #define DISPID_IHTMLDOCUMENT6_UPDATESETTINGS DISPID_OMDOCUMENT+106 +/* IHTMLDocument7 */ +#define DISPID_IHTMLDOCUMENT7_DEFAULTVIEW DISPID_OMDOCUMENT+110 +#define DISPID_IHTMLDOCUMENT7_CREATECDATASECTION DISPID_OMDOCUMENT+123 +#define DISPID_IHTMLDOCUMENT7_GETSELECTION DISPID_OMDOCUMENT+112 +#define DISPID_IHTMLDOCUMENT7_GETELEMENTSBYTAGNAMENS DISPID_OMDOCUMENT+113 +#define DISPID_IHTMLDOCUMENT7_CREATEELEMENTNS DISPID_OMDOCUMENT+114 +#define DISPID_IHTMLDOCUMENT7_CREATEATTRIBUTENS DISPID_OMDOCUMENT+115 +#define DISPID_IHTMLDOCUMENT7_ONMSTHUMBNAILCLICK DISPID_EVPROP_ONMSTHUMBNAILCLICK +#define DISPID_IHTMLDOCUMENT7_CHARACTERSET DISPID_OMDOCUMENT+117 +#define DISPID_IHTMLDOCUMENT7_IE9_CREATEELEMENT DISPID_OMDOCUMENT+118 +#define DISPID_IHTMLDOCUMENT7_IE9_CREATEATTRIBUTE DISPID_OMDOCUMENT+119 +#define DISPID_IHTMLDOCUMENT7_GETELEMENTSBYCLASSNAME DISPID_OMDOCUMENT+120 +#define DISPID_IHTMLDOCUMENT7_CREATEPROCESSINGINSTRUCTION DISPID_OMDOCUMENT+124 +#define DISPID_IHTMLDOCUMENT7_ADOPTNODE DISPID_OMDOCUMENT+125 +#define DISPID_IHTMLDOCUMENT7_ONMSSITEMODEJUMPLISTITEMREMOVED DISPID_EVPROP_ONMSSITEMODEJUMPLISTITEMREMOVED +#define DISPID_IHTMLDOCUMENT7_IE9_ALL DISPID_OMDOCUMENT+126 +#define DISPID_IHTMLDOCUMENT7_INPUTENCODING DISPID_OMDOCUMENT+127 +#define DISPID_IHTMLDOCUMENT7_XMLENCODING DISPID_OMDOCUMENT+128 +#define DISPID_IHTMLDOCUMENT7_XMLSTANDALONE DISPID_OMDOCUMENT+129 +#define DISPID_IHTMLDOCUMENT7_XMLVERSION DISPID_OMDOCUMENT+130 +#define DISPID_IHTMLDOCUMENT7_HASATTRIBUTES DISPID_OMDOCUMENT+132 +#define DISPID_IHTMLDOCUMENT7_ONABORT DISPID_EVPROP_ONABORT +#define DISPID_IHTMLDOCUMENT7_ONBLUR DISPID_EVPROP_ONBLUR +#define DISPID_IHTMLDOCUMENT7_ONCANPLAY DISPID_EVPROP_CANPLAY +#define DISPID_IHTMLDOCUMENT7_ONCANPLAYTHROUGH DISPID_EVPROP_CANPLAYTHROUGH +#define DISPID_IHTMLDOCUMENT7_ONCHANGE DISPID_EVPROP_ONCHANGE +#define DISPID_IHTMLDOCUMENT7_ONDRAG DISPID_EVPROP_ONDRAG +#define DISPID_IHTMLDOCUMENT7_ONDRAGEND DISPID_EVPROP_ONDRAGEND +#define DISPID_IHTMLDOCUMENT7_ONDRAGENTER DISPID_EVPROP_ONDRAGENTER +#define DISPID_IHTMLDOCUMENT7_ONDRAGLEAVE DISPID_EVPROP_ONDRAGLEAVE +#define DISPID_IHTMLDOCUMENT7_ONDRAGOVER DISPID_EVPROP_ONDRAGOVER +#define DISPID_IHTMLDOCUMENT7_ONDROP DISPID_EVPROP_ONDROP +#define DISPID_IHTMLDOCUMENT7_ONDURATIONCHANGE DISPID_EVPROP_DURATIONCHANGE +#define DISPID_IHTMLDOCUMENT7_ONEMPTIED DISPID_EVPROP_EMPTIED +#define DISPID_IHTMLDOCUMENT7_ONENDED DISPID_EVPROP_ENDED +#define DISPID_IHTMLDOCUMENT7_ONERROR DISPID_EVPROP_ONERROR +#define DISPID_IHTMLDOCUMENT7_ONFOCUS DISPID_EVPROP_ONFOCUS +#define DISPID_IHTMLDOCUMENT7_ONINPUT DISPID_EVPROP_INPUT +#define DISPID_IHTMLDOCUMENT7_ONLOAD DISPID_EVPROP_ONLOAD +#define DISPID_IHTMLDOCUMENT7_ONLOADEDDATA DISPID_EVPROP_LOADEDDATA +#define DISPID_IHTMLDOCUMENT7_ONLOADEDMETADATA DISPID_EVPROP_LOADEDMETADATA +#define DISPID_IHTMLDOCUMENT7_ONLOADSTART DISPID_EVPROP_LOADSTART +#define DISPID_IHTMLDOCUMENT7_ONPAUSE DISPID_EVPROP_PAUSE +#define DISPID_IHTMLDOCUMENT7_ONPLAY DISPID_EVPROP_PLAY +#define DISPID_IHTMLDOCUMENT7_ONPLAYING DISPID_EVPROP_PLAYING +#define DISPID_IHTMLDOCUMENT7_ONPROGRESS DISPID_EVPROP_PROGRESS +#define DISPID_IHTMLDOCUMENT7_ONRATECHANGE DISPID_EVPROP_RATECHANGE +#define DISPID_IHTMLDOCUMENT7_ONRESET DISPID_EVPROP_ONRESET +#define DISPID_IHTMLDOCUMENT7_ONSCROLL DISPID_EVPROP_ONSCROLL +#define DISPID_IHTMLDOCUMENT7_ONSEEKED DISPID_EVPROP_SEEKED +#define DISPID_IHTMLDOCUMENT7_ONSEEKING DISPID_EVPROP_SEEKING +#define DISPID_IHTMLDOCUMENT7_ONSELECT DISPID_EVPROP_ONSELECT +#define DISPID_IHTMLDOCUMENT7_ONSTALLED DISPID_EVPROP_STALLED +#define DISPID_IHTMLDOCUMENT7_ONSUBMIT DISPID_EVPROP_ONSUBMIT +#define DISPID_IHTMLDOCUMENT7_ONSUSPEND DISPID_EVPROP_SUSPEND +#define DISPID_IHTMLDOCUMENT7_ONTIMEUPDATE DISPID_EVPROP_TIMEUPDATE +#define DISPID_IHTMLDOCUMENT7_ONVOLUMECHANGE DISPID_EVPROP_VOLUMECHANGE +#define DISPID_IHTMLDOCUMENT7_ONWAITING DISPID_EVPROP_WAITING +#define DISPID_IHTMLDOCUMENT7_NORMALIZE DISPID_OMDOCUMENT+134 +#define DISPID_IHTMLDOCUMENT7_IMPORTNODE DISPID_OMDOCUMENT+135 +#define DISPID_IHTMLDOCUMENT7_IE9_PARENTWINDOW DISPID_OMDOCUMENT+136 +#define DISPID_IHTMLDOCUMENT7_IE9_BODY DISPID_OMDOCUMENT+137 +#define DISPID_IHTMLDOCUMENT7_HEAD DISPID_OMDOCUMENT+138 + /* DWebBridgeEvents */ #define DISPID_DWEBBRIDGEEVENTS_ONSCRIPTLETEVENT 1 #define DISPID_DWEBBRIDGEEVENTS_ONREADYSTATECHANGE DISPID_HTMLDOCUMENTEVENTS_ONREADYSTATECHANGE @@ -1689,6 +1759,24 @@ #define DISPID_IHTMLSELECTIONOBJECT_CLEAR (DISPID_SELECTOBJ+3) #define DISPID_IHTMLSELECTIONOBJECT_TYPE (DISPID_SELECTOBJ+4) +/* IHTMLSelection */ +#define DISPID_IHTMLSELECTION_ANCHORNODE DISPID_HTMLSELECTION+1 +#define DISPID_IHTMLSELECTION_ANCHOROFFSET DISPID_HTMLSELECTION+2 +#define DISPID_IHTMLSELECTION_FOCUSNODE DISPID_HTMLSELECTION+3 +#define DISPID_IHTMLSELECTION_FOCUSOFFSET DISPID_HTMLSELECTION+4 +#define DISPID_IHTMLSELECTION_ISCOLLAPSED DISPID_HTMLSELECTION+5 +#define DISPID_IHTMLSELECTION_COLLAPSE DISPID_HTMLSELECTION+6 +#define DISPID_IHTMLSELECTION_COLLAPSETOSTART DISPID_HTMLSELECTION+7 +#define DISPID_IHTMLSELECTION_COLLAPSETOEND DISPID_HTMLSELECTION+8 +#define DISPID_IHTMLSELECTION_SELECTALLCHILDREN DISPID_HTMLSELECTION+9 +#define DISPID_IHTMLSELECTION_DELETEFROMDOCUMENT DISPID_HTMLSELECTION+10 +#define DISPID_IHTMLSELECTION_RANGECOUNT DISPID_HTMLSELECTION+11 +#define DISPID_IHTMLSELECTION_GETRANGEAT DISPID_HTMLSELECTION+12 +#define DISPID_IHTMLSELECTION_ADDRANGE DISPID_HTMLSELECTION+13 +#define DISPID_IHTMLSELECTION_REMOVERANGE DISPID_HTMLSELECTION+14 +#define DISPID_IHTMLSELECTION_REMOVEALLRANGES DISPID_HTMLSELECTION+15 +#define DISPID_IHTMLSELECTION_TOSTRING DISPID_HTMLSELECTION+16 + /* IHTMLFramesCollection2 */ #define DISPID_IHTMLFRAMESCOLLECTION2_ITEM 0 #define DISPID_IHTMLFRAMESCOLLECTION2_LENGTH 1001 @@ -2224,6 +2312,23 @@ #define DISPID_IHTMLDOMNODE_PREVIOUSSIBLING DISPID_ELEMENT+78 #define DISPID_IHTMLDOMNODE_NEXTSIBLING DISPID_ELEMENT+79 +/* IHTMLDOMNode3 */ +#define DISPID_IHTMLDOMNODE3_PREFIX DISPID_ELEMENT+120 +#define DISPID_IHTMLDOMNODE3_LOCALNAME DISPID_ELEMENT+118 +#define DISPID_IHTMLDOMNODE3_NAMESPACEURI DISPID_ELEMENT+119 +#define DISPID_IHTMLDOMNODE3_TEXTCONTENT DISPID_ELEMENT+127 +#define DISPID_IHTMLDOMNODE3_ISEQUALNODE DISPID_ELEMENT+121 +#define DISPID_IHTMLDOMNODE3_LOOKUPNAMESPACEURI DISPID_ELEMENT+122 +#define DISPID_IHTMLDOMNODE3_LOOKUPPREFIX DISPID_ELEMENT+123 +#define DISPID_IHTMLDOMNODE3_ISDEFAULTNAMESPACE DISPID_ELEMENT+124 +#define DISPID_IHTMLDOMNODE3_IE9_APPENDCHILD DISPID_IE9_ELEMENT+18 +#define DISPID_IHTMLDOMNODE3_IE9_INSERTBEFORE DISPID_IE9_ELEMENT+19 +#define DISPID_IHTMLDOMNODE3_IE9_REMOVECHILD DISPID_IE9_ELEMENT+20 +#define DISPID_IHTMLDOMNODE3_IE9_REPLACECHILD DISPID_IE9_ELEMENT+21 +#define DISPID_IHTMLDOMNODE3_ISSAMENODE DISPID_ELEMENT+125 +#define DISPID_IHTMLDOMNODE3_COMPAREDOCUMENTPOSITION DISPID_ELEMENT+126 +#define DISPID_IHTMLDOMNODE3_ISSUPPORTED DISPID_IE9_ELEMENT+27 + /* IHTMLLinkElement */ #define DISPID_IHTMLLINKELEMENT_HREF DISPID_HEDELEMS+5 #define DISPID_IHTMLLINKELEMENT_REL DISPID_HEDELEMS+6 @@ -2432,6 +2537,34 @@ #define DISPID_IHTMLTEXTAREAELEMENT_WRAP DISPID_RICHTEXT+3 #define DISPID_IHTMLTEXTAREAELEMENT_CREATETEXTRANGE DISPID_RICHTEXT+6 +/* IHTMLDOMRange */ +#define DISPID_IHTMLDOMRANGE_STARTCONTAINER DISPID_DOMRANGE+1 +#define DISPID_IHTMLDOMRANGE_STARTOFFSET DISPID_DOMRANGE+2 +#define DISPID_IHTMLDOMRANGE_ENDCONTAINER DISPID_DOMRANGE+3 +#define DISPID_IHTMLDOMRANGE_ENDOFFSET DISPID_DOMRANGE+4 +#define DISPID_IHTMLDOMRANGE_COLLAPSED DISPID_DOMRANGE+5 +#define DISPID_IHTMLDOMRANGE_COMMONANCESTORCONTAINER DISPID_DOMRANGE+6 +#define DISPID_IHTMLDOMRANGE_SETSTART DISPID_DOMRANGE+7 +#define DISPID_IHTMLDOMRANGE_SETEND DISPID_DOMRANGE+8 +#define DISPID_IHTMLDOMRANGE_SETSTARTBEFORE DISPID_DOMRANGE+9 +#define DISPID_IHTMLDOMRANGE_SETSTARTAFTER DISPID_DOMRANGE+10 +#define DISPID_IHTMLDOMRANGE_SETENDBEFORE DISPID_DOMRANGE+11 +#define DISPID_IHTMLDOMRANGE_SETENDAFTER DISPID_DOMRANGE+12 +#define DISPID_IHTMLDOMRANGE_COLLAPSE DISPID_DOMRANGE+13 +#define DISPID_IHTMLDOMRANGE_SELECTNODE DISPID_DOMRANGE+14 +#define DISPID_IHTMLDOMRANGE_SELECTNODECONTENTS DISPID_DOMRANGE+15 +#define DISPID_IHTMLDOMRANGE_COMPAREBOUNDARYPOINTS DISPID_DOMRANGE+16 +#define DISPID_IHTMLDOMRANGE_DELETECONTENTS DISPID_DOMRANGE+17 +#define DISPID_IHTMLDOMRANGE_EXTRACTCONTENTS DISPID_DOMRANGE+18 +#define DISPID_IHTMLDOMRANGE_CLONECONTENTS DISPID_DOMRANGE+19 +#define DISPID_IHTMLDOMRANGE_INSERTNODE DISPID_DOMRANGE+20 +#define DISPID_IHTMLDOMRANGE_SURROUNDCONTENTS DISPID_DOMRANGE+21 +#define DISPID_IHTMLDOMRANGE_CLONERANGE DISPID_DOMRANGE+22 +#define DISPID_IHTMLDOMRANGE_TOSTRING DISPID_DOMRANGE+23 +#define DISPID_IHTMLDOMRANGE_DETACH DISPID_DOMRANGE+24 +#define DISPID_IHTMLDOMRANGE_GETCLIENTRECTS DISPID_DOMRANGE+25 +#define DISPID_IHTMLDOMRANGE_GETBOUNDINGCLIENTRECT DISPID_DOMRANGE+26 + /* IHTMLButtonElement */ #define DISPID_IHTMLBUTTONELEMENT_TYPE DISPID_INPUT #define DISPID_IHTMLBUTTONELEMENT_VALUE DISPID_A_VALUE @@ -3093,4 +3226,8 @@ #define DISPID_IHTMLCONTROLELEMENT_CLIENTTOP (DISPID_SITE+21) #define DISPID_IHTMLCONTROLELEMENT_CLIENTLEFT (DISPID_SITE+22) +/* IDOMProcessingInstruction */ +#define DISPID_IDOMPROCESSINGINSTRUCTION_TARGET DISPID_PROCESSINGINSTRUCTION +#define DISPID_IDOMPROCESSINGINSTRUCTION_DATA DISPID_PROCESSINGINSTRUCTION+1 + #endif /* __MSHTMDID_H__ */ diff --git a/include/psdk/mshtml.idl b/include/psdk/mshtml.idl index 8bed5e79088..0c5a8746ec8 100644 --- a/include/psdk/mshtml.idl +++ b/include/psdk/mshtml.idl @@ -21,10 +21,6 @@ #include #include -#if defined(_MSC_VER) && (__midl >= 501) -midl_pragma warning(disable: 2362) -#endif - import "ocidl.idl"; import "dimm.idl"; import "shtypes.idl"; @@ -3881,6 +3877,94 @@ interface IHTMLDOMNode2 : IDispatch WINE_IHTMLDOMNODE_DISPINTERFACE_DECL; \ WINE_IHTMLDOMNODE2_DISPINTERFACE_DECL +/***************************************************************************** + * IHTMLDOMNode3 interface + */ +[ + odl, + oleautomation, + dual, + uuid(305106e0-98b5-11cf-bb82-00aa00bdce0b) +] +interface IHTMLDOMNode3 : IDispatch +{ + [propput, id(DISPID_IHTMLDOMNODE3_PREFIX)] + HRESULT prefix([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOMNODE3_PREFIX)] + HRESULT prefix([out, retval] VARIANT *p); + + [propget, id(DISPID_IHTMLDOMNODE3_LOCALNAME)] + HRESULT localName([out, retval] VARIANT *p); + + [propget, id(DISPID_IHTMLDOMNODE3_NAMESPACEURI)] + HRESULT namespaceURI([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOMNODE3_TEXTCONTENT)] + HRESULT textContent([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOMNODE3_TEXTCONTENT)] + HRESULT textContent([out, retval] VARIANT *p); + + [id(DISPID_IHTMLDOMNODE3_ISEQUALNODE)] + HRESULT isEqualNode( + [in] IHTMLDOMNode3 *otherNode, + [out, retval] VARIANT_BOOL *isEqual); + + [id(DISPID_IHTMLDOMNODE3_LOOKUPNAMESPACEURI)] + HRESULT lookupNamespaceURI( + [in] VARIANT *pvarPrefix, + [out, retval] VARIANT *pvarNamespaceURI); + + [id(DISPID_IHTMLDOMNODE3_LOOKUPPREFIX)] + HRESULT lookupPrefix( + [in] VARIANT *pvarNamespaceURI, + [out, retval] VARIANT *pvarPrefix); + + [id(DISPID_IHTMLDOMNODE3_ISDEFAULTNAMESPACE)] + HRESULT isDefaultNamespace( + [in] VARIANT *pvarNamespace, + [out, retval] VARIANT_BOOL *pfDefaultNamespace); + + [id(DISPID_IHTMLDOMNODE3_IE9_APPENDCHILD)] + HRESULT appendChild( + [in] IHTMLDOMNode *newChild, + [out, retval] IHTMLDOMNode **node); + + [id(DISPID_IHTMLDOMNODE3_IE9_INSERTBEFORE)] + HRESULT insertBefore( + [in] IHTMLDOMNode *newChild, + [in, optional] VARIANT refChild, + [out, retval] IHTMLDOMNode **node); + + [id(DISPID_IHTMLDOMNODE3_IE9_REMOVECHILD)] + HRESULT removeChild( + [in] IHTMLDOMNode *oldChild, + [out, retval] IHTMLDOMNode **node); + + [id(DISPID_IHTMLDOMNODE3_IE9_REPLACECHILD)] + HRESULT replaceChild( + [in] IHTMLDOMNode *newChild, + [in] IHTMLDOMNode *oldChild, + [out, retval] IHTMLDOMNode **node); + + [id(DISPID_IHTMLDOMNODE3_ISSAMENODE)] + HRESULT isSameNode( + [in] IHTMLDOMNode3 *otherNode, + [out, retval] VARIANT_BOOL *isSame); + + [id(DISPID_IHTMLDOMNODE3_COMPAREDOCUMENTPOSITION)] + HRESULT compareDocumentPosition( + [in] IHTMLDOMNode *otherNode, + [out, retval] USHORT *flags); + + [id(DISPID_IHTMLDOMNODE3_ISSUPPORTED)] + HRESULT isSupported( + [in] BSTR feature, + [in] VARIANT version, + [out, retval] VARIANT_BOOL *pfisSupported); +} + /***************************************************************************** * IHTMLDOMAttribute interface */ @@ -7154,6 +7238,103 @@ interface IHTMLTxtRange : IDispatch [retval, out] VARIANT_BOOL *pfRet); } +/***************************************************************************** + * IHTMLDOMRange interface + */ +[ + odl, + oleautomation, + dual, + uuid(305104ae-98b5-11cf-bb82-00aa00bdce0b) +] +interface IHTMLDOMRange : IDispatch +{ + [propget, id(DISPID_IHTMLDOMRANGE_STARTCONTAINER)] + HRESULT startContainer([out, retval] IHTMLDOMNode **p); + + [propget, id(DISPID_IHTMLDOMRANGE_STARTOFFSET)] + HRESULT startOffset([out, retval] long *p); + + [propget, id(DISPID_IHTMLDOMRANGE_ENDCONTAINER)] + HRESULT endContainer([out, retval] IHTMLDOMNode **p); + + [propget, id(DISPID_IHTMLDOMRANGE_ENDOFFSET)] + HRESULT endOffset([out, retval] long *p); + + [propget, id(DISPID_IHTMLDOMRANGE_COLLAPSED)] + HRESULT collapsed([out, retval] VARIANT_BOOL *p); + + [propget, id(DISPID_IHTMLDOMRANGE_COMMONANCESTORCONTAINER)] + HRESULT commonAncestorContainer([out, retval] IHTMLDOMNode **p); + + [id(DISPID_IHTMLDOMRANGE_SETSTART)] + HRESULT setStart( + [in] IDispatch *refNode, + [in] long offset); + + [id(DISPID_IHTMLDOMRANGE_SETEND)] HRESULT + setEnd( + [in] IDispatch *refNode, + [in] long offset); + + [id(DISPID_IHTMLDOMRANGE_SETSTARTBEFORE)] + HRESULT setStartBefore([in] IDispatch* refNode); + + [id(DISPID_IHTMLDOMRANGE_SETSTARTAFTER)] + HRESULT setStartAfter([in] IDispatch *refNode); + + [id(DISPID_IHTMLDOMRANGE_SETENDBEFORE)] + HRESULT setEndBefore([in] IDispatch *refNode); + + [id(DISPID_IHTMLDOMRANGE_SETENDAFTER)] + HRESULT setEndAfter([in] IDispatch *refNode); + + [id(DISPID_IHTMLDOMRANGE_COLLAPSE)] + HRESULT collapse([in] VARIANT_BOOL toStart); + + [id(DISPID_IHTMLDOMRANGE_SELECTNODE)] + HRESULT selectNode([in] IDispatch *refNode); + + [id(DISPID_IHTMLDOMRANGE_SELECTNODECONTENTS)] + HRESULT selectNodeContents([in] IDispatch *refNode); + + [id(DISPID_IHTMLDOMRANGE_COMPAREBOUNDARYPOINTS)] + HRESULT compareBoundaryPoints( + [in] short how, + [in] IDispatch *sourceRange, + [out, retval] long *compareResult); + + [id(DISPID_IHTMLDOMRANGE_DELETECONTENTS)] + HRESULT deleteContents(); + + [id(DISPID_IHTMLDOMRANGE_EXTRACTCONTENTS)] + HRESULT extractContents([out, retval] IDispatch **ppDocumentFragment); + + [id(DISPID_IHTMLDOMRANGE_CLONECONTENTS)] + HRESULT cloneContents([out, retval] IDispatch **ppDocumentFragment); + + [id(DISPID_IHTMLDOMRANGE_INSERTNODE)] + HRESULT insertNode([in] IDispatch *newNode); + + [id(DISPID_IHTMLDOMRANGE_SURROUNDCONTENTS)] + HRESULT surroundContents([in] IDispatch *newParent); + + [id(DISPID_IHTMLDOMRANGE_CLONERANGE)] + HRESULT cloneRange([out, retval] IHTMLDOMRange **ppClonedRange); + + [id(DISPID_IHTMLDOMRANGE_TOSTRING)] + HRESULT toString([out, retval] BSTR *pRangeString); + + [id(DISPID_IHTMLDOMRANGE_DETACH)] + HRESULT detach(); + + [id(DISPID_IHTMLDOMRANGE_GETCLIENTRECTS)] + HRESULT getClientRects([out, retval] IHTMLRectCollection **ppRectCol); + + [id(DISPID_IHTMLDOMRANGE_GETBOUNDINGCLIENTRECT)] + HRESULT getBoundingClientRect([out, retval] IHTMLRect **ppRect); +} + [ noncreatable, uuid(3050f37f-98b5-11cf-bb82-00aa00bdce0b) @@ -9312,6 +9493,70 @@ interface IHTMLSelectionObject : IDispatch HRESULT type([retval, out] BSTR *p); } +/***************************************************************************** + * IHTMLSelection interface + */ +[ + odl, + oleautomation, + dual, + uuid(305104b6-98b5-11cf-bb82-00aa00bdce0b) +] +interface IHTMLSelection : IDispatch +{ + [propget, id(DISPID_IHTMLSELECTION_ANCHORNODE)] + HRESULT anchorNode([out, retval] IHTMLDOMNode **p); + + [propget, id(DISPID_IHTMLSELECTION_ANCHOROFFSET)] + HRESULT anchorOffset([out, retval] long *p); + + [propget, id(DISPID_IHTMLSELECTION_FOCUSNODE)] + HRESULT focusNode([out, retval] IHTMLDOMNode **p); + + [propget, id(DISPID_IHTMLSELECTION_FOCUSOFFSET)] + HRESULT focusOffset([out, retval] long *p); + + [propget, id(DISPID_IHTMLSELECTION_ISCOLLAPSED)] + HRESULT isCollapsed([out, retval] VARIANT_BOOL *p); + + [id(DISPID_IHTMLSELECTION_COLLAPSE)] + HRESULT collapse( + [in] IDispatch *parentNode, + [in] long offfset); + + [id(DISPID_IHTMLSELECTION_COLLAPSETOSTART)] + HRESULT collapseToStart(); + + [id(DISPID_IHTMLSELECTION_COLLAPSETOEND)] + HRESULT collapseToEnd(); + + [id(DISPID_IHTMLSELECTION_SELECTALLCHILDREN)] + HRESULT selectAllChildren([in] IDispatch *parentNode); + + [id(DISPID_IHTMLSELECTION_DELETEFROMDOCUMENT)] + HRESULT deleteFromDocument(); + + [propget, id(DISPID_IHTMLSELECTION_RANGECOUNT)] + HRESULT rangeCount([out, retval] long *p); + + [id(DISPID_IHTMLSELECTION_GETRANGEAT)] + HRESULT getRangeAt( + [in] long index, + [out, retval] IHTMLDOMRange **ppRange); + + [id(DISPID_IHTMLSELECTION_ADDRANGE)] + HRESULT addRange([in] IDispatch *range); + + [id(DISPID_IHTMLSELECTION_REMOVERANGE)] + HRESULT removeRange([in] IDispatch *range); + + [id(DISPID_IHTMLSELECTION_REMOVEALLRANGES)] + HRESULT removeAllRanges(); + + [id(DISPID_IHTMLSELECTION_TOSTRING)] + HRESULT toString([out, retval] BSTR *pSelectionString); +} + /***************************************************************************** * IHTMLOptionElement interface */ @@ -13341,6 +13586,27 @@ methods: void onselect([in] IHTMLEventObj* pEvtObj); } +/***************************************************************************** + * IDOMProcessingInstruction interface + */ +[ + odl, + oleautomation, + dual, + uuid(30510742-98b5-11cf-bb82-00aa00bdce0b) +] +interface IDOMProcessingInstruction : IDispatch +{ + [propget, id(DISPID_IDOMPROCESSINGINSTRUCTION_TARGET)] + HRESULT target([out, retval] BSTR *p); + + [propput, id(DISPID_IDOMPROCESSINGINSTRUCTION_DATA)] + HRESULT data([in] BSTR v); + + [propget, id(DISPID_IDOMPROCESSINGINSTRUCTION_DATA)] + HRESULT data([out, retval] BSTR *p); +} + /***************************************************************************** * IHTMLDocument interface */ @@ -14046,6 +14312,355 @@ interface IHTMLDocument6 : IDispatch HRESULT updateSettings(); } +/***************************************************************************** + * IHTMLDocument7 interface + */ +[ + odl, + oleautomation, + dual, + uuid(305104b8-98b5-11cf-bb82-00aa00bdce0b) +] +interface IHTMLDocument7 : IDispatch +{ + [propget, id(DISPID_IHTMLDOCUMENT7_DEFAULTVIEW)] + HRESULT defaultView([out, retval] IHTMLWindow2 **p); + + [id(DISPID_IHTMLDOCUMENT7_CREATECDATASECTION)] + HRESULT createCDATASection( + [in] BSTR text, + [out, retval] IHTMLDOMNode **newCDATASectionNode); + + [id(DISPID_IHTMLDOCUMENT7_GETSELECTION)] + HRESULT getSelection([out, retval] IHTMLSelection **ppIHTMLSelection); + + [id(DISPID_IHTMLDOCUMENT7_GETELEMENTSBYTAGNAMENS)] + HRESULT getElementsByTagNameNS( + [in] VARIANT *pvarNS, + [in] BSTR bstrLocalName, + [out, retval] IHTMLElementCollection **pelColl); + + [id(DISPID_IHTMLDOCUMENT7_CREATEELEMENTNS)] + HRESULT createElementNS( + [in] VARIANT *pvarNS, + [in] BSTR bstrTag, + [out, retval] IHTMLElement **newElem); + + [id(DISPID_IHTMLDOCUMENT7_CREATEATTRIBUTENS)] + HRESULT createAttributeNS( + [in] VARIANT *pvarNS, + [in] BSTR bstrAttrName, + [out, retval] IHTMLDOMAttribute **ppAttribute); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONMSTHUMBNAILCLICK), displaybind, bindable] + HRESULT onmsthumbnailclick([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONMSTHUMBNAILCLICK), displaybind, bindable] + HRESULT onmsthumbnailclick([out, retval] VARIANT *p); + + [propget, id(DISPID_IHTMLDOCUMENT7_CHARACTERSET)] + HRESULT characterSet([out, retval] BSTR *p); + + [id(DISPID_IHTMLDOCUMENT7_IE9_CREATEELEMENT)] + HRESULT createElement( + [in] BSTR bstrTag, + [out, retval] IHTMLElement **newElem); + + [id(DISPID_IHTMLDOCUMENT7_IE9_CREATEATTRIBUTE)] + HRESULT createAttribute( + [in] BSTR bstrAttrName, + [out, retval] IHTMLDOMAttribute **ppAttribute); + + [id(DISPID_IHTMLDOCUMENT7_GETELEMENTSBYCLASSNAME)] + HRESULT getElementsByClassName( + [in] BSTR v, + [out, retval] IHTMLElementCollection **pel); + + [id(DISPID_IHTMLDOCUMENT7_CREATEPROCESSINGINSTRUCTION)] + HRESULT createProcessingInstruction( + [in] BSTR bstrTarget, + [in] BSTR bstrData, + [out, retval] IDOMProcessingInstruction **newProcessingInstruction); + + [id(DISPID_IHTMLDOCUMENT7_ADOPTNODE)] + HRESULT adoptNode( + [in] IHTMLDOMNode *pNodeSource, + [out, retval] IHTMLDOMNode3 **ppNodeDest); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONMSSITEMODEJUMPLISTITEMREMOVED), displaybind, bindable] + HRESULT onmssitemodejumplistitemremoved([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONMSSITEMODEJUMPLISTITEMREMOVED), displaybind, bindable] + HRESULT onmssitemodejumplistitemremoved([out, retval] VARIANT *p); + + [propget, id(DISPID_IHTMLDOCUMENT7_IE9_ALL)] + HRESULT all([out, retval] IHTMLElementCollection **p); + + [propget, id(DISPID_IHTMLDOCUMENT7_INPUTENCODING)] + HRESULT inputEncoding([out, retval] BSTR *p); + + [propget, id(DISPID_IHTMLDOCUMENT7_XMLENCODING)] + HRESULT xmlEncoding([out, retval] BSTR *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_XMLSTANDALONE)] + HRESULT xmlStandalone([in] VARIANT_BOOL v); + + [propget, id(DISPID_IHTMLDOCUMENT7_XMLSTANDALONE)] + HRESULT xmlStandalone([out, retval] VARIANT_BOOL *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_XMLVERSION)] + HRESULT xmlVersion([in] BSTR v); + + [propget, id(DISPID_IHTMLDOCUMENT7_XMLVERSION)] + HRESULT xmlVersion([out, retval] BSTR *p); + + [id(DISPID_IHTMLDOCUMENT7_HASATTRIBUTES)] + HRESULT hasAttributes([out, retval] VARIANT_BOOL *pfHasAttributes); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONABORT), displaybind, bindable] + HRESULT onabort([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONABORT), displaybind, bindable] + HRESULT onabort([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONBLUR), displaybind, bindable] + HRESULT onblur([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONBLUR), displaybind, bindable] + HRESULT onblur([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONCANPLAY), displaybind, bindable] + HRESULT oncanplay([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONCANPLAY), displaybind, bindable] + HRESULT oncanplay([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONCANPLAYTHROUGH), displaybind, bindable] + HRESULT oncanplaythrough([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONCANPLAYTHROUGH), displaybind, bindable] + HRESULT oncanplaythrough([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONCHANGE), displaybind, bindable] + HRESULT onchange([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONCHANGE), displaybind, bindable] + HRESULT onchange([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONDRAG), displaybind, bindable] + HRESULT ondrag([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONDRAG), displaybind, bindable] + HRESULT ondrag([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONDRAGEND), displaybind, bindable] + HRESULT ondragend([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONDRAGEND), displaybind, bindable] + HRESULT ondragend([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONDRAGENTER), displaybind, bindable] + HRESULT ondragenter([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONDRAGENTER), displaybind, bindable] + HRESULT ondragenter([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONDRAGLEAVE), displaybind, bindable] + HRESULT ondragleave([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONDRAGLEAVE), displaybind, bindable] + HRESULT ondragleave([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONDRAGOVER), displaybind, bindable] + HRESULT ondragover([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONDRAGOVER), displaybind, bindable] + HRESULT ondragover([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONDROP), displaybind, bindable] + HRESULT ondrop([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONDROP), displaybind, bindable] + HRESULT ondrop([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONDURATIONCHANGE), displaybind, bindable] + HRESULT ondurationchange([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONDURATIONCHANGE), displaybind, bindable] + HRESULT ondurationchange([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONEMPTIED), displaybind, bindable] + HRESULT onemptied([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONEMPTIED), displaybind, bindable] + HRESULT onemptied([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONENDED), displaybind, bindable] + HRESULT onended([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONENDED), displaybind, bindable] + HRESULT onended([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONERROR), displaybind, bindable] + HRESULT onerror([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONERROR), displaybind, bindable] + HRESULT onerror([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONFOCUS), displaybind, bindable] + HRESULT onfocus([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONFOCUS), displaybind, bindable] + HRESULT onfocus([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONINPUT), displaybind, bindable] + HRESULT oninput([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONINPUT), displaybind, bindable] + HRESULT oninput([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONLOAD), displaybind, bindable] + HRESULT onload([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONLOAD), displaybind, bindable] + HRESULT onload([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONLOADEDDATA), displaybind, bindable] + HRESULT onloadeddata([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONLOADEDDATA), displaybind, bindable] + HRESULT onloadeddata([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONLOADEDMETADATA), displaybind, bindable] + HRESULT onloadedmetadata([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONLOADEDMETADATA), displaybind, bindable] + HRESULT onloadedmetadata([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONLOADSTART), displaybind, bindable] + HRESULT onloadstart([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONLOADSTART), displaybind, bindable] + HRESULT onloadstart([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONPAUSE), displaybind, bindable] + HRESULT onpause([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONPAUSE), displaybind, bindable] + HRESULT onpause([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONPLAY), displaybind, bindable] + HRESULT onplay([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONPLAY), displaybind, bindable] + HRESULT onplay([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONPLAYING), displaybind, bindable] + HRESULT onplaying([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONPLAYING), displaybind, bindable] + HRESULT onplaying([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONPROGRESS), displaybind, bindable] + HRESULT onprogress([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONPROGRESS), displaybind, bindable] + HRESULT onprogress([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONRATECHANGE), displaybind, bindable] + HRESULT onratechange([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONRATECHANGE), displaybind, bindable] + HRESULT onratechange([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONRESET), displaybind, bindable] + HRESULT onreset([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONRESET), displaybind, bindable] + HRESULT onreset([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONSCROLL), displaybind, bindable] + HRESULT onscroll([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONSCROLL), displaybind, bindable] + HRESULT onscroll([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONSEEKED), displaybind, bindable] + HRESULT onseeked([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONSEEKED), displaybind, bindable] + HRESULT onseeked([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONSEEKING), displaybind, bindable] + HRESULT onseeking([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONSEEKING), displaybind, bindable] + HRESULT onseeking([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONSELECT), displaybind, bindable] + HRESULT onselect([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONSELECT), displaybind, bindable] + HRESULT onselect([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONSTALLED), displaybind, bindable] + HRESULT onstalled([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONSTALLED), displaybind, bindable] + HRESULT onstalled([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONSUBMIT), displaybind, bindable] + HRESULT onsubmit([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONSUBMIT), displaybind, bindable] + HRESULT onsubmit([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONSUSPEND), displaybind, bindable] + HRESULT onsuspend([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONSUSPEND), displaybind, bindable] + HRESULT onsuspend([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONTIMEUPDATE), displaybind, bindable] + HRESULT ontimeupdate([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONTIMEUPDATE), displaybind, bindable] + HRESULT ontimeupdate([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONVOLUMECHANGE), displaybind, bindable] + HRESULT onvolumechange([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONVOLUMECHANGE), displaybind, bindable] + HRESULT onvolumechange([out, retval] VARIANT *p); + + [propput, id(DISPID_IHTMLDOCUMENT7_ONWAITING), displaybind, bindable] + HRESULT onwaiting([in] VARIANT v); + + [propget, id(DISPID_IHTMLDOCUMENT7_ONWAITING), displaybind, bindable] + HRESULT onwaiting([out, retval] VARIANT *p); + + [id(DISPID_IHTMLDOCUMENT7_NORMALIZE)] + HRESULT normalize(); + + [id(DISPID_IHTMLDOCUMENT7_IMPORTNODE)] + HRESULT importNode( + [in] IHTMLDOMNode *pNodeSource, + [in] VARIANT_BOOL fDeep, + [out, retval] IHTMLDOMNode3 **ppNodeDest); + + [propget, id(DISPID_IHTMLDOCUMENT7_IE9_PARENTWINDOW)] + HRESULT parentWindow([out, retval] IHTMLWindow2 **p); + + [propputref, id(DISPID_IHTMLDOCUMENT7_IE9_BODY)] + HRESULT body([in] IHTMLElement *v); + + [propget, id(DISPID_IHTMLDOCUMENT7_IE9_BODY)] + HRESULT body([out, retval] IHTMLElement **p); + + [propget, id(DISPID_IHTMLDOCUMENT7_HEAD)] + HRESULT head([out, retval] IHTMLElement **p); +} + /***************************************************************************** * DispHTMLDocument dispinterface */ @@ -18520,3 +19135,55 @@ interface IHTMLPrivateWindow : IUnknown HRESULT FindWindowByName(LPCWSTR name, IHTMLWindow2 **ret); HRESULT GetAddressBarUrl(BSTR *url); } + +/***************************************************************************** + * IWebBrowserPriv interface + */ +[ + object, + uuid(3050f804-98b5-11cf-bb82-00aa00bdce0b), + local +] +interface IWebBrowserPriv : IUnknown +{ + HRESULT NavigateWithBindCtx(VARIANT *uri, VARIANT *flags, VARIANT *target_frame, VARIANT *post_data, + VARIANT *headers, IBindCtx *bind_ctx, LPOLESTR url_fragment); + HRESULT OnClose(); +} + +/***************************************************************************** + * IWebBrowserPriv2IE8 interface + */ +[ + object, + uuid(3ed72303-6ffc-4214-ba90-faf1862dec8a), + local +] +interface IWebBrowserPriv2IE8 : IUnknown +{ + HRESULT NavigateWithBindCtx2(IUri *uri, VARIANT *flags, VARIANT *target_frame, VARIANT *post_data, + VARIANT *headers, IBindCtx *bind_ctx, LPOLESTR url_fragment); + HRESULT SetBrowserFrameOptions(DWORD opt1, DWORD opt2); + HRESULT DetachConnectionPoints(); + HRESULT GetProcessId(DWORD *pid); + HRESULT CompatAttachEditEvents(); + HRESULT HandleOpenOptions(IUnknown *obj, BSTR bstr, int options); + HRESULT SetSearchTerm(BSTR term); + HRESULT GetSearchTerm(BSTR *term); + HRESULT GetCurrentDocument(IDispatch** doc); +} + +/***************************************************************************** + * IWebBrowserPriv2IE9 interface + */ +[ + object, + uuid(3ed72303-6ffc-4214-ba90-faf1862dec8a), + local +] +interface IWebBrowserPriv2IE9 : IUnknown +{ + HRESULT NavigateWithBindCtx2(IUri *uri, VARIANT *flags, VARIANT *target_frame, VARIANT *post_data, + VARIANT *headers, IBindCtx *bind_ctx, LPOLESTR url_fragment, DWORD unused); + /* Probably more */ +} diff --git a/include/psdk/winnt.h b/include/psdk/winnt.h index 3f7111ac5c3..d2e277b09b7 100644 --- a/include/psdk/winnt.h +++ b/include/psdk/winnt.h @@ -4672,10 +4672,10 @@ typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY { _ANONYMOUS_STRUCT struct { DWORD NameOffset:31; DWORD NameIsString:1; - } DUMMYSTRUCTNAME1; + } DUMMYSTRUCTNAME; DWORD Name; WORD Id; - } DUMMYUNIONNAME1; + } DUMMYUNIONNAME; _ANONYMOUS_UNION union { DWORD OffsetToData; _ANONYMOUS_STRUCT struct { diff --git a/include/reactos/kdros.h b/include/reactos/kdros.h index 49fce67c2f0..bcc71ff16a4 100644 --- a/include/reactos/kdros.h +++ b/include/reactos/kdros.h @@ -5,30 +5,30 @@ #if 0 -VOID FORCEINLINE +VOID KdRosDumpAllThreads(VOID) { KdSystemDebugControl(' soR', (PVOID)DumpAllThreads, 0, 0, 0, 0, 0); } -VOID FORCEINLINE +VOID KdRosDumpUserThreads(VOID) { KdSystemDebugControl(' soR', (PVOID)DumpUserThreads, 0, 0, 0, 0, 0); } -VOID FORCEINLINE +VOID KdRosDumpArmPfnDatabase(VOID) { KdSystemDebugControl(' soR', (PVOID)KdSpare3, 0, 0, 0, 0, 0); } #endif -VOID FORCEINLINE +VOID KdRosSetDebugCallback( ULONG Id, PVOID Callback) @@ -36,8 +36,8 @@ KdRosSetDebugCallback( KdSystemDebugControl('CsoR', Callback, Id, 0, 0, 0, 0); } -VOID FORCEINLINE +VOID KdRosDumpStackFrames( ULONG Count, PULONG_PTR Backtrace) @@ -46,16 +46,16 @@ KdRosDumpStackFrames( } #if KDBG -VOID FORCEINLINE +VOID KdRosRegisterCliCallback( PVOID Callback) { KdSystemDebugControl('RbdK', Callback, FALSE, 0, 0, 0, 0); } -VOID FORCEINLINE +VOID KdRosDeregisterCliCallback( PVOID Callback) { diff --git a/include/reactos/libs/pseh/pseh2.h b/include/reactos/libs/pseh/pseh2.h index b2666585f6b..ff11f61d64b 100644 --- a/include/reactos/libs/pseh/pseh2.h +++ b/include/reactos/libs/pseh/pseh2.h @@ -39,12 +39,15 @@ #elif defined(_USE_DUMMY_PSEH) || defined (__arm__) || defined(__clang__) || defined(_M_AMD64) +extern int _SEH2_Volatile0; +extern int _SEH2_VolatileExceptionCode; + #define _SEH2_TRY { #define _SEH2_FINALLY } { -#define _SEH2_EXCEPT(...) } if (0) { +#define _SEH2_EXCEPT(...) } if (_SEH2_Volatile0) { #define _SEH2_END } #define _SEH2_GetExceptionInformation() -#define _SEH2_GetExceptionCode() 0 +#define _SEH2_GetExceptionCode() _SEH2_VolatileExceptionCode #define _SEH2_AbnormalTermination() #define _SEH2_YIELD(STMT_) STMT_ #define _SEH2_LEAVE diff --git a/include/reactos/libs/pseh/pseh3.h b/include/reactos/libs/pseh/pseh3.h index 4fe95d45238..6aa15dd9c15 100644 --- a/include/reactos/libs/pseh/pseh3.h +++ b/include/reactos/libs/pseh/pseh3.h @@ -283,10 +283,13 @@ _SEH3$_AutoCleanup( #define _SEH3$_DEFINE_FILTER_FUNC(_Name, expression) \ _SEH3$_NESTED_FUNC_OPEN(_Name) \ /* Declare the intrinsics for exception filters */ \ +_Pragma("GCC diagnostic push") \ +_Pragma("GCC diagnostic ignored \"-Wshadow\"") \ inline __attribute__((always_inline, gnu_inline)) \ unsigned long _exception_code() { return _SEH3$_TrylevelFrame.ExceptionPointers->ExceptionRecord->ExceptionCode; } \ inline __attribute__((always_inline, gnu_inline)) \ void * _exception_info() { return _SEH3$_TrylevelFrame.ExceptionPointers; } \ +_Pragma("GCC diagnostic pop") \ \ /* Now handle the actual filter expression */ \ return (expression); \ @@ -345,6 +348,9 @@ _SEH3$_AutoCleanup( (void)&&_SEH3$_l_OnException; \ (void)&&_SEH3$_l_BeforeFilterOrFinally; \ (void)&&_SEH3$_l_FilterOrFinally; \ +\ +_Pragma("GCC diagnostic push") \ +_Pragma("GCC diagnostic ignored \"-Wdeclaration-after-statement\"") \ \ /* Count the try level. Outside of any __try, _SEH3$_TryLevel is 0 */ \ enum { \ @@ -357,6 +363,8 @@ _SEH3$_AutoCleanup( \ /* Allocate a registration frame */ \ volatile SEH3$_REGISTRATION_FRAME _SEH3$_AUTO_CLEANUP _SEH3$_TrylevelFrame; \ +\ +_Pragma("GCC diagnostic pop") \ \ goto _SEH3$_l_BeforeTry; \ /* Silence warning */ goto _SEH3$_l_AfterTry; \ @@ -373,6 +381,9 @@ _SEH3$_AutoCleanup( \ _SEH3$_l_BeforeTry: (void)0; \ _SEH3$_ASM_GOTO(_SEH3$_l_OnException); \ +\ +_Pragma("GCC diagnostic push") \ +_Pragma("GCC diagnostic ignored \"-Wdeclaration-after-statement\"") \ \ /* Forward declaration of the filter function */ \ _SEH3$_DECLARE_FILTER_FUNC(_SEH3$_FilterFunction); \ @@ -421,6 +432,9 @@ _SEH3$_AutoCleanup( \ _SEH3$_l_BeforeTry: (void)0; \ _SEH3$_ASM_GOTO(_SEH3$_l_OnException); \ +\ +_Pragma("GCC diagnostic push") \ +_Pragma("GCC diagnostic ignored \"-Wdeclaration-after-statement\"") \ \ /* Forward declaration of the finally function */ \ _SEH3$_DECLARE_FILTER_FUNC(_SEH3$_FinallyFunction); \ @@ -458,6 +472,8 @@ _SEH3$_AutoCleanup( \ /* Implementation of the auto cleanup function */ \ _SEH3$_DEFINE_CLEANUP_FUNC(_SEH3$_AutoCleanup); \ +\ +_Pragma("GCC diagnostic pop") \ \ /* Close the outer scope */ \ } while (0); diff --git a/lib/3rdparty/adns/adns_win32/adns_win32.h b/lib/3rdparty/adns/adns_win32/adns_win32.h index d3cba4019a3..61e7480cb09 100644 --- a/lib/3rdparty/adns/adns_win32/adns_win32.h +++ b/lib/3rdparty/adns/adns_win32/adns_win32.h @@ -108,7 +108,15 @@ extern "C" #define ADNS_CLEAR_ERRNO {WSASetLastError(errno = 0);} #define ENOBUFS WSAENOBUFS + +/* FIXME: there are two types of defines for this, + * one points to WSAEWOULDBLOCK and the other is from errno.h */ +#ifdef EWOULDBLOCK +#undef EWOULDBLOCK +#endif + #define EWOULDBLOCK WSAEWOULDBLOCK + #define EINPROGRESS WSAEINPROGRESS #define EMSGSIZE WSAEMSGSIZE #define ENOPROTOOPT WSAENOPROTOOPT diff --git a/lib/3rdparty/cardlib/cardbutton.cpp b/lib/3rdparty/cardlib/cardbutton.cpp index 76957a4453a..035d9c9a54b 100644 --- a/lib/3rdparty/cardlib/cardbutton.cpp +++ b/lib/3rdparty/cardlib/cardbutton.cpp @@ -75,7 +75,7 @@ void CardButton::DrawRect(HDC hdc, RECT *rect, bool fNormal) if(fNormal) hOld = SelectObject(hdc, hhi); else - hOld = SelectObject(hdc, hhi); + hOld = SelectObject(hdc, hsh); MoveToEx(hdc, x, y+height, 0); LineTo(hdc, x, y); diff --git a/lib/pseh/dummy.c b/lib/pseh/dummy.c index c21b66d7297..e35e958b46a 100644 --- a/lib/pseh/dummy.c +++ b/lib/pseh/dummy.c @@ -1,2 +1,4 @@ /* intentionally empty file */ +int _SEH2_Volatile0 = 0; +int _SEH2_VolatileExceptionCode = 0xC0000005; diff --git a/lib/rtl/actctx.c b/lib/rtl/actctx.c index 437995d18dc..1243f59ceab 100644 --- a/lib/rtl/actctx.c +++ b/lib/rtl/actctx.c @@ -190,6 +190,9 @@ struct actctx_loader unsigned int allocated_dependencies; }; +static const WCHAR asmv1W[] = {'a','s','m','v','1',':',0}; +static const WCHAR asmv2W[] = {'a','s','m','v','2',':',0}; + typedef struct _ACTIVATION_CONTEXT_WRAPPED { PVOID MagicMarker; @@ -270,6 +273,7 @@ static const WCHAR iidW[] = {'i','i','d',0}; static const WCHAR languageW[] = {'l','a','n','g','u','a','g','e',0}; static const WCHAR manifestVersionW[] = {'m','a','n','i','f','e','s','t','V','e','r','s','i','o','n',0}; static const WCHAR g_nameW[] = {'n','a','m','e',0}; +static const WCHAR neutralW[] = {'n','e','u','t','r','a','l',0}; static const WCHAR newVersionW[] = {'n','e','w','V','e','r','s','i','o','n',0}; static const WCHAR oldVersionW[] = {'o','l','d','V','e','r','s','i','o','n',0}; static const WCHAR optionalW[] = {'o','p','t','i','o','n','a','l',0}; @@ -286,6 +290,7 @@ static const WCHAR manifestv3W[] = {'u','r','n',':','s','c','h','e','m','a','s', static const WCHAR dotManifestW[] = {'.','m','a','n','i','f','e','s','t',0}; static const WCHAR version_formatW[] = {'%','u','.','%','u','.','%','u','.','%','u',0}; +static const WCHAR wildcardW[] = {'*',0}; static ACTIVATION_CONTEXT_WRAPPED system_actctx = { ACTCTX_MAGIC_MARKER, { 1 } }; static ACTIVATION_CONTEXT *process_actctx = &system_actctx.ActivationContext; @@ -311,16 +316,6 @@ static WCHAR *xmlstrdupW(const xmlstr_t* str) return strW; } -static UNICODE_STRING xmlstr2unicode(const xmlstr_t *xmlstr) -{ - UNICODE_STRING res; - - res.Buffer = (PWSTR)xmlstr->ptr; - res.Length = res.MaximumLength = (USHORT)xmlstr->len * sizeof(WCHAR); - - return res; -} - static inline BOOL xmlstr_cmp(const xmlstr_t* xmlstr, const WCHAR *str) { return !strncmpW(xmlstr->ptr, str, xmlstr->len) && !str[xmlstr->len]; @@ -337,11 +332,42 @@ static inline BOOL xmlstr_cmp_end(const xmlstr_t* xmlstr, const WCHAR *str) !strncmpW(xmlstr->ptr + 1, str, xmlstr->len - 1) && !str[xmlstr->len - 1]); } +static inline BOOL xml_elem_cmp(const xmlstr_t *elem, const WCHAR *str, const WCHAR *namespace) +{ + UINT len = strlenW( namespace ); + + if (!strncmpW(elem->ptr, str, elem->len) && !str[elem->len]) return TRUE; + return (elem->len > len && !strncmpW(elem->ptr, namespace, len) && + !strncmpW(elem->ptr + len, str, elem->len - len) && !str[elem->len - len]); +} + +static inline BOOL xml_elem_cmp_end(const xmlstr_t *elem, const WCHAR *str, const WCHAR *namespace) +{ + if (elem->len && elem->ptr[0] == '/') + { + xmlstr_t elem_end; + elem_end.ptr = elem->ptr + 1; + elem_end.len = elem->len - 1; + return xml_elem_cmp( &elem_end, str, namespace ); + } + return FALSE; +} + static inline BOOL isxmlspace( WCHAR ch ) { return (ch == ' ' || ch == '\r' || ch == '\n' || ch == '\t'); } +static UNICODE_STRING xmlstr2unicode(const xmlstr_t *xmlstr) +{ + UNICODE_STRING res; + + res.Buffer = (PWSTR)xmlstr->ptr; + res.Length = res.MaximumLength = (USHORT)xmlstr->len * sizeof(WCHAR); + + return res; +} + static struct assembly *add_assembly(ACTIVATION_CONTEXT *actctx, enum assembly_type at) { struct assembly *assembly; @@ -485,7 +511,6 @@ static BOOL is_matching_identity( const struct assembly_identity *id1, if (id1->language && id2->language && strcmpiW( id1->language, id2->language )) { - static const WCHAR wildcardW[] = {'*',0}; if (strcmpW( wildcardW, id1->language ) && strcmpW( wildcardW, id2->language )) return FALSE; } @@ -605,17 +630,21 @@ static WCHAR *build_assembly_id( const struct assembly_identity *ai ) {',','p','r','o','c','e','s','s','o','r','A','r','c','h','i','t','e','c','t','u','r','e','=',0}; static const WCHAR public_keyW[] = {',','p','u','b','l','i','c','K','e','y','T','o','k','e','n','=',0}; + static const WCHAR typeW2[] = + {',','t','y','p','e','=',0}; + static const WCHAR versionW2[] = + {',','v','e','r','s','i','o','n','=',0}; WCHAR version[64], *ret; SIZE_T size = 0; sprintfW( version, version_formatW, ai->version.major, ai->version.minor, ai->version.build, ai->version.revision ); - if (ai->name) size += strlenW(ai->name); + if (ai->name) size += strlenW(ai->name) * sizeof(WCHAR); if (ai->arch) size += strlenW(archW) + strlenW(ai->arch) + 2; if (ai->public_key) size += strlenW(public_keyW) + strlenW(ai->public_key) + 2; - if (ai->type) size += 1 + strlenW(typeW) + 1 + strlenW(ai->type) + 2; - size += 1+ strlenW(versionW) + 1 + strlenW(version) + 2; + if (ai->type) size += strlenW(typeW2) + strlenW(ai->type) + 2; + size += strlenW(versionW2) + strlenW(version) + 2; if (!(ret = RtlAllocateHeap( RtlGetProcessHeap(), 0, (size + 1) * sizeof(WCHAR) ))) return NULL; @@ -624,8 +653,8 @@ static WCHAR *build_assembly_id( const struct assembly_identity *ai ) else *ret = 0; append_string( ret, archW, ai->arch ); append_string( ret, public_keyW, ai->public_key ); - append_string( ret, typeW, ai->type ); - append_string( ret, versionW, version ); + append_string( ret, typeW2, ai->type ); + append_string( ret, versionW2, version ); return ret; } static ACTIVATION_CONTEXT *check_actctx( HANDLE h ) @@ -722,13 +751,23 @@ static BOOL next_xml_attr(xmlbuf_t* xmlbuf, xmlstr_t* name, xmlstr_t* value, ptr = xmlbuf->ptr; while (ptr < xmlbuf->end && *ptr != '=' && *ptr != '>' && !isxmlspace(*ptr)) ptr++; - if (ptr == xmlbuf->end || *ptr != '=') return FALSE; + if (ptr == xmlbuf->end) return FALSE; name->ptr = xmlbuf->ptr; - name->len = (ULONG)(ptr - xmlbuf->ptr); + name->len = ptr-xmlbuf->ptr; xmlbuf->ptr = ptr; + /* skip spaces before '=' */ + while (ptr < xmlbuf->end && *ptr != '=' && isxmlspace(*ptr)) ptr++; + if (ptr == xmlbuf->end || *ptr != '=') return FALSE; + + /* skip '=' itself */ ptr++; + if (ptr == xmlbuf->end) return FALSE; + + /* skip spaces after '=' */ + while (ptr < xmlbuf->end && *ptr != '"' && *ptr != '\'' && isxmlspace(*ptr)) ptr++; + if (ptr == xmlbuf->end || (*ptr != '"' && *ptr != '\'')) return FALSE; value->ptr = ++ptr; @@ -741,7 +780,7 @@ static BOOL next_xml_attr(xmlbuf_t* xmlbuf, xmlstr_t* name, xmlstr_t* value, return FALSE; } - value->len = (ULONG)(ptr - value->ptr); + value->len = ptr - value->ptr; xmlbuf->ptr = ptr + 1; if (xmlbuf->ptr == xmlbuf->end) return FALSE; @@ -783,7 +822,7 @@ static BOOL next_xml_elem(xmlbuf_t* xmlbuf, xmlstr_t* elem) ptr++; elem->ptr = xmlbuf->ptr; - elem->len = (ULONG)(ptr - xmlbuf->ptr); + elem->len = ptr - xmlbuf->ptr; xmlbuf->ptr = ptr; return xmlbuf->ptr != xmlbuf->end; } @@ -811,7 +850,7 @@ static BOOL parse_text_content(xmlbuf_t* xmlbuf, xmlstr_t* content) if (!ptr) return FALSE; content->ptr = xmlbuf->ptr; - content->len = (ULONG)(ptr - xmlbuf->ptr); + content->len = ptr - xmlbuf->ptr; xmlbuf->ptr = ptr; return TRUE; @@ -851,12 +890,12 @@ error: return FALSE; } -static BOOL parse_expect_elem(xmlbuf_t* xmlbuf, const WCHAR* name) +static BOOL parse_expect_elem(xmlbuf_t* xmlbuf, const WCHAR* name, const WCHAR *namespace) { xmlstr_t elem; UNICODE_STRING elemU; if (!next_xml_elem(xmlbuf, &elem)) return FALSE; - if (xmlstr_cmp(&elem, name)) return TRUE; + if (xml_elem_cmp(&elem, name, namespace)) return TRUE; elemU = xmlstr2unicode(&elem); DPRINT1( "unexpected element %wZ\n", &elemU ); return FALSE; @@ -884,12 +923,12 @@ static BOOL parse_end_element(xmlbuf_t *xmlbuf) return parse_expect_no_attr(xmlbuf, &end) && !end; } -static BOOL parse_expect_end_elem(xmlbuf_t *xmlbuf, const WCHAR *name) +static BOOL parse_expect_end_elem(xmlbuf_t *xmlbuf, const WCHAR *name, const WCHAR *namespace) { xmlstr_t elem; UNICODE_STRING elemU; if (!next_xml_elem(xmlbuf, &elem)) return FALSE; - if (!xmlstr_cmp_end(&elem, name)) + if (!xml_elem_cmp_end(&elem, name, namespace)) { elemU = xmlstr2unicode(&elem); DPRINT1( "unexpected element %wZ\n", &elemU ); @@ -949,9 +988,9 @@ static BOOL parse_assembly_identity_elem(xmlbuf_t* xmlbuf, ACTIVATION_CONTEXT* a } else if (xmlstr_cmp(&attr_name, languageW)) { - if (!(ai->language = xmlstrdupW(&attr_value))) return FALSE; DPRINT1("Unsupported yet language attribute (%S)\n", ai->language); + if (!(ai->language = xmlstrdupW(&attr_value))) return FALSE; } else { @@ -962,13 +1001,13 @@ static BOOL parse_assembly_identity_elem(xmlbuf_t* xmlbuf, ACTIVATION_CONTEXT* a } if (error || end) return end; - return parse_expect_end_elem(xmlbuf, assemblyIdentityW); + return parse_expect_end_elem(xmlbuf, assemblyIdentityW, asmv1W); } static BOOL parse_com_class_elem(xmlbuf_t* xmlbuf, struct dll_redirect* dll) { xmlstr_t elem, attr_name, attr_value; - BOOL ret, end = FALSE, error; + BOOL ret = TRUE, end = FALSE, error; struct entity* entity; UNICODE_STRING attr_valueU, attr_nameU; @@ -1037,7 +1076,7 @@ static BOOL parse_cominterface_proxy_stub_elem(xmlbuf_t* xmlbuf, struct dll_redi } if (error || end) return end; - return parse_expect_end_elem(xmlbuf, comInterfaceProxyStubW); + return parse_expect_end_elem(xmlbuf, comInterfaceProxyStubW, asmv1W); } static BOOL parse_typelib_elem(xmlbuf_t* xmlbuf, struct dll_redirect* dll) @@ -1073,13 +1112,13 @@ static BOOL parse_typelib_elem(xmlbuf_t* xmlbuf, struct dll_redirect* dll) } if (error || end) return end; - return parse_expect_end_elem(xmlbuf, typelibW); + return parse_expect_end_elem(xmlbuf, typelibW, asmv1W); } static BOOL parse_window_class_elem(xmlbuf_t* xmlbuf, struct dll_redirect* dll) { - xmlstr_t elem, content; - BOOL end = FALSE, ret = TRUE; + xmlstr_t elem, content; + BOOL end = FALSE, ret = TRUE; struct entity* entity; UNICODE_STRING elemU; @@ -1137,7 +1176,7 @@ static BOOL parse_binding_redirect_elem(xmlbuf_t* xmlbuf) } if (error || end) return end; - return parse_expect_end_elem(xmlbuf, bindingRedirectW); + return parse_expect_end_elem(xmlbuf, bindingRedirectW, asmv1W); } static BOOL parse_description_elem(xmlbuf_t* xmlbuf) @@ -1201,7 +1240,7 @@ static BOOL parse_com_interface_external_proxy_stub_elem(xmlbuf_t* xmlbuf, } if (error || end) return end; - return parse_expect_end_elem(xmlbuf, comInterfaceExternalProxyStubW); + return parse_expect_end_elem(xmlbuf, comInterfaceExternalProxyStubW, asmv1W); } static BOOL parse_clr_class_elem(xmlbuf_t* xmlbuf, struct assembly* assembly) @@ -1233,7 +1272,7 @@ static BOOL parse_clr_class_elem(xmlbuf_t* xmlbuf, struct assembly* assembly) } if (error || end) return end; - return parse_expect_end_elem(xmlbuf, clrClassW); + return parse_expect_end_elem(xmlbuf, clrClassW, asmv1W); } static BOOL parse_clr_surrogate_elem(xmlbuf_t* xmlbuf, struct assembly* assembly) @@ -1265,7 +1304,7 @@ static BOOL parse_clr_surrogate_elem(xmlbuf_t* xmlbuf, struct assembly* assembly } if (error || end) return end; - return parse_expect_end_elem(xmlbuf, clrSurrogateW); + return parse_expect_end_elem(xmlbuf, clrSurrogateW, asmv1W); } static BOOL parse_dependent_assembly_elem(xmlbuf_t* xmlbuf, struct actctx_loader* acl, BOOL optional) @@ -1279,7 +1318,7 @@ static BOOL parse_dependent_assembly_elem(xmlbuf_t* xmlbuf, struct actctx_loader memset(&ai, 0, sizeof(ai)); ai.optional = optional; - if (!parse_expect_elem(xmlbuf, assemblyIdentityW) || + if (!parse_expect_elem(xmlbuf, assemblyIdentityW, asmv1W) || !parse_assembly_identity_elem(xmlbuf, acl->actctx, &ai)) return FALSE; @@ -1357,7 +1396,7 @@ static BOOL parse_noinherit_elem(xmlbuf_t* xmlbuf) BOOL end = FALSE; if (!parse_expect_no_attr(xmlbuf, &end)) return FALSE; - return end || parse_expect_end_elem(xmlbuf, noInheritW); + return end || parse_expect_end_elem(xmlbuf, noInheritW, asmv1W); } static BOOL parse_noinheritable_elem(xmlbuf_t* xmlbuf) @@ -1365,7 +1404,7 @@ static BOOL parse_noinheritable_elem(xmlbuf_t* xmlbuf) BOOL end = FALSE; if (!parse_expect_no_attr(xmlbuf, &end)) return FALSE; - return end || parse_expect_end_elem(xmlbuf, noInheritableW); + return end || parse_expect_end_elem(xmlbuf, noInheritableW, asmv1W); } static BOOL parse_file_elem(xmlbuf_t* xmlbuf, struct assembly* assembly) @@ -1869,7 +1908,7 @@ static NTSTATUS get_manifest_in_manifest_file( struct actctx_loader* acl, struct base = NULL; status = NtMapViewOfSection( mapping, NtCurrentProcess(), &base, 0, 0, &offset, &count, ViewShare, 0, PAGE_READONLY ); - + NtClose( mapping ); if (status != STATUS_SUCCESS) return status; /* Fixme: WINE uses FileEndOfFileInformation with NtQueryInformationFile. */ @@ -1879,7 +1918,6 @@ static NTSTATUS get_manifest_in_manifest_file( struct actctx_loader* acl, struct status = parse_manifest(acl, ai, filename, directory, shared, base, (SIZE_T)info.EndOfFile.QuadPart); NtUnmapViewOfSection( NtCurrentProcess(), base ); - NtClose( mapping ); return status; } @@ -1928,7 +1966,7 @@ static NTSTATUS get_manifest_in_associated_manifest( struct actctx_loader* acl, status = get_manifest_in_manifest_file( acl, ai, nameW.Buffer, directory, FALSE, file ); NtClose( file ); } - else status = STATUS_RESOURCE_DATA_NOT_FOUND; + else status = STATUS_RESOURCE_TYPE_NOT_FOUND; RtlFreeUnicodeString( &nameW ); return status; } @@ -1943,6 +1981,7 @@ static WCHAR *lookup_manifest_file( HANDLE dir, struct assembly_identity *ai ) WCHAR *lookup, *ret = NULL; UNICODE_STRING lookup_us; IO_STATUS_BLOCK io; + const WCHAR *lang = ai->language; unsigned int data_pos = 0, data_len; char buffer[8192]; @@ -1952,7 +1991,9 @@ static WCHAR *lookup_manifest_file( HANDLE dir, struct assembly_identity *ai ) + sizeof(lookup_fmtW) ))) return NULL; - sprintfW( lookup, lookup_fmtW, ai->arch, ai->name, ai->public_key, ai->version.major, ai->version.minor); + if (!lang || !strcmpiW( lang, neutralW )) lang = wildcardW; + sprintfW( lookup, lookup_fmtW, ai->arch, ai->name, ai->public_key, + ai->version.major, ai->version.minor, lang ); RtlInitUnicodeString( &lookup_us, lookup ); NtQueryDirectoryFile( dir, 0, NULL, NULL, &io, buffer, sizeof(buffer), @@ -2089,6 +2130,7 @@ static NTSTATUS lookup_assembly(struct actctx_loader* acl, NTSTATUS status; UNICODE_STRING nameW; HANDLE file; + DWORD len; DPRINT( "looking for name=%S version=%u.%u.%u.%u arch=%S\n", ai->name, ai->version.major, ai->version.minor, ai->version.build, ai->version.revision, ai->arch ); @@ -2097,9 +2139,12 @@ static NTSTATUS lookup_assembly(struct actctx_loader* acl, /* FIXME: add support for language specific lookup */ + len = max(RtlGetFullPathName_U(acl->actctx->assemblies->manifest.info, 0, NULL, NULL) / sizeof(WCHAR), + strlenW(acl->actctx->appdir.info)); + nameW.Buffer = NULL; if (!(buffer = RtlAllocateHeap( RtlGetProcessHeap(), 0, - (strlenW(acl->actctx->appdir.info) + 2 * strlenW(ai->name) + 2) * sizeof(WCHAR) + sizeof(dotManifestW) ))) + (len + 2 * strlenW(ai->name) + 2) * sizeof(WCHAR) + sizeof(dotManifestW) ))) return STATUS_NO_MEMORY; if (!(directory = build_assembly_dir( ai ))) @@ -2108,16 +2153,25 @@ static NTSTATUS lookup_assembly(struct actctx_loader* acl, return STATUS_NO_MEMORY; } - /* lookup in appdir\name.dll - * appdir\name.manifest - * appdir\name\name.dll - * appdir\name\name.manifest + /* Lookup in \name.dll + * \name.manifest + * \name\name.dll + * \name\name.manifest + * + * First 'appdir' is used as , if that failed + * it tries application manifest file path. */ strcpyW( buffer, acl->actctx->appdir.info ); p = buffer + strlenW(buffer); - for (i = 0; i < 2; i++) + for (i = 0; i < 4; i++) { - *p++ = '\\'; + if (i == 2) + { + struct assembly *assembly = acl->actctx->assemblies; + if (!RtlGetFullPathName_U(assembly->manifest.info, len * sizeof(WCHAR), buffer, &p)) break; + } + else *p++ = '\\'; + strcpyW( p, ai->name ); p += strlenW(p); @@ -2308,6 +2362,28 @@ static NTSTATUS find_string(ACTIVATION_CONTEXT* actctx, ULONG section_kind, return STATUS_SUCCESS; } +static NTSTATUS find_guid(ACTIVATION_CONTEXT* actctx, ULONG section_kind, + const GUID *guid, DWORD flags, PACTCTX_SECTION_KEYED_DATA data) +{ + NTSTATUS status; + + switch (section_kind) + { + default: + DPRINT("Unknown section_kind %x\n", section_kind); + return STATUS_SXS_SECTION_NOT_FOUND; + } + + if (status != STATUS_SUCCESS) return status; + + if (flags & FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX) + { + actctx_addref(actctx); + data->hActCtx = actctx; + } + return STATUS_SUCCESS; +} + /* initialize the activation context for the current process */ void actctx_init(void) { @@ -2384,7 +2460,10 @@ RtlCreateActivationContext(IN ULONG Flags, } nameW.Buffer = NULL; - if (pActCtx->lpSource) + + /* open file only if it's going to be used */ + if (pActCtx->lpSource && !((pActCtx->dwFlags & ACTCTX_FLAG_RESOURCE_NAME_VALID) && + (pActCtx->dwFlags & ACTCTX_FLAG_HMODULE_VALID))) { if (!RtlDosPathNameToNtPathName_U(pActCtx->lpSource, &nameW, NULL, NULL)) { @@ -2789,7 +2868,6 @@ RtlQueryInformationActivationContext( ULONG flags, HANDLE handle, PVOID subinst, { afdi->lpAssemblyDirectoryName = ptr; memcpy(ptr, assembly->directory, ad_len * sizeof(WCHAR)); - ptr += ad_len; } else afdi->lpAssemblyDirectoryName = NULL; RtlFreeHeap( RtlGetProcessHeap(), 0, assembly_id ); @@ -2923,12 +3001,37 @@ RtlFindActivationContextSectionString( ULONG flags, const GUID *guid, ULONG sect return status; } -NTSTATUS -NTAPI -RtlFindActivationContextSectionGuid(ULONG flags, const GUID *guid, ULONG section_kind, UNICODE_STRING *section_name, PVOID ptr) +NTSTATUS WINAPI RtlFindActivationContextSectionGuid( ULONG flags, const GUID *extguid, ULONG section_kind, + const GUID *guid, void *ptr ) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + ACTCTX_SECTION_KEYED_DATA *data = ptr; + NTSTATUS status = STATUS_SXS_KEY_NOT_FOUND; + + if (extguid) + { + DPRINT1("expected extguid == NULL\n"); + return STATUS_INVALID_PARAMETER; + } + + if (flags & ~FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX) + { + DPRINT1("unknown flags %08x\n", flags); + return STATUS_INVALID_PARAMETER; + } + + if (!data || data->cbSize < FIELD_OFFSET(ACTCTX_SECTION_KEYED_DATA, ulAssemblyRosterIndex) || !guid) + return STATUS_INVALID_PARAMETER; + + if (NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame) + { + ACTIVATION_CONTEXT *actctx = check_actctx(NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame->ActivationContext); + if (actctx) status = find_guid( actctx, section_kind, guid, flags, data ); + } + + if (status != STATUS_SUCCESS) + status = find_guid( process_actctx, section_kind, guid, flags, data ); + + return status; } /* Stubs */ diff --git a/lib/rtl/heap.c b/lib/rtl/heap.c index bcd0683cc02..fe68bd4f44e 100644 --- a/lib/rtl/heap.c +++ b/lib/rtl/heap.c @@ -46,7 +46,8 @@ UCHAR RtlpBitsClearLow[] = 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0 }; -UCHAR FORCEINLINE +FORCEINLINE +UCHAR RtlpFindLeastSetBit(ULONG Bits) { if (Bits & 0xFFFF) @@ -203,7 +204,8 @@ RtlpInitializeHeap(OUT PHEAP Heap, return STATUS_SUCCESS; } -VOID FORCEINLINE +FORCEINLINE +VOID RtlpSetFreeListsBit(PHEAP Heap, PHEAP_FREE_ENTRY FreeEntry) { @@ -222,7 +224,8 @@ RtlpSetFreeListsBit(PHEAP Heap, Heap->u.FreeListsInUseBytes[Index] |= Bit; } -VOID FORCEINLINE +FORCEINLINE +VOID RtlpClearFreeListsBit(PHEAP Heap, PHEAP_FREE_ENTRY FreeEntry) { diff --git a/lib/rtl/image.c b/lib/rtl/image.c index 97e8ee86ec8..3c0fd41f5d5 100644 --- a/lib/rtl/image.c +++ b/lib/rtl/image.c @@ -20,8 +20,8 @@ /* FUNCTIONS *****************************************************************/ -USHORT FORCEINLINE +USHORT ChkSum(ULONG Sum, PUSHORT Src, ULONG Len) { ULONG i; diff --git a/lib/rtl/rtlavl.h b/lib/rtl/rtlavl.h index 7088ce1ecfe..7f3a549b071 100644 --- a/lib/rtl/rtlavl.h +++ b/lib/rtl/rtlavl.h @@ -24,16 +24,16 @@ #define RtlInsertAsLeftChildAvl RtlInsertAsLeftChild #define RtlIsLeftChildAvl RtlIsLeftChild -VOID FORCEINLINE +VOID RtlpCopyAvlNodeData(IN PRTL_BALANCED_LINKS Node1, IN PRTL_BALANCED_LINKS Node2) { *Node1 = *Node2; } -RTL_GENERIC_COMPARE_RESULTS FORCEINLINE +RTL_GENERIC_COMPARE_RESULTS RtlpAvlCompareRoutine(IN PRTL_AVL_TABLE Table, IN PVOID Buffer, IN PVOID UserData) @@ -44,24 +44,24 @@ RtlpAvlCompareRoutine(IN PRTL_AVL_TABLE Table, UserData); } -VOID FORCEINLINE +VOID RtlSetParent(IN PRTL_BALANCED_LINKS Node, IN PRTL_BALANCED_LINKS Parent) { Node->Parent = Parent; } -VOID FORCEINLINE +VOID RtlSetBalance(IN PRTL_BALANCED_LINKS Node, IN CHAR Balance) { Node->Balance = Balance; } -CHAR FORCEINLINE +CHAR RtlBalance(IN PRTL_BALANCED_LINKS Node) { return Node->Balance; diff --git a/lib/sdk/crt/include/internal/tls.h b/lib/sdk/crt/include/internal/tls.h index 664e553ee39..c1b5eef03c9 100644 --- a/lib/sdk/crt/include/internal/tls.h +++ b/lib/sdk/crt/include/internal/tls.h @@ -39,7 +39,8 @@ struct __thread_data { struct tm *time_buffer; /* buffer for localtime/gmtime */ char *efcvt_buffer; /* buffer for ecvt/fcvt */ int unk3[2]; - void *unk4[4]; + void *unk4[3]; + EXCEPTION_POINTERS *xcptinfo; int fpecode; struct MSVCRT_threadmbcinfostruct *mbcinfo; struct MSVCRT_threadlocaleinfostruct *locinfo; diff --git a/lib/sdk/crt/signal/xcptinfo.c b/lib/sdk/crt/signal/xcptinfo.c index 0d14df09afb..a476d9c41ce 100644 --- a/lib/sdk/crt/signal/xcptinfo.c +++ b/lib/sdk/crt/signal/xcptinfo.c @@ -1,9 +1,9 @@ -#include +#include /* - * @unimplemented + * @implemented */ -void **__pxcptinfoptrs (void) +void** __pxcptinfoptrs(void) { - return NULL; + return (void**)&msvcrt_get_thread_data()->xcptinfo; } diff --git a/lib/sdk/crt/stdio/file.c b/lib/sdk/crt/stdio/file.c index a08d59e16f8..52e7f09f244 100644 --- a/lib/sdk/crt/stdio/file.c +++ b/lib/sdk/crt/stdio/file.c @@ -2813,7 +2813,7 @@ FILE* CDECL _wfreopen(const wchar_t *path, const wchar_t *mode, FILE* file) { int open_flags, stream_flags, fd; - TRACE(":path (%p) mode (%s) file (%p) fd (%d)\n", debugstr_w(path), debugstr_w(mode), file, file->_file); + TRACE(":path (%p) mode (%s) file (%p) fd (%d)\n", debugstr_w(path), debugstr_w(mode), file, file ? file->_file : -1); LOCK_FILES(); if (!file || ((fd = file->_file) < 0) || fd > fdend) diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 9a446a15812..ec4763afd84 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -23,7 +23,7 @@ The following build tools are shared with Wine. reactos/tools/unicode # Synced to Wine-1.7.17 reactos/tools/widl # Synced to Wine-1.7.17 -reactos/tools/wpp # Synced to Wine-1.7.1 +reactos/tools/wpp # Synced to Wine-1.7.17 The following libraries are shared with Wine. @@ -38,189 +38,189 @@ reactos/dll/directx/wine/devenum # Synced to Wine-1.7.17 reactos/dll/directx/wine/dinput # Synced to Wine-1.7.17 reactos/dll/directx/wine/dinput8 # Synced to Wine-1.7.17 reactos/dll/directx/wine/dmusic # Synced to Wine-1.7.17 -reactos/dll/directx/wine/dplay # Synced to Wine-1.7.1 +reactos/dll/directx/wine/dplay # Synced to Wine-1.7.17 reactos/dll/directx/wine/dplayx # Synced to Wine-1.7.17 reactos/dll/directx/wine/dsound # Synced to Wine-1.5.26 reactos/dll/directx/wine/dxdiagn # Synced to Wine-1.7.17 reactos/dll/directx/wine/dxgi # Synced to Wine-1.7.17 -reactos/dll/directx/wine/msdmo # Synced to Wine-1.7.1 +reactos/dll/directx/wine/msdmo # Synced to Wine-1.7.17 reactos/dll/directx/wine/qedit # Synced to Wine-1.7.17 reactos/dll/directx/wine/quartz # Synced to Wine-1.7.17 reactos/dll/directx/wine/wined3d # Synced to Wine-1.7.17 -reactos/dll/win32/activeds # Synced to Wine-1.7.1 +reactos/dll/win32/activeds # Synced to Wine-1.7.17 reactos/dll/win32/actxprxy # Synced to Wine-1.7.17 -reactos/dll/win32/advpack # Synced to Wine-1.7.1 -reactos/dll/win32/atl # Synced to Wine-1.7.1 -reactos/dll/win32/atl100 # Synced to Wine-1.7.1 -reactos/dll/win32/atl80 # Synced to Wine-1.7.1 +reactos/dll/win32/advpack # Synced to Wine-1.7.17 +reactos/dll/win32/atl # Synced to Wine-1.7.17 +reactos/dll/win32/atl100 # Synced to Wine-1.7.17 +reactos/dll/win32/atl80 # Synced to Wine-1.7.17 reactos/dll/win32/avifil32 # Synced to Wine-1.7.17 reactos/dll/win32/bcrypt # Synced to Wine-1.7.17 reactos/dll/win32/browseui # Out of sync reactos/dll/win32/cabinet # Synced to Wine-1.7.17 -reactos/dll/win32/clusapi # Synced to Wine-1.7.1 -reactos/dll/win32/comcat # Synced to Wine-1.7.1 -reactos/dll/win32/comctl32 # Synced to Wine 1.7.17 -reactos/dll/win32/comdlg32 # Synced to Wine 1.7.17 -reactos/dll/win32/compstui # Synced to Wine-1.7.1 -reactos/dll/win32/credui # Synced to Wine-1.7.1 +reactos/dll/win32/clusapi # Synced to Wine-1.7.17 +reactos/dll/win32/comcat # Synced to Wine-1.7.17 +reactos/dll/win32/comctl32 # Synced to Wine-1.7.17 +reactos/dll/win32/comdlg32 # Synced to Wine-1.7.17 +reactos/dll/win32/compstui # Synced to Wine-1.7.17 +reactos/dll/win32/credui # Synced to Wine-1.7.17 reactos/dll/win32/crypt32 # Synced to Wine-1.7.17 -reactos/dll/win32/cryptdlg # Synced to Wine-1.7.1 -reactos/dll/win32/cryptdll # Synced to Wine-1.7.1 +reactos/dll/win32/cryptdlg # Synced to Wine-1.7.17 +reactos/dll/win32/cryptdll # Synced to Wine-1.7.17 reactos/dll/win32/cryptnet # Synced to Wine-1.7.17 -reactos/dll/win32/cryptui # Synced to Wine-1.7.1 -reactos/dll/win32/dbghelp # Synced to Wine-1.7.1 -reactos/dll/win32/dciman32 # Synced to Wine-1.7.1 +reactos/dll/win32/cryptui # Synced to Wine-1.7.17 +reactos/dll/win32/dbghelp # Synced to Wine-1.7.17 +reactos/dll/win32/dciman32 # Synced to Wine-1.7.17 reactos/dll/win32/dwmapi # Synced to Wine-1.7.17 -reactos/dll/win32/faultrep # Synced to Wine-1.7.1 -reactos/dll/win32/fusion # Synced to Wine-1.7.1 +reactos/dll/win32/faultrep # Synced to Wine-1.7.17 +reactos/dll/win32/fusion # Synced to Wine-1.7.17 reactos/dll/win32/gdiplus # Synced to Wine-1.7.17 reactos/dll/win32/hhctrl.ocx # Synced to Wine-1.7.17 reactos/dll/win32/hlink # Synced to Wine-1.7.17 -reactos/dll/win32/hnetcfg # Synced to Wine-1.7.1 -reactos/dll/win32/httpapi # Synced to Wine-1.7.1 -reactos/dll/win32/iccvid # Synced to Wine-1.7.1 +reactos/dll/win32/hnetcfg # Synced to Wine-1.7.17 +reactos/dll/win32/httpapi # Synced to Wine-1.7.17 +reactos/dll/win32/iccvid # Synced to Wine-1.7.17 reactos/dll/win32/icmp # Out of sync -reactos/dll/win32/ieframe # Synced to Wine-1.7.1 -reactos/dll/win32/imaadp32.acm # Synced to Wine-1.7.1 +reactos/dll/win32/ieframe # Synced to Wine-1.7.17 +reactos/dll/win32/imaadp32.acm # Synced to Wine-1.7.17 reactos/dll/win32/imagehlp # Synced to Wine-1.7.17 -reactos/dll/win32/imm32 # Synced to Wine-1.7.1 +reactos/dll/win32/imm32 # Synced to Wine-1.7.17 reactos/dll/win32/inetcomm # Synced to Wine-1.7.17 reactos/dll/win32/inetmib1 # Synced to Wine-1.7.1 -reactos/dll/win32/initpki # Synced to Wine-1.7.1 -reactos/dll/win32/inseng # Synced to Wine-1.7.1 +reactos/dll/win32/initpki # Synced to Wine-1.7.17 +reactos/dll/win32/inseng # Synced to Wine-1.7.17 reactos/dll/win32/iphlpapi # Out of sync -reactos/dll/win32/itircl # Synced to Wine-1.7.1 +reactos/dll/win32/itircl # Synced to Wine-1.7.17 reactos/dll/win32/itss # Synced to Wine-1.7.17 reactos/dll/win32/jscript # Synced to Wine-1.7.17 -reactos/dll/win32/loadperf # Synced to Wine-1.7.1 +reactos/dll/win32/loadperf # Synced to Wine-1.7.17 reactos/dll/win32/localspl # Synced to Wine-1.7.17 -reactos/dll/win32/localui # Synced to Wine-1.7.1 -reactos/dll/win32/lz32 # Synced to Wine-1.7.1 +reactos/dll/win32/localui # Synced to Wine-1.7.17 +reactos/dll/win32/lz32 # Synced to Wine-1.7.17 reactos/dll/win32/mapi32 # Synced to Wine-1.7.17 -reactos/dll/win32/mciavi32 # Synced to Wine-1.7.1 -reactos/dll/win32/mcicda # Synced to Wine-1.7.1 +reactos/dll/win32/mciavi32 # Synced to Wine-1.7.17 +reactos/dll/win32/mcicda # Synced to Wine-1.7.17 reactos/dll/win32/mciqtz32 # Synced to Wine-1.7.17 -reactos/dll/win32/mciseq # Synced to Wine-1.7.1 -reactos/dll/win32/mciwave # Synced to Wine-1.7.1 +reactos/dll/win32/mciseq # Synced to Wine-1.7.17 +reactos/dll/win32/mciwave # Synced to Wine-1.7.17 reactos/dll/win32/mlang # Synced to Wine-1.7.17 reactos/dll/win32/mmdevapi # Synced to Wine-1.7.1 -reactos/dll/win32/mpr # Synced to Wine-1.7.1 -reactos/dll/win32/mprapi # Synced to Wine-1.7.1 +reactos/dll/win32/mpr # Synced to Wine-1.7.17 +reactos/dll/win32/mprapi # Synced to Wine-1.7.17 reactos/dll/win32/msacm32 # Synced to Wine-1.7.17 reactos/dll/win32/msacm32/msacm32.drv # Synced to Wine-1.7.17 reactos/dll/win32/msadp32.acm # Synced to Wine-1.7.17 -reactos/dll/win32/mscat32 # Synced to Wine-1.7.1 +reactos/dll/win32/mscat32 # Synced to Wine-1.7.17 reactos/dll/win32/mscms # Synced to Wine-1.7.17 reactos/dll/win32/mscoree # Synced to Wine-1.5.4 reactos/dll/win32/msctf # Synced to Wine-1.7.17 -reactos/dll/win32/msftedit # Synced to Wine-1.7.1 -reactos/dll/win32/msg711.acm # Synced to Wine-1.7.1 +reactos/dll/win32/msftedit # Synced to Wine-1.7.17 +reactos/dll/win32/msg711.acm # Synced to Wine-1.7.17 reactos/dll/win32/msgsm32.acm # Synced to Wine-1.7.17 -reactos/dll/win32/mshtml # Synced to Wine-1.7.1 +reactos/dll/win32/mshtml # Synced to Wine-1.7.17 reactos/dll/win32/mshtml.tlb # Synced to Wine-1.7.17 reactos/dll/win32/msi # Synced to Wine-1.7.17 -reactos/dll/win32/msimg32 # Synced to Wine-1.7.1 -reactos/dll/win32/msimtf # Synced to Wine-1.7.1 -reactos/dll/win32/msisip # Synced to Wine-1.7.1 -reactos/dll/win32/msisys.ocx # Synced to Wine-1.7.1 -reactos/dll/win32/msnet32 # Synced to Wine-1.7.1 -reactos/dll/win32/msrle32 # Synced to Wine-1.7.1 -reactos/dll/win32/mssign32 # Synced to Wine-1.7.1 -reactos/dll/win32/mssip32 # Synced to Wine-1.7.1 -reactos/dll/win32/mstask # Synced to Wine-1.7.1 +reactos/dll/win32/msimg32 # Synced to Wine-1.7.17 +reactos/dll/win32/msimtf # Synced to Wine-1.7.17 +reactos/dll/win32/msisip # Synced to Wine-1.7.17 +reactos/dll/win32/msisys.ocx # Synced to Wine-1.7.17 +reactos/dll/win32/msnet32 # Synced to Wine-1.7.17 +reactos/dll/win32/msrle32 # Synced to Wine-1.7.17 +reactos/dll/win32/mssign32 # Synced to Wine-1.7.17 +reactos/dll/win32/mssip32 # Synced to Wine-1.7.17 +reactos/dll/win32/mstask # Synced to Wine-1.7.17 reactos/dll/win32/msvcrt20 # Out of sync reactos/dll/win32/msvcrt40 # Out of sync -reactos/dll/win32/msvfw32 # Synced to Wine-1.7.1 +reactos/dll/win32/msvfw32 # Synced to Wine-1.7.17 reactos/dll/win32/msvidc32 # Synced to Wine-1.7.17 -reactos/dll/win32/msxml # Synced to Wine-1.7.1 -reactos/dll/win32/msxml2 # Synced to Wine-1.7.1 +reactos/dll/win32/msxml # Synced to Wine-1.7.17 +reactos/dll/win32/msxml2 # Synced to Wine-1.7.17 reactos/dll/win32/msxml3 # Synced to Wine-1.7.17 -reactos/dll/win32/msxml4 # Synced to Wine-1.7.1 -reactos/dll/win32/msxml6 # Synced to Wine-1.7.1 -reactos/dll/win32/nddeapi # Synced to Wine-1.7.1 +reactos/dll/win32/msxml4 # Synced to Wine-1.7.17 +reactos/dll/win32/msxml6 # Synced to Wine-1.7.17 +reactos/dll/win32/nddeapi # Synced to Wine-1.7.17 reactos/dll/win32/netapi32 # Forked at Wine-1.3.34 -reactos/dll/win32/ntdsapi # Synced to Wine-1.7.1 -reactos/dll/win32/ntprint # Synced to Wine-1.7.1 -reactos/dll/win32/objsel # Synced to Wine-1.7.1 +reactos/dll/win32/ntdsapi # Synced to Wine-1.7.17 +reactos/dll/win32/ntprint # Synced to Wine-1.7.17 +reactos/dll/win32/objsel # Synced to Wine-1.7.17 reactos/dll/win32/odbc32 # Synced to Wine-1.7.17. Depends on port of Linux ODBC. -reactos/dll/win32/odbccp32 # Synced to Wine-1.7.1 +reactos/dll/win32/odbccp32 # Synced to Wine-1.7.17 reactos/dll/win32/ole32 # Synced to Wine-1.7.17 reactos/dll/win32/oleacc # Synced to Wine-1.7.17 reactos/dll/win32/oleaut32 # Synced to Wine-1.7.17 -reactos/dll/win32/olecli32 # Synced to Wine-1.7.1 -reactos/dll/win32/oledlg # Synced to Wine-1.7.1 -reactos/dll/win32/olepro32 # Synced to Wine-1.7.1 -reactos/dll/win32/olesvr32 # Synced to Wine-1.7.1 -reactos/dll/win32/olethk32 # Synced to Wine-1.7.1 -reactos/dll/win32/pdh # Synced to Wine-1.7.1 -reactos/dll/win32/pidgen # Synced to Wine-1.7.1 +reactos/dll/win32/olecli32 # Synced to Wine-1.7.17 +reactos/dll/win32/oledlg # Synced to Wine-1.7.17 +reactos/dll/win32/olepro32 # Synced to Wine-1.7.17 +reactos/dll/win32/olesvr32 # Synced to Wine-1.7.17 +reactos/dll/win32/olethk32 # Synced to Wine-1.7.17 +reactos/dll/win32/pdh # Synced to Wine-1.7.17 +reactos/dll/win32/pidgen # Synced to Wine-1.7.17 reactos/dll/win32/powrprof # Forked at Wine-1.0rc5 -reactos/dll/win32/printui # Synced to Wine-1.7.1 -reactos/dll/win32/propsys # Synced to Wine-1.7.1 -reactos/dll/win32/pstorec # Synced to Wine-1.7.1 -reactos/dll/win32/qmgr # Synced to Wine-1.7.1 -reactos/dll/win32/qmgrprxy # Synced to Wine-1.7.1 -reactos/dll/win32/query # Synced to Wine-1.7.1 -reactos/dll/win32/rasapi32 # Synced to Wine-1.7.1 -reactos/dll/win32/resutils # Synced to Wine-1.7.1 -reactos/dll/win32/riched20 # Synced to Wine-1.7.1 -reactos/dll/win32/riched32 # Synced to Wine-1.7.1 -reactos/dll/win32/rpcrt4 # Synced to Wine-1.7.1 -reactos/dll/win32/rsabase # Synced to Wine-1.7.1 +reactos/dll/win32/printui # Synced to Wine-1.7.17 +reactos/dll/win32/propsys # Synced to Wine-1.7.17 +reactos/dll/win32/pstorec # Synced to Wine-1.7.17 +reactos/dll/win32/qmgr # Synced to Wine-1.7.17 +reactos/dll/win32/qmgrprxy # Synced to Wine-1.7.17 +reactos/dll/win32/query # Synced to Wine-1.7.17 +reactos/dll/win32/rasapi32 # Synced to Wine-1.7.17 +reactos/dll/win32/resutils # Synced to Wine-1.7.17 +reactos/dll/win32/riched20 # Synced to Wine-1.7.17 +reactos/dll/win32/riched32 # Synced to Wine-1.7.17 +reactos/dll/win32/rpcrt4 # Synced to Wine-1.7.17 +reactos/dll/win32/rsabase # Synced to Wine-1.7.17 reactos/dll/win32/rsaenh # Synced to Wine-1.7.17 -reactos/dll/win32/sccbase # Synced to Wine-1.7.1 -reactos/dll/win32/schannel # Synced to Wine-1.7.1 +reactos/dll/win32/sccbase # Synced to Wine-1.7.17 +reactos/dll/win32/schannel # Synced to Wine-1.7.17 reactos/dll/win32/scrrun # Synced to Wine-1.7.17 reactos/dll/win32/secur32 # Forked reactos/dll/win32/security # Forked (different .spec) -reactos/dll/win32/sensapi # Synced to Wine-1.7.1 +reactos/dll/win32/sensapi # Synced to Wine-1.7.17 reactos/dll/win32/setupapi # Forked at Wine-20050524 -reactos/dll/win32/shdoclc # Synced to Wine-1.7.1 -reactos/dll/win32/shdocvw # Synced to Wine-1.7.1 +reactos/dll/win32/shdoclc # Synced to Wine-1.7.17 +reactos/dll/win32/shdocvw # Synced to Wine-1.7.17 reactos/dll/win32/shell32 # Forked at Wine-20071011 -reactos/dll/win32/shfolder # Synced to Wine-1.7.1 +reactos/dll/win32/shfolder # Synced to Wine-1.7.17 reactos/dll/win32/shlwapi # Synced to Wine-1.7.17 -reactos/dll/win32/slbcsp # Synced to Wine-1.7.1 -reactos/dll/win32/snmpapi # Synced to Wine-1.7.1 -reactos/dll/win32/softpub # Synced to Wine-1.7.1 -reactos/dll/win32/spoolss # Synced to Wine-1.7.1 -reactos/dll/win32/stdole2.tlb # Synced to Wine-1.7.1 -reactos/dll/win32/stdole32.tlb # Synced to Wine-1.7.1 -reactos/dll/win32/sti # Synced to Wine-1.7.1 -reactos/dll/win32/sxs # Synced to Wine-1.7.1 +reactos/dll/win32/slbcsp # Synced to Wine-1.7.17 +reactos/dll/win32/snmpapi # Synced to Wine-1.7.17 +reactos/dll/win32/softpub # Synced to Wine-1.7.17 +reactos/dll/win32/spoolss # Synced to Wine-1.7.17 +reactos/dll/win32/stdole2.tlb # Synced to Wine-1.7.17 +reactos/dll/win32/stdole32.tlb # Synced to Wine-1.7.17 +reactos/dll/win32/sti # Synced to Wine-1.7.17 +reactos/dll/win32/sxs # Synced to Wine-1.7.17 reactos/dll/win32/tapi32 # Synced to Wine-1.7.17 -reactos/dll/win32/traffic # Synced to Wine-1.7.1 +reactos/dll/win32/traffic # Synced to Wine-1.7.17 reactos/dll/win32/twain_32 # Synced to Wine-1.7.17 reactos/dll/win32/unicows # Synced to Wine-1.3.32 (Win9x only, why do we need this?!) -reactos/dll/win32/updspapi # Synced to Wine-1.7.1 +reactos/dll/win32/updspapi # Synced to Wine-1.7.17 reactos/dll/win32/url # Synced to Wine-1.7.17 reactos/dll/win32/urlmon # Synced to Wine-1.7.17 reactos/dll/win32/usp10 # Synced to Wine-1.7.17 reactos/dll/win32/uxtheme # Forked reactos/dll/win32/vbscript # Synced to Wine-1.7.17 -reactos/dll/win32/version # Synced to Wine-1.7.1 +reactos/dll/win32/version # Synced to Wine-1.7.17 reactos/dll/win32/wbemdisp # Synced to Wine-1.7.17 -reactos/dll/win32/wbemprox # Synced to Wine-1.7.2 +reactos/dll/win32/wbemprox # Synced to Wine-1.7.17 reactos/dll/win32/wer # Autosync reactos/dll/win32/windowscodecs # Synced to Wine-1.7.17 -reactos/dll/win32/windowscodecsext # Synced to Wine-1.7.1 -reactos/dll/win32/winemp3.acm # Synced to Wine-1.7.1 +reactos/dll/win32/windowscodecsext # Synced to Wine-1.7.17 +reactos/dll/win32/winemp3.acm # Synced to Wine-1.7.17 reactos/dll/win32/wing32 # Out of sync -reactos/dll/win32/winhttp # Synced to Wine-1.7.1 -reactos/dll/win32/wininet # Synced to Wine-1.7.1 +reactos/dll/win32/winhttp # Synced to Wine-1.7.17 +reactos/dll/win32/wininet # Synced to Wine-1.7.17 reactos/dll/win32/winmm # Forked at Wine-20050628 reactos/dll/win32/winmm/midimap # Forked at Wine-20050628 reactos/dll/win32/winmm/wavemap # Forked at Wine-20050628 reactos/dll/win32/wintrust # Synced to Wine-1.7.17 reactos/dll/win32/wldap32 # Synced to Wine-1.7.17 reactos/dll/win32/wmi # Synced to Wine-1.7.17 -reactos/dll/win32/wtsapi32 # Synced to Wine-1.7.1 -reactos/dll/win32/wuapi # Synced to Wine-1.7.1 -reactos/dll/win32/xinput1_1 # Synced to Wine-1.7.1 -reactos/dll/win32/xinput1_2 # Synced to Wine-1.7.1 -reactos/dll/win32/xinput1_3 # Synced to Wine-1.7.1 -reactos/dll/win32/xinput9_1_0 # Synced to Wine-1.7.1 +reactos/dll/win32/wtsapi32 # Synced to Wine-1.7.17 +reactos/dll/win32/wuapi # Synced to Wine-1.7.17 +reactos/dll/win32/xinput1_1 # Synced to Wine-1.7.17 +reactos/dll/win32/xinput1_2 # Synced to Wine-1.7.17 +reactos/dll/win32/xinput1_3 # Synced to Wine-1.7.17 +reactos/dll/win32/xinput9_1_0 # Synced to Wine-1.7.17 reactos/dll/win32/xmllite # Synced to Wine-1.7.17 reactos/dll/cpl/inetcpl # Synced to Wine-1.7.1 @@ -275,6 +275,7 @@ kernel32 - msvcrt - reactos/lib/sdk/crt/except/cpp.c # Synced at 20080528 reactos/lib/sdk/crt/except/cppexcept.c # Synced at 20071111 + reactos/lib/sdk/crt/signal/xcptinfo.c # Synced to Wine-1.7.17 reactos/lib/sdk/crt/string/scanf.c/h # Synced to Wine-1_1_27 reactos/lib/sdk/crt/strings/wcs.c # Synced at 20080611 reactos/lib/sdk/crt/wine/heap.c # Synced at 20080529 @@ -290,9 +291,9 @@ User32 - reactos/dll/win32/user32/controls/scrollbar.c # Forked reactos/dll/win32/user32/controls/static.c # Synced to Wine-1_1_39 - reactos/dll/win32/user32/include/dde_private.h # Synced to wine 1.1.24 + reactos/dll/win32/user32/include/dde_private.h # Synced to Wine-1.1.24 - reactos/dll/win32/user32/misc/dde.c # Synced to wine 1.1.24 (dde_misc.c) + reactos/dll/win32/user32/misc/dde.c # Synced to Wine-1.1.24 (dde_misc.c) reactos/dll/win32/user32/misc/ddeclient.c # Synced to Wine-1_1_23 reactos/dll/win32/user32/misc/ddeserver.c # Synced to Wine-1_1_23 reactos/dll/win32/user32/misc/exticon.c # Synced to Wine-1_1_22 @@ -300,7 +301,7 @@ User32 - reactos/dll/win32/user32/misc/winhelp.c # Last sync date unknown reactos/dll/win32/user32/misc/wsprintf.c # Synced to Wine-1_1_23 - reactos/dll/win32/user32/windows/cursoricon # Forked from wine 1.2-rc7 + reactos/dll/win32/user32/windows/cursoricon # Forked from Wine-1.2-rc7 reactos/dll/win32/user32/windows/defwnd.c # Forked reactos/dll/win32/user32/windows/draw.c # Forked at Wine-20020904 (uitools.c) reactos/dll/win32/user32/windows/mdi.c # Synced to Wine-1_1_40 diff --git a/ntoskrnl/fstub/fstubex.c b/ntoskrnl/fstub/fstubex.c index e864c1f09cd..d039e718b1c 100644 --- a/ntoskrnl/fstub/fstubex.c +++ b/ntoskrnl/fstub/fstubex.c @@ -1006,7 +1006,7 @@ FstubReadPartitionTableEFI(IN PDISK_INFORMATION Disk, if ((Disk->SectorCount - 1ULL) != EfiHeader->AlternateLBA) { /* We'll update it. First, count number of sectors needed to store partitions */ - SectorsForPartitions = (EfiHeader->NumberOfEntries * PARTITION_ENTRY_SIZE) / Disk->SectorSize; + SectorsForPartitions = ((ULONGLONG)EfiHeader->NumberOfEntries * PARTITION_ENTRY_SIZE) / Disk->SectorSize; /* Then set first usable LBA: Legacy MBR + GPT header + Partitions entries */ EfiHeader->FirstUsableLBA = SectorsForPartitions + 2; /* Then set last usable LBA: Last sector - GPT header - Partitions entries */ @@ -1313,7 +1313,7 @@ FstubVerifyPartitionTableEFI(IN PDISK_INFORMATION Disk, } /* Compute sectors taken by partitions */ - SectorsForPartitions = ((EFIHeader->NumberOfEntries * PARTITION_ENTRY_SIZE) + Disk->SectorSize - 1) / Disk->SectorSize; + SectorsForPartitions = (((ULONGLONG)EFIHeader->NumberOfEntries * PARTITION_ENTRY_SIZE) + Disk->SectorSize - 1) / Disk->SectorSize; if (PrimaryValid) { WriteBackup = TRUE; diff --git a/ntoskrnl/include/internal/i386/trap_x.h b/ntoskrnl/include/internal/i386/trap_x.h index 86f7c77d02e..99e7cba3262 100644 --- a/ntoskrnl/include/internal/i386/trap_x.h +++ b/ntoskrnl/include/internal/i386/trap_x.h @@ -180,6 +180,11 @@ KiExitTrapDebugChecks(IN PKTRAP_FRAME TrapFrame, StopChecking = FALSE; } +#else +#define KiExitTrapDebugChecks(x, y) +#define KiFillTrapFrameDebug(x) +#endif + FORCEINLINE VOID KiExitSystemCallDebugChecks(IN ULONG SystemCall, @@ -219,11 +224,6 @@ KiExitSystemCallDebugChecks(IN ULONG SystemCall, } } } -#else -#define KiExitTrapDebugChecks(x, y) -#define KiFillTrapFrameDebug(x) -#define KiExitSystemCallDebugChecks(x, y) -#endif // // Generic Exit Routine diff --git a/ntoskrnl/io/iomgr/iofunc.c b/ntoskrnl/io/iomgr/iofunc.c index f1f56d0a614..e2830022c5b 100644 --- a/ntoskrnl/io/iomgr/iofunc.c +++ b/ntoskrnl/io/iomgr/iofunc.c @@ -635,6 +635,236 @@ IopQueryDeviceInformation(IN PFILE_OBJECT FileObject, return Status; } +NTSTATUS +NTAPI +IopGetFileInformation(IN PFILE_OBJECT FileObject, + IN ULONG Length, + IN FILE_INFORMATION_CLASS FileInfoClass, + OUT PVOID Buffer, + OUT PULONG ReturnedLength) +{ + PIRP Irp; + KEVENT Event; + NTSTATUS Status; + PIO_STACK_LOCATION Stack; + PDEVICE_OBJECT DeviceObject; + IO_STATUS_BLOCK IoStatusBlock; + + PAGED_CODE(); + + /* Allocate an IRP */ + ObReferenceObject(FileObject); + DeviceObject = IoGetRelatedDeviceObject(FileObject); + Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); + if (Irp == NULL) + { + ObDereferenceObject(FileObject); + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* Init event */ + KeInitializeEvent(&Event, SynchronizationEvent, FALSE); + + /* Setup the IRP */ + Irp->UserIosb = &IoStatusBlock; + Irp->UserEvent = &Event; + Irp->Overlay.AsynchronousParameters.UserApcRoutine = NULL; + Irp->RequestorMode = KernelMode; + Irp->AssociatedIrp.SystemBuffer = Buffer; + Irp->Flags = IRP_SYNCHRONOUS_API | IRP_BUFFERED_IO | IRP_OB_QUERY_NAME; + Irp->Tail.Overlay.OriginalFileObject = FileObject; + Irp->Tail.Overlay.Thread = PsGetCurrentThread(); + + Stack = IoGetNextIrpStackLocation(Irp); + Stack->MajorFunction = IRP_MJ_QUERY_INFORMATION; + Stack->FileObject = FileObject; + Stack->Parameters.QueryFile.FileInformationClass = FileInfoClass; + Stack->Parameters.QueryFile.Length = Length; + + + /* Queue the IRP */ + IopQueueIrpToThread(Irp); + + /* Call the driver */ + Status = IoCallDriver(DeviceObject, Irp); + if (Status == STATUS_PENDING) + { + KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); + Status = IoStatusBlock.Status; + } + + *ReturnedLength = IoStatusBlock.Information; + return Status; +} + +NTSTATUS +NTAPI +IopGetBasicInformationFile(IN PFILE_OBJECT FileObject, + OUT PFILE_BASIC_INFORMATION BasicInfo) +{ + ULONG ReturnedLength; + PDEVICE_OBJECT DeviceObject; + IO_STATUS_BLOCK IoStatusBlock; + + PAGED_CODE(); + + /* Try to do it the fast way if possible */ + DeviceObject = IoGetRelatedDeviceObject(FileObject); + if (DeviceObject->DriverObject->FastIoDispatch != NULL && + DeviceObject->DriverObject->FastIoDispatch->FastIoQueryBasicInfo != NULL && + DeviceObject->DriverObject->FastIoDispatch->FastIoQueryBasicInfo(FileObject, + ((FileObject->Flags & FO_SYNCHRONOUS_IO) != 0), + BasicInfo, + &IoStatusBlock, + DeviceObject)) + { + return IoStatusBlock.Status; + } + + /* In case it failed, fall back to IRP-based method */ + return IopGetFileInformation(FileObject, sizeof(FILE_BASIC_INFORMATION), FileBasicInformation, BasicInfo, &ReturnedLength); +} + +NTSTATUS +NTAPI +IopOpenLinkOrRenameTarget(OUT PHANDLE Handle, + IN PIRP Irp, + IN PFILE_RENAME_INFORMATION RenameInfo, + IN PFILE_OBJECT FileObject) +{ + NTSTATUS Status; + HANDLE TargetHandle; + UNICODE_STRING FileName; + PIO_STACK_LOCATION Stack; + PFILE_OBJECT TargetFileObject; + IO_STATUS_BLOCK IoStatusBlock; + FILE_BASIC_INFORMATION BasicInfo; + OBJECT_ATTRIBUTES ObjectAttributes; + OBJECT_HANDLE_INFORMATION HandleInformation; + ACCESS_MASK DesiredAccess = FILE_WRITE_DATA; + + PAGED_CODE(); + + /* First, establish whether our target is a directory */ + if (!(FileObject->Flags & FO_DIRECT_DEVICE_OPEN)) + { + Status = IopGetBasicInformationFile(FileObject, &BasicInfo); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + if (BasicInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + DesiredAccess = FILE_ADD_SUBDIRECTORY; + } + } + + /* Setup the string to the target */ + FileName.Buffer = RenameInfo->FileName; + FileName.Length = RenameInfo->FileNameLength; + FileName.MaximumLength = RenameInfo->FileNameLength; + + InitializeObjectAttributes(&ObjectAttributes, + &FileName, + (FileObject->Flags & FO_OPENED_CASE_SENSITIVE ? 0 : OBJ_CASE_INSENSITIVE) | OBJ_KERNEL_HANDLE, + RenameInfo->RootDirectory, + NULL); + + /* And open its parent directory */ + if (FileObject->Flags & FO_FILE_OBJECT_HAS_EXTENSION) + { + ASSERT(!(FileObject->Flags & FO_DIRECT_DEVICE_OPEN)); +#if 0 + /* Commented out - we don't support FO extension yet + * FIXME: Corrected last arg when it's supported + */ + Status = IoCreateFileSpecifyDeviceObjectHint(&TargetHandle, + DesiredAccess | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + NULL, + 0, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_OPEN, + FILE_OPEN_FOR_BACKUP_INTENT, + NULL, + 0, + CreateFileTypeNone, + NULL, + IO_FORCE_ACCESS_CHECK | IO_OPEN_TARGET_DIRECTORY | IO_NO_PARAMETER_CHECKING, + FileObject->DeviceObject); +#else + ASSERT(FALSE); + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; +#endif + } + else + { + Status = IoCreateFile(&TargetHandle, + DesiredAccess | SYNCHRONIZE, + &ObjectAttributes, + &IoStatusBlock, + NULL, + 0, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_OPEN, + FILE_OPEN_FOR_BACKUP_INTENT, + NULL, + 0, + CreateFileTypeNone, + NULL, + IO_FORCE_ACCESS_CHECK | IO_OPEN_TARGET_DIRECTORY | IO_NO_PARAMETER_CHECKING); + } + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + /* Once open, continue only if: + * Target exists and we're allowed to overwrite it + */ + Stack = IoGetNextIrpStackLocation(Irp); + if (Stack->Parameters.SetFile.FileInformationClass == FileLinkInformation && + !RenameInfo->ReplaceIfExists && + IoStatusBlock.Information == FILE_EXISTS) + { + ObCloseHandle(TargetHandle, KernelMode); + return STATUS_OBJECT_NAME_COLLISION; + } + + /* Now, we'll get the associated device of the target, to check for same device location + * So, get the FO first + */ + Status = ObReferenceObjectByHandle(TargetHandle, + FILE_WRITE_DATA, + IoFileObjectType, + KernelMode, + (PVOID *)&TargetFileObject, + &HandleInformation); + if (!NT_SUCCESS(Status)) + { + ObCloseHandle(TargetHandle, KernelMode); + return Status; + } + + /* We can dereference, we have the handle */ + ObDereferenceObject(TargetFileObject); + /* If we're not on the same device, error out **/ + if (IoGetRelatedDeviceObject(TargetFileObject) != IoGetRelatedDeviceObject(FileObject)) + { + ObCloseHandle(TargetHandle, KernelMode); + return STATUS_NOT_SAME_DEVICE; + } + + /* Return parent directory file object and handle */ + Stack->Parameters.SetFile.FileObject = TargetFileObject; + *Handle = TargetHandle; + + return STATUS_SUCCESS; +} + /* PUBLIC FUNCTIONS **********************************************************/ /* @@ -2218,6 +2448,8 @@ NtSetInformationFile(IN HANDLE FileHandle, PVOID Queue; PFILE_COMPLETION_INFORMATION CompletionInfo = FileInformation; PIO_COMPLETION_CONTEXT Context; + PFILE_RENAME_INFORMATION RenameInfo; + HANDLE TargetHandle = NULL; PAGED_CODE(); IOTRACE(IO_API_DEBUG, "FileHandle: %p\n", FileHandle); @@ -2469,6 +2701,58 @@ NtSetInformationFile(IN HANDLE FileHandle, Irp->IoStatus.Status = Status; Irp->IoStatus.Information = 0; } + else if (FileInformationClass == FileRenameInformation || + FileInformationClass == FileLinkInformation || + FileInformationClass == FileMoveClusterInformation) + { + /* Get associated information */ + RenameInfo = Irp->AssociatedIrp.SystemBuffer; + + /* Only rename if: + * -> We have a name + * -> In unicode + * -> sizes are valid + */ + if (RenameInfo->FileNameLength != 0 && + !(RenameInfo->FileNameLength & 1) && + (Length - FIELD_OFFSET(FILE_RENAME_INFORMATION, FileName) >= RenameInfo->FileNameLength)) + { + /* Properly set information received */ + if (FileInformationClass == FileMoveClusterInformation) + { + StackPtr->Parameters.SetFile.ClusterCount = ((PFILE_MOVE_CLUSTER_INFORMATION)RenameInfo)->ClusterCount; + } + else + { + StackPtr->Parameters.SetFile.ReplaceIfExists = RenameInfo->ReplaceIfExists; + } + + /* If we got fully path OR relative target, attempt a parent directory open */ + if (RenameInfo->FileName[0] == OBJ_NAME_PATH_SEPARATOR || RenameInfo->RootDirectory) + { + Status = IopOpenLinkOrRenameTarget(&TargetHandle, Irp, RenameInfo, FileObject); + if (!NT_SUCCESS(Status)) + { + Irp->IoStatus.Status = Status; + } + else + { + /* Call the Driver */ + Status = IoCallDriver(DeviceObject, Irp); + } + } + else + { + /* Call the Driver */ + Status = IoCallDriver(DeviceObject, Irp); + } + } + else + { + Status = STATUS_INVALID_PARAMETER; + Irp->IoStatus.Status = Status; + } + } else { /* Call the Driver */ @@ -2560,6 +2844,11 @@ NtSetInformationFile(IN HANDLE FileHandle, if (!LocalEvent) IopUnlockFileObject(FileObject); } + if (TargetHandle != NULL) + { + ObCloseHandle(TargetHandle, KernelMode); + } + /* Return the Status */ return Status; } diff --git a/ntoskrnl/io/iomgr/irp.c b/ntoskrnl/io/iomgr/irp.c index 609636e3676..f768c7649d2 100644 --- a/ntoskrnl/io/iomgr/irp.c +++ b/ntoskrnl/io/iomgr/irp.c @@ -591,16 +591,18 @@ IoAllocateIrp(IN CCHAR StackSize, /* Check if we should charge quota */ if (ChargeQuota) { - Irp = ExAllocatePoolWithQuotaTag(NonPagedPool, Size, TAG_IRP); + Irp = ExAllocatePoolWithQuotaTag(NonPagedPool | POOL_QUOTA_FAIL_INSTEAD_OF_RAISE, + Size, + TAG_IRP); } else { - /* Allocate the IRP With no Quota charge */ + /* Allocate the IRP with no quota charge */ Irp = ExAllocatePoolWithTag(NonPagedPool, Size, TAG_IRP); } /* Make sure it was sucessful */ - if (!Irp) return(NULL); + if (!Irp) return NULL; } else { diff --git a/win32ss/drivers/font/bmfd/glyph.c b/win32ss/drivers/font/bmfd/glyph.c index 55e0cdb952b..da4642a0c82 100644 --- a/win32ss/drivers/font/bmfd/glyph.c +++ b/win32ss/drivers/font/bmfd/glyph.c @@ -7,8 +7,8 @@ #include "bmfd.h" -ULONG FORCEINLINE +ULONG _ReadPixel( CHAR* pjBits, ULONG x, @@ -21,8 +21,8 @@ _ReadPixel( } -VOID FORCEINLINE +VOID _WritePixel( CHAR* pjBits, ULONG x, diff --git a/win32ss/gdi/eng/engbrush.c b/win32ss/gdi/eng/engbrush.c index 81d2a977efd..c9de13d901b 100644 --- a/win32ss/gdi/eng/engbrush.c +++ b/win32ss/gdi/eng/engbrush.c @@ -362,8 +362,7 @@ EBRUSHOBJ_bRealizeBrush(EBRUSHOBJ *pebo, BOOL bCallDriver) EXLATEOBJ_vCleanup(&exlo); /* Unlock surfaces */ - if (psurfPattern) - SURFACE_ShareUnlockSurface(psurfPattern); + SURFACE_ShareUnlockSurface(psurfPattern); if (psurfMask) SURFACE_ShareUnlockSurface(psurfMask); diff --git a/win32ss/gdi/eng/engmisc.c b/win32ss/gdi/eng/engmisc.c index 56d0fadd29b..076aead1eca 100644 --- a/win32ss/gdi/eng/engmisc.c +++ b/win32ss/gdi/eng/engmisc.c @@ -245,22 +245,34 @@ EngQuerySystemAttribute( { SYSTEM_BASIC_INFORMATION sbi; SYSTEM_PROCESSOR_INFORMATION spi; + NTSTATUS status; switch (CapNum) { case EngNumberOfProcessors: - NtQuerySystemInformation(SystemBasicInformation, - &sbi, - sizeof(SYSTEM_BASIC_INFORMATION), - NULL); + status = NtQuerySystemInformation(SystemBasicInformation, + &sbi, + sizeof(SYSTEM_BASIC_INFORMATION), + NULL); + if (!NT_SUCCESS(status)) + { + DPRINT1("Failed to query basic information: 0x%lx\n", status); + return FALSE; + } + *pCapability = sbi.NumberOfProcessors; return TRUE; case EngProcessorFeature: - NtQuerySystemInformation(SystemProcessorInformation, - &spi, - sizeof(SYSTEM_PROCESSOR_INFORMATION), - NULL); + status = NtQuerySystemInformation(SystemProcessorInformation, + &spi, + sizeof(SYSTEM_PROCESSOR_INFORMATION), + NULL); + if (!NT_SUCCESS(status)) + { + DPRINT1("Failed to query processor information: 0x%lx\n", status); + return FALSE; + } *pCapability = spi.ProcessorFeatureBits; return TRUE; diff --git a/win32ss/gdi/eng/gradient.c b/win32ss/gdi/eng/gradient.c index 24a55cc32d4..784f21600cb 100644 --- a/win32ss/gdi/eng/gradient.c +++ b/win32ss/gdi/eng/gradient.c @@ -38,7 +38,8 @@ const LONG LINC[2] = {-1, 1}; /* FUNCTIONS ******************************************************************/ -BOOL FASTCALL +BOOL +FASTCALL IntEngGradientFillRect( IN SURFOBJ *psoDest, IN CLIPOBJ *pco, @@ -50,129 +51,137 @@ IntEngGradientFillRect( IN POINTL *pptlDitherOrg, IN BOOL Horizontal) { - SURFOBJ *psoOutput; - TRIVERTEX *v1, *v2; - RECTL rcGradient, rcSG; - RECT_ENUM RectEnum; - BOOL EnumMore; - ULONG i; - POINTL Translate; - INTENG_ENTER_LEAVE EnterLeave; - LONG y, dy, c[3], dc[3], ec[3], ic[3]; + SURFOBJ *psoOutput; + TRIVERTEX *v1, *v2; + RECTL rcGradient, rcSG; + RECT_ENUM RectEnum; + BOOL EnumMore; + ULONG i; + POINTL Translate; + INTENG_ENTER_LEAVE EnterLeave; + LONG y, dy, c[3], dc[3], ec[3], ic[3]; - v1 = (pVertex + gRect->UpperLeft); - v2 = (pVertex + gRect->LowerRight); + v1 = (pVertex + gRect->UpperLeft); + v2 = (pVertex + gRect->LowerRight); - rcGradient.left = min(v1->x, v2->x); - rcGradient.right = max(v1->x, v2->x); - rcGradient.top = min(v1->y, v2->y); - rcGradient.bottom = max(v1->y, v2->y); - rcSG = rcGradient; - RECTL_vOffsetRect(&rcSG, pptlDitherOrg->x, pptlDitherOrg->y); + rcGradient.left = min(v1->x, v2->x); + rcGradient.right = max(v1->x, v2->x); + rcGradient.top = min(v1->y, v2->y); + rcGradient.bottom = max(v1->y, v2->y); + rcSG = rcGradient; + RECTL_vOffsetRect(&rcSG, pptlDitherOrg->x, pptlDitherOrg->y); - if(Horizontal) - { - dy = abs(rcGradient.right - rcGradient.left); - } - else - { - dy = abs(rcGradient.bottom - rcGradient.top); - } + if(Horizontal) + { + dy = abs(rcGradient.right - rcGradient.left); + } + else + { + dy = abs(rcGradient.bottom - rcGradient.top); + } - if(!IntEngEnter(&EnterLeave, psoDest, &rcSG, FALSE, &Translate, &psoOutput)) - { - return FALSE; - } + if(!IntEngEnter(&EnterLeave, psoDest, &rcSG, FALSE, &Translate, &psoOutput)) + { + return FALSE; + } - if((v1->Red != v2->Red || v1->Green != v2->Green || v1->Blue != v2->Blue) && dy > 1) - { + if((v1->Red != v2->Red || v1->Green != v2->Green || v1->Blue != v2->Blue) && dy > 1) + { + CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0); + do + { + RECTL FillRect; + ULONG Color; + + if (Horizontal) + { + EnumMore = CLIPOBJ_bEnum(pco, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum); + for (i = 0; i < RectEnum.c && RectEnum.arcl[i].top <= rcSG.bottom; i++) + { + if (RECTL_bIntersectRect(&FillRect, &RectEnum.arcl[i], &rcSG)) + { + HVINITCOL(Red, 0); + HVINITCOL(Green, 1); + HVINITCOL(Blue, 2); + + for (y = rcSG.left; y < FillRect.right; y++) + { + if (y >= FillRect.left) + { + Color = XLATEOBJ_iXlate(pxlo, RGB(c[0], c[1], c[2])); + DibFunctionsForBitmapFormat[psoOutput->iBitmapFormat].DIB_VLine( + psoOutput, y + Translate.x, FillRect.top + Translate.y, FillRect.bottom + Translate.y, Color); + } + HVSTEPCOL(0); + HVSTEPCOL(1); + HVSTEPCOL(2); + } + } + } + + continue; + } + + /* vertical */ + EnumMore = CLIPOBJ_bEnum(pco, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum); + for (i = 0; i < RectEnum.c && RectEnum.arcl[i].top <= rcSG.bottom; i++) + { + if (RECTL_bIntersectRect(&FillRect, &RectEnum.arcl[i], &rcSG)) + { + HVINITCOL(Red, 0); + HVINITCOL(Green, 1); + HVINITCOL(Blue, 2); + + for (y = rcSG.top; y < FillRect.bottom; y++) + { + if (y >= FillRect.top) + { + Color = XLATEOBJ_iXlate(pxlo, RGB(c[0], c[1], c[2])); + DibFunctionsForBitmapFormat[psoOutput->iBitmapFormat].DIB_HLine(psoOutput, + FillRect.left + Translate.x, + FillRect.right + Translate.x, + y + Translate.y, + Color); + } + HVSTEPCOL(0); + HVSTEPCOL(1); + HVSTEPCOL(2); + } + } + } + + } + while (EnumMore); + + return IntEngLeave(&EnterLeave); + } + + /* rectangle has only one color, no calculation required */ CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0); do { - RECTL FillRect; - ULONG Color; + RECTL FillRect; + ULONG Color = XLATEOBJ_iXlate(pxlo, RGB(v1->Red, v1->Green, v1->Blue)); - if(Horizontal) - { EnumMore = CLIPOBJ_bEnum(pco, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum); for (i = 0; i < RectEnum.c && RectEnum.arcl[i].top <= rcSG.bottom; i++) { - if(RECTL_bIntersectRect(&FillRect, &RectEnum.arcl[i], &rcSG)) - { - HVINITCOL(Red, 0); - HVINITCOL(Green, 1); - HVINITCOL(Blue, 2); - - for(y = rcSG.left; y < FillRect.right; y++) + if (RECTL_bIntersectRect(&FillRect, &RectEnum.arcl[i], &rcSG)) { - if(y >= FillRect.left) - { - Color = XLATEOBJ_iXlate(pxlo, RGB(c[0], c[1], c[2])); - DibFunctionsForBitmapFormat[psoOutput->iBitmapFormat].DIB_VLine( - psoOutput, y + Translate.x, FillRect.top + Translate.y, FillRect.bottom + Translate.y, Color); - } - HVSTEPCOL(0); - HVSTEPCOL(1); - HVSTEPCOL(2); + for (; FillRect.top < FillRect.bottom; FillRect.top++) + { + DibFunctionsForBitmapFormat[psoOutput->iBitmapFormat].DIB_HLine(psoOutput, + FillRect.left + Translate.x, + FillRect.right + Translate.x, + FillRect.top + Translate.y, + Color); + } } - } } - - continue; - } - - /* vertical */ - EnumMore = CLIPOBJ_bEnum(pco, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum); - for (i = 0; i < RectEnum.c && RectEnum.arcl[i].top <= rcSG.bottom; i++) - { - if(RECTL_bIntersectRect(&FillRect, &RectEnum.arcl[i], &rcSG)) - { - HVINITCOL(Red, 0); - HVINITCOL(Green, 1); - HVINITCOL(Blue, 2); - - for(y = rcSG.top; y < FillRect.bottom; y++) - { - if(y >= FillRect.top) - { - Color = XLATEOBJ_iXlate(pxlo, RGB(c[0], c[1], c[2])); - DibFunctionsForBitmapFormat[psoOutput->iBitmapFormat].DIB_HLine( - psoOutput, FillRect.left + Translate.x, FillRect.right + Translate.x, y + Translate.y, Color); - } - HVSTEPCOL(0); - HVSTEPCOL(1); - HVSTEPCOL(2); - } - } - } - - } while(EnumMore); + } + while (EnumMore); return IntEngLeave(&EnterLeave); - } - - /* rectangle has only one color, no calculation required */ - CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0); - do - { - RECTL FillRect; - ULONG Color = XLATEOBJ_iXlate(pxlo, RGB(v1->Red, v1->Green, v1->Blue)); - - EnumMore = CLIPOBJ_bEnum(pco, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum); - for (i = 0; i < RectEnum.c && RectEnum.arcl[i].top <= rcSG.bottom; i++) - { - if(RECTL_bIntersectRect(&FillRect, &RectEnum.arcl[i], &rcSG)) - { - for(; FillRect.top < FillRect.bottom; FillRect.top++) - { - DibFunctionsForBitmapFormat[psoOutput->iBitmapFormat].DIB_HLine( - psoOutput, FillRect.left + Translate.x, FillRect.right + Translate.x, FillRect.top + Translate.y, Color); - } - } - } - } while(EnumMore); - - return IntEngLeave(&EnterLeave); } /* Fill triangle with solid color */ @@ -181,6 +190,7 @@ IntEngGradientFillRect( DibFunctionsForBitmapFormat[psoOutput->iBitmapFormat].DIB_HLine(psoOutput, max(sx[lineto], FillRect.left), min(sx[linefrom], FillRect.right), sy, Color); \ else \ DibFunctionsForBitmapFormat[psoOutput->iBitmapFormat].DIB_HLine(psoOutput, max(sx[linefrom], FillRect.left), min(sx[lineto], FillRect.right), sy, Color); + #define S_DOLINE(a,b,line) \ ex[line] += dx[line]; \ while(ex[line] > 0 && x[line] != destx[line]) \ @@ -189,11 +199,14 @@ IntEngGradientFillRect( sx[line] += incx[line]; \ ex[line] -= dy[line]; \ } + #define S_GOLINE(a,b,line) \ if(y >= a->y && y <= b->y) \ { + #define S_ENDLINE(a,b,line) \ } + #define S_INITLINE(a,b,line) \ x[line] = a->x; \ sx[line] = a->x + pptlDitherOrg->x; \ @@ -209,6 +222,7 @@ IntEngGradientFillRect( dc[line][id] = abs((b->col >> 8) - c[line][id]); \ ec[line][id] = -(dy[line]>>1); \ ic[line][id] = LINC[(b->col >> 8) > c[line][id]] + #define STEPCOL(a,b,line,col,id) \ ec[line][id] += dc[line][id]; \ while(ec[line][id] > 0) \ @@ -216,11 +230,13 @@ IntEngGradientFillRect( c[line][id] += ic[line][id]; \ ec[line][id] -= dy[line]; \ } + #define FINITCOL(linefrom,lineto,colid) \ gc[colid] = c[linefrom][colid]; \ gd[colid] = abs(c[lineto][colid] - gc[colid]); \ ge[colid] = -(gx >> 1); \ gi[colid] = LINC[c[lineto][colid] > gc[colid]] + #define FDOCOL(linefrom,lineto,colid) \ ge[colid] += gd[colid]; \ while(ge[colid] > 0) \ @@ -228,6 +244,7 @@ IntEngGradientFillRect( gc[colid] += gi[colid]; \ ge[colid] -= gx; \ } + #define FILLLINE(linefrom,lineto) \ gx = abs(sx[lineto] - sx[linefrom]); \ gxi = LINC[sx[linefrom] < sx[lineto]]; \ @@ -245,6 +262,7 @@ IntEngGradientFillRect( FDOCOL(linefrom, lineto, 1); \ FDOCOL(linefrom, lineto, 2); \ } + #define DOLINE(a,b,line) \ STEPCOL(a, b, line, Red, 0); \ STEPCOL(a, b, line, Green, 1); \ @@ -256,11 +274,14 @@ IntEngGradientFillRect( sx[line] += incx[line]; \ ex[line] -= dy[line]; \ } + #define GOLINE(a,b,line) \ if(y >= a->y && y <= b->y) \ { + #define ENDLINE(a,b,line) \ } + #define INITLINE(a,b,line) \ x[line] = a->x; \ sx[line] = a->x + pptlDitherOrg->x; \ @@ -269,17 +290,23 @@ IntEngGradientFillRect( incx[line] = LINC[b->x > a->x]; \ ex[line] = -(dy[line]>>1); \ destx[line] = b->x + #define DOINIT(a, b, line) \ INITLINE(a, b, line); \ INITCOL(a, b, line, Red, 0); \ INITCOL(a, b, line, Green, 1); \ INITCOL(a, b, line, Blue, 2); + #define SMALLER(a,b) (a->y < b->y) || (a->y == b->y && a->x < b->x) + #define SWAP(a,b,c) c = a;\ a = b;\ b = c + #define NLINES 3 -BOOL FASTCALL + +BOOL +FASTCALL IntEngGradientFillTriangle( IN SURFOBJ *psoDest, IN CLIPOBJ *pco, @@ -290,158 +317,161 @@ IntEngGradientFillTriangle( IN RECTL *prclExtents, IN POINTL *pptlDitherOrg) { - SURFOBJ *psoOutput; - PTRIVERTEX v1, v2, v3; - //RECT_ENUM RectEnum; - //BOOL EnumMore; - //ULONG i; - POINTL Translate; - INTENG_ENTER_LEAVE EnterLeave; - RECTL FillRect = { 0, 0, 0, 0 }; - //ULONG Color; + SURFOBJ *psoOutput; + PTRIVERTEX v1, v2, v3; + //RECT_ENUM RectEnum; + //BOOL EnumMore; + //ULONG i; + POINTL Translate; + INTENG_ENTER_LEAVE EnterLeave; + RECTL FillRect = { 0, 0, 0, 0 }; + //ULONG Color; - //BOOL sx[NLINES]; - //LONG x[NLINES], dx[NLINES], dy[NLINES], incx[NLINES], ex[NLINES], destx[NLINES]; - //LONG c[NLINES][3], dc[NLINES][3], ec[NLINES][3], ic[NLINES][3]; /* colors on lines */ - //LONG g, gx, gxi, gc[3], gd[3], ge[3], gi[3]; /* colors in triangle */ - //LONG sy, y, bt; + //BOOL sx[NLINES]; + //LONG x[NLINES], dx[NLINES], dy[NLINES], incx[NLINES], ex[NLINES], destx[NLINES]; + //LONG c[NLINES][3], dc[NLINES][3], ec[NLINES][3], ic[NLINES][3]; /* colors on lines */ + //LONG g, gx, gxi, gc[3], gd[3], ge[3], gi[3]; /* colors in triangle */ + //LONG sy, y, bt; - v1 = (pVertex + gTriangle->Vertex1); - v2 = (pVertex + gTriangle->Vertex2); - v3 = (pVertex + gTriangle->Vertex3); + v1 = (pVertex + gTriangle->Vertex1); + v2 = (pVertex + gTriangle->Vertex2); + v3 = (pVertex + gTriangle->Vertex3); - /* bubble sort */ - if(SMALLER(v2,v1)) - { - TRIVERTEX *t; - SWAP(v1,v2,t); - } - if(SMALLER(v3,v2)) - { - TRIVERTEX *t; - SWAP(v2,v3,t); - if(SMALLER(v2,v1)) + /* bubble sort */ + if (SMALLER(v2, v1)) { - SWAP(v1,v2,t); + TRIVERTEX *t; + SWAP(v1, v2, t); } - } - DPRINT1("Triangle: (%i,%i) (%i,%i) (%i,%i)\n", v1->x, v1->y, v2->x, v2->y, v3->x, v3->y); - /* FIXME: commented out because of an endless loop - fix triangles first */ - DPRINT1("FIXME: IntEngGradientFillTriangle is broken\n"); + if (SMALLER(v3, v2)) + { + TRIVERTEX *t; + SWAP(v2, v3, t); + if (SMALLER(v2, v1)) + { + SWAP(v1, v2, t); + } + } - if(!IntEngEnter(&EnterLeave, psoDest, &FillRect, FALSE, &Translate, &psoOutput)) - { - return FALSE; - } + DPRINT1("Triangle: (%i,%i) (%i,%i) (%i,%i)\n", v1->x, v1->y, v2->x, v2->y, v3->x, v3->y); + /* FIXME: commented out because of an endless loop - fix triangles first */ + DPRINT1("FIXME: IntEngGradientFillTriangle is broken\n"); - //if(VCMPCLRS(v1, v2, v3)) - //{ - // CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0); - // do - // { - // EnumMore = CLIPOBJ_bEnum(pco, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum); - // for (i = 0; i < RectEnum.c && RectEnum.arcl[i].top <= prclExtents->bottom; i++) - // { - // if(RECTL_bIntersectRect(&FillRect, &RectEnum.arcl[i], prclExtents)) - // { - // BOOL InY; + if (!IntEngEnter(&EnterLeave, psoDest, &FillRect, FALSE, &Translate, &psoOutput)) + { + return FALSE; + } - // DOINIT(v1, v3, 0); - // DOINIT(v1, v2, 1); - // DOINIT(v2, v3, 2); + //if (VCMPCLRS(v1, v2, v3)) + //{ + // CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0); + // do + // { + // EnumMore = CLIPOBJ_bEnum(pco, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum); + // for (i = 0; i < RectEnum.c && RectEnum.arcl[i].top <= prclExtents->bottom; i++) + // { + // if (RECTL_bIntersectRect(&FillRect, &RectEnum.arcl[i], prclExtents)) + // { + // BOOL InY; - // y = v1->y; - // sy = v1->y + pptlDitherOrg->y; - // bt = min(v3->y + pptlDitherOrg->y, FillRect.bottom); + // DOINIT(v1, v3, 0); + // DOINIT(v1, v2, 1); + // DOINIT(v2, v3, 2); - // while(sy < bt) - // { - // InY = !(sy < FillRect.top || sy >= FillRect.bottom); - // GOLINE(v1, v3, 0); - // DOLINE(v1, v3, 0); - // ENDLINE(v1, v3, 0); + // y = v1->y; + // sy = v1->y + pptlDitherOrg->y; + // bt = min(v3->y + pptlDitherOrg->y, FillRect.bottom); - // GOLINE(v1, v2, 1); - // DOLINE(v1, v2, 1); - // FILLLINE(0, 1); - // ENDLINE(v1, v2, 1); + // while (sy < bt) + // { + // InY = !(sy < FillRect.top || sy >= FillRect.bottom); + // GOLINE(v1, v3, 0); + // DOLINE(v1, v3, 0); + // ENDLINE(v1, v3, 0); - // GOLINE(v2, v3, 2); - // DOLINE(v2, v3, 2); - // FILLLINE(0, 2); - // ENDLINE(23, v3, 2); + // GOLINE(v1, v2, 1); + // DOLINE(v1, v2, 1); + // FILLLINE(0, 1); + // ENDLINE(v1, v2, 1); - // y++; - // sy++; - // } - // } - // } - // } while(EnumMore); + // GOLINE(v2, v3, 2); + // DOLINE(v2, v3, 2); + // FILLLINE(0, 2); + // ENDLINE(23, v3, 2); - // return IntEngLeave(&EnterLeave); - //} + // y++; + // sy++; + // } + // } + // } + // } while (EnumMore); - ///* fill triangle with one solid color */ + // return IntEngLeave(&EnterLeave); + //} - //Color = XLATEOBJ_iXlate(pxlo, RGB(v1->Red >> 8, v1->Green >> 8, v1->Blue >> 8)); - //CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0); - //do - //{ - // EnumMore = CLIPOBJ_bEnum(pco, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum); - // for (i = 0; i < RectEnum.c && RectEnum.arcl[i].top <= prclExtents->bottom; i++) - // { - // if(RECTL_bIntersectRect(&FillRect, &RectEnum.arcl[i], prclExtents)) - // { - // S_INITLINE(v1, v3, 0); - // S_INITLINE(v1, v2, 1); - // S_INITLINE(v2, v3, 2); + ///* fill triangle with one solid color */ - // y = v1->y; - // sy = v1->y + pptlDitherOrg->y; - // bt = min(v3->y + pptlDitherOrg->y, FillRect.bottom); + //Color = XLATEOBJ_iXlate(pxlo, RGB(v1->Red >> 8, v1->Green >> 8, v1->Blue >> 8)); + //CLIPOBJ_cEnumStart(pco, FALSE, CT_RECTANGLES, CD_RIGHTDOWN, 0); + //do + //{ + // EnumMore = CLIPOBJ_bEnum(pco, (ULONG) sizeof(RectEnum), (PVOID) &RectEnum); + // for (i = 0; i < RectEnum.c && RectEnum.arcl[i].top <= prclExtents->bottom; i++) + // { + // if (RECTL_bIntersectRect(&FillRect, &RectEnum.arcl[i], prclExtents)) + // { + // S_INITLINE(v1, v3, 0); + // S_INITLINE(v1, v2, 1); + // S_INITLINE(v2, v3, 2); - // while(sy < bt) - // { - // S_GOLINE(v1, v3, 0); - // S_DOLINE(v1, v3, 0); - // S_ENDLINE(v1, v3, 0); + // y = v1->y; + // sy = v1->y + pptlDitherOrg->y; + // bt = min(v3->y + pptlDitherOrg->y, FillRect.bottom); - // S_GOLINE(v1, v2, 1); - // S_DOLINE(v1, v2, 1); - // S_FILLLINE(0, 1); - // S_ENDLINE(v1, v2, 1); + // while (sy < bt) + // { + // S_GOLINE(v1, v3, 0); + // S_DOLINE(v1, v3, 0); + // S_ENDLINE(v1, v3, 0); - // S_GOLINE(v2, v3, 2); - // S_DOLINE(v2, v3, 2); - // S_FILLLINE(0, 2); - // S_ENDLINE(23, v3, 2); + // S_GOLINE(v1, v2, 1); + // S_DOLINE(v1, v2, 1); + // S_FILLLINE(0, 1); + // S_ENDLINE(v1, v2, 1); - // y++; - // sy++; - // } - // } - // } - //} while(EnumMore); + // S_GOLINE(v2, v3, 2); + // S_DOLINE(v2, v3, 2); + // S_FILLLINE(0, 2); + // S_ENDLINE(23, v3, 2); - return IntEngLeave(&EnterLeave); + // y++; + // sy++; + // } + // } + // } + //} while (EnumMore); + + return IntEngLeave(&EnterLeave); } -static BOOL +static +BOOL IntEngIsNULLTriangle(TRIVERTEX *pVertex, GRADIENT_TRIANGLE *gt) { - if(COMPAREVERTEX(VERTEX(Vertex1), VERTEX(Vertex2))) - return TRUE; - if(COMPAREVERTEX(VERTEX(Vertex1), VERTEX(Vertex3))) - return TRUE; - if(COMPAREVERTEX(VERTEX(Vertex2), VERTEX(Vertex3))) - return TRUE; - return FALSE; + if(COMPAREVERTEX(VERTEX(Vertex1), VERTEX(Vertex2))) + return TRUE; + if(COMPAREVERTEX(VERTEX(Vertex1), VERTEX(Vertex3))) + return TRUE; + if(COMPAREVERTEX(VERTEX(Vertex2), VERTEX(Vertex3))) + return TRUE; + return FALSE; } -BOOL APIENTRY +BOOL +APIENTRY EngGradientFill( _Inout_ SURFOBJ *psoDest, _In_ CLIPOBJ *pco, @@ -454,90 +484,117 @@ EngGradientFill( _In_ POINTL *pptlDitherOrg, _In_ ULONG ulMode) { - ULONG i; - BOOL ret = FALSE; + ULONG i; + BOOL ret = FALSE; - if (!pco) - { - pco = IntEngCreateClipRegion(0, 0, prclExtents); - if (!pco) + /* Check for NULL clip object */ + if (pco == NULL) { - return FALSE; + /* Use the trivial one instead */ + pco = &gxcoTrivial.ClipObj; } - } - switch(ulMode) - { - case GRADIENT_FILL_RECT_H: - case GRADIENT_FILL_RECT_V: + switch(ulMode) { - PGRADIENT_RECT gr = (PGRADIENT_RECT)pMesh; - for(i = 0; i < nMesh; i++, gr++) - { - if(!IntEngGradientFillRect(psoDest, pco, pxlo, pVertex, nVertex, gr, prclExtents, - pptlDitherOrg, (ulMode == GRADIENT_FILL_RECT_H))) + case GRADIENT_FILL_RECT_H: + case GRADIENT_FILL_RECT_V: { - break; + PGRADIENT_RECT gr = (PGRADIENT_RECT)pMesh; + for (i = 0; i < nMesh; i++, gr++) + { + if (!IntEngGradientFillRect(psoDest, + pco, + pxlo, + pVertex, + nVertex, + gr, + prclExtents, + pptlDitherOrg, + (ulMode == GRADIENT_FILL_RECT_H))) + { + break; + } + } + ret = TRUE; + break; + } + case GRADIENT_FILL_TRIANGLE: + { + PGRADIENT_TRIANGLE gt = (PGRADIENT_TRIANGLE)pMesh; + for (i = 0; i < nMesh; i++, gt++) + { + if (IntEngIsNULLTriangle(pVertex, gt)) + { + /* skip empty triangles */ + continue; + } + if (!IntEngGradientFillTriangle(psoDest, + pco, + pxlo, + pVertex, + nVertex, + gt, + prclExtents, + pptlDitherOrg)) + { + break; + } + } + ret = TRUE; + break; } - } - ret = TRUE; - break; } - case GRADIENT_FILL_TRIANGLE: - { - PGRADIENT_TRIANGLE gt = (PGRADIENT_TRIANGLE)pMesh; - for(i = 0; i < nMesh; i++, gt++) - { - if(IntEngIsNULLTriangle(pVertex, gt)) - { - /* skip empty triangles */ - continue; - } - if(!IntEngGradientFillTriangle(psoDest, pco, pxlo, pVertex, nVertex, gt, prclExtents, - pptlDitherOrg)) - { - break; - } - } - ret = TRUE; - break; - } - } - return ret; + return ret; } -BOOL APIENTRY +BOOL +APIENTRY IntEngGradientFill( - IN SURFOBJ *psoDest, - IN CLIPOBJ *pco, - IN XLATEOBJ *pxlo, - IN TRIVERTEX *pVertex, - IN ULONG nVertex, - IN PVOID pMesh, - IN ULONG nMesh, - IN RECTL *prclExtents, - IN POINTL *pptlDitherOrg, - IN ULONG ulMode) + IN SURFOBJ *psoDest, + IN CLIPOBJ *pco, + IN XLATEOBJ *pxlo, + IN TRIVERTEX *pVertex, + IN ULONG nVertex, + IN PVOID pMesh, + IN ULONG nMesh, + IN RECTL *prclExtents, + IN POINTL *pptlDitherOrg, + IN ULONG ulMode) { - BOOL Ret; - SURFACE *psurf; - ASSERT(psoDest); + BOOL Ret; + SURFACE *psurf; + ASSERT(psoDest); - psurf = CONTAINING_RECORD(psoDest, SURFACE, SurfObj); - ASSERT(psurf); + psurf = CONTAINING_RECORD(psoDest, SURFACE, SurfObj); + ASSERT(psurf); - if(psurf->flags & HOOK_GRADIENTFILL) - { - Ret = GDIDEVFUNCS(psoDest).GradientFill( - psoDest, pco, pxlo, pVertex, nVertex, pMesh, nMesh, - prclExtents, pptlDitherOrg, ulMode); - } - else - { - Ret = EngGradientFill(psoDest, pco, pxlo, pVertex, nVertex, pMesh, nMesh, prclExtents, - pptlDitherOrg, ulMode); - } + if (psurf->flags & HOOK_GRADIENTFILL) + { + Ret = GDIDEVFUNCS(psoDest).GradientFill(psoDest, + pco, + pxlo, + pVertex, + nVertex, + pMesh, + nMesh, + prclExtents, + pptlDitherOrg, + ulMode); + } + else + { + Ret = EngGradientFill(psoDest, + pco, + pxlo, + pVertex, + nVertex, + pMesh, + nMesh, + prclExtents, + pptlDitherOrg, + ulMode); + } - return Ret; + return Ret; } diff --git a/win32ss/gdi/eng/pdevobj.c b/win32ss/gdi/eng/pdevobj.c index a2feddc8897..4d90b0ac5f9 100644 --- a/win32ss/gdi/eng/pdevobj.c +++ b/win32ss/gdi/eng/pdevobj.c @@ -360,8 +360,8 @@ EngpCreatePDEV( return ppdev; } -VOID FORCEINLINE +VOID SwitchPointer( _Inout_ PVOID pvPointer1, _Inout_ PVOID pvPointer2) diff --git a/win32ss/gdi/eng/perfcnt.c b/win32ss/gdi/eng/perfcnt.c index b8fb9790181..ddcd7bb6d66 100644 --- a/win32ss/gdi/eng/perfcnt.c +++ b/win32ss/gdi/eng/perfcnt.c @@ -1,4 +1,4 @@ -/* +/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * PURPOSE: GDI Driver Performance Counter Functions @@ -17,10 +17,10 @@ VOID APIENTRY EngQueryPerformanceFrequency(LONGLONG *Frequency) { - LARGE_INTEGER Freq; + LARGE_INTEGER Freq; - KeQueryPerformanceCounter(&Freq); - *Frequency = Freq.QuadPart; + KeQueryPerformanceCounter(&Freq); + *Frequency = Freq.QuadPart; } /* @@ -29,8 +29,8 @@ EngQueryPerformanceFrequency(LONGLONG *Frequency) VOID APIENTRY EngQueryPerformanceCounter(LONGLONG *Count) { - LARGE_INTEGER PerfCount; + LARGE_INTEGER PerfCount; - PerfCount = KeQueryPerformanceCounter(NULL); - *Count = PerfCount.QuadPart; + PerfCount = KeQueryPerformanceCounter(NULL); + *Count = PerfCount.QuadPart; } diff --git a/win32ss/gdi/eng/semaphor.c b/win32ss/gdi/eng/semaphor.c index cb15505f1bc..9e1696566ee 100644 --- a/win32ss/gdi/eng/semaphor.c +++ b/win32ss/gdi/eng/semaphor.c @@ -8,26 +8,28 @@ */ HSEMAPHORE APIENTRY -EngCreateSemaphore ( VOID ) +EngCreateSemaphore(VOID) { - // www.osr.com/ddk/graphics/gdifncs_95lz.htm - PERESOURCE psem = ExAllocatePoolWithTag( NonPagedPool, sizeof(ERESOURCE), GDITAG_SEMAPHORE ); - if ( !psem ) - return NULL; - if ( !NT_SUCCESS(ExInitializeResourceLite ( psem )) ) - { - ExFreePoolWithTag ( psem, GDITAG_SEMAPHORE ); - return NULL; - } - return (HSEMAPHORE)psem; + // www.osr.com/ddk/graphics/gdifncs_95lz.htm + PERESOURCE psem = ExAllocatePoolWithTag(NonPagedPool, sizeof(ERESOURCE), GDITAG_SEMAPHORE); + if (!psem) + return NULL; + + if (!NT_SUCCESS(ExInitializeResourceLite(psem))) + { + ExFreePoolWithTag ( psem, GDITAG_SEMAPHORE ); + return NULL; + } + + return (HSEMAPHORE)psem; } VOID FASTCALL -IntGdiAcquireSemaphore ( HSEMAPHORE hsem ) +IntGdiAcquireSemaphore(HSEMAPHORE hsem) { - KeEnterCriticalRegion(); - ExAcquireResourceExclusiveLite ( (PERESOURCE)hsem, TRUE ); + KeEnterCriticalRegion(); + ExAcquireResourceExclusiveLite ((PERESOURCE)hsem, TRUE); } /* @@ -35,14 +37,14 @@ IntGdiAcquireSemaphore ( HSEMAPHORE hsem ) */ VOID APIENTRY -EngAcquireSemaphore ( IN HSEMAPHORE hsem ) +EngAcquireSemaphore(IN HSEMAPHORE hsem) { - // www.osr.com/ddk/graphics/gdifncs_14br.htm - PTHREADINFO W32Thread; - ASSERT(hsem); - IntGdiAcquireSemaphore ( hsem ); - W32Thread = PsGetThreadWin32Thread(PsGetCurrentThread()); - if (W32Thread) W32Thread->dwEngAcquireCount++; + // www.osr.com/ddk/graphics/gdifncs_14br.htm + PTHREADINFO W32Thread; + ASSERT(hsem); + IntGdiAcquireSemaphore(hsem); + W32Thread = PsGetThreadWin32Thread(PsGetCurrentThread()); + if (W32Thread) W32Thread->dwEngAcquireCount++; } @@ -50,8 +52,8 @@ VOID FASTCALL IntGdiReleaseSemaphore ( HSEMAPHORE hsem ) { - ExReleaseResourceLite ( (PERESOURCE)hsem ); - KeLeaveCriticalRegion(); + ExReleaseResourceLite((PERESOURCE)hsem); + KeLeaveCriticalRegion(); } /* @@ -61,12 +63,12 @@ VOID APIENTRY EngReleaseSemaphore ( IN HSEMAPHORE hsem ) { - // www.osr.com/ddk/graphics/gdifncs_5u3r.htm - PTHREADINFO W32Thread; - ASSERT(hsem); - W32Thread = PsGetThreadWin32Thread(PsGetCurrentThread()); - if (W32Thread) --W32Thread->dwEngAcquireCount; - IntGdiReleaseSemaphore ( hsem ); + // www.osr.com/ddk/graphics/gdifncs_5u3r.htm + PTHREADINFO W32Thread; + ASSERT(hsem); + W32Thread = PsGetThreadWin32Thread(PsGetCurrentThread()); + if (W32Thread) --W32Thread->dwEngAcquireCount; + IntGdiReleaseSemaphore(hsem); } VOID @@ -89,12 +91,11 @@ VOID APIENTRY EngDeleteSemaphore ( IN HSEMAPHORE hsem ) { - // www.osr.com/ddk/graphics/gdifncs_13c7.htm - ASSERT ( hsem ); + // www.osr.com/ddk/graphics/gdifncs_13c7.htm + ASSERT(hsem); - ExDeleteResourceLite((PERESOURCE)hsem); - - ExFreePoolWithTag( (PVOID)hsem, GDITAG_SEMAPHORE); + ExDeleteResourceLite((PERESOURCE)hsem); + ExFreePoolWithTag((PVOID)hsem, GDITAG_SEMAPHORE); } /* @@ -104,9 +105,9 @@ BOOL APIENTRY EngIsSemaphoreOwned ( IN HSEMAPHORE hsem ) { - // www.osr.com/ddk/graphics/gdifncs_6wmf.htm - ASSERT(hsem); - return (((PERESOURCE)hsem)->ActiveCount > 0); + // www.osr.com/ddk/graphics/gdifncs_6wmf.htm + ASSERT(hsem); + return (((PERESOURCE)hsem)->ActiveCount > 0); } /* @@ -116,9 +117,9 @@ BOOL APIENTRY EngIsSemaphoreOwnedByCurrentThread ( IN HSEMAPHORE hsem ) { - // www.osr.com/ddk/graphics/gdifncs_9yxz.htm - ASSERT(hsem); - return ExIsResourceAcquiredExclusiveLite ( (PERESOURCE)hsem ); + // www.osr.com/ddk/graphics/gdifncs_9yxz.htm + ASSERT(hsem); + return ExIsResourceAcquiredExclusiveLite((PERESOURCE)hsem); } /* @@ -126,32 +127,32 @@ EngIsSemaphoreOwnedByCurrentThread ( IN HSEMAPHORE hsem ) */ BOOL APIENTRY EngInitializeSafeSemaphore( - OUT ENGSAFESEMAPHORE *Semaphore) + OUT ENGSAFESEMAPHORE *Semaphore) { - HSEMAPHORE hSem; + HSEMAPHORE hSem; - if (InterlockedIncrement(&Semaphore->lCount) == 1) - { - /* Create the semaphore */ - hSem = EngCreateSemaphore(); - if (hSem == 0) - { - InterlockedDecrement(&Semaphore->lCount); - return FALSE; - } - /* FIXME: Not thread-safe! Check result of InterlockedCompareExchangePointer - and delete semaphore if already initialized! */ - (void)InterlockedExchangePointer((volatile PVOID *)&Semaphore->hsem, hSem); - } - else - { - /* Wait for the other thread to create the semaphore */ - ASSERT(Semaphore->lCount > 1); - ASSERT_IRQL_LESS_OR_EQUAL(PASSIVE_LEVEL); - while (Semaphore->hsem == NULL); - } + if (InterlockedIncrement(&Semaphore->lCount) == 1) + { + /* Create the semaphore */ + hSem = EngCreateSemaphore(); + if (hSem == 0) + { + InterlockedDecrement(&Semaphore->lCount); + return FALSE; + } + /* FIXME: Not thread-safe! Check result of InterlockedCompareExchangePointer + and delete semaphore if already initialized! */ + (void)InterlockedExchangePointer((volatile PVOID *)&Semaphore->hsem, hSem); + } + else + { + /* Wait for the other thread to create the semaphore */ + ASSERT(Semaphore->lCount > 1); + ASSERT_IRQL_LESS_OR_EQUAL(PASSIVE_LEVEL); + while (Semaphore->hsem == NULL); + } - return TRUE; + return TRUE; } /* @@ -159,14 +160,14 @@ EngInitializeSafeSemaphore( */ VOID APIENTRY EngDeleteSafeSemaphore( - IN OUT ENGSAFESEMAPHORE *Semaphore) + IN OUT ENGSAFESEMAPHORE *Semaphore) { - if (InterlockedDecrement(&Semaphore->lCount) == 0) - { - /* FIXME: Not thread-safe! Use result of InterlockedCompareExchangePointer! */ - EngDeleteSemaphore(Semaphore->hsem); - (void)InterlockedExchangePointer((volatile PVOID *)&Semaphore->hsem, NULL); - } + if (InterlockedDecrement(&Semaphore->lCount) == 0) + { + /* FIXME: Not thread-safe! Use result of InterlockedCompareExchangePointer! */ + EngDeleteSemaphore(Semaphore->hsem); + (void)InterlockedExchangePointer((volatile PVOID *)&Semaphore->hsem, NULL); + } } /* EOF */ diff --git a/win32ss/gdi/eng/sort.c b/win32ss/gdi/eng/sort.c index 96c629f2060..b1e25443012 100644 --- a/win32ss/gdi/eng/sort.c +++ b/win32ss/gdi/eng/sort.c @@ -1,7 +1,7 @@ /* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS win32 subsystem - * PURPOSE: + * PURPOSE: * FILE: subsystems/win32k/eng/sort.c * PROGRAMER: ReactOS Team */ @@ -14,10 +14,11 @@ /* * @implemented */ -void APIENTRY +void +APIENTRY EngSort(IN OUT PBYTE Buf, IN ULONG ElemSize, IN ULONG ElemCount, IN SORTCOMP CompFunc) { - qsort(Buf, ElemCount, ElemSize, CompFunc); + qsort(Buf, ElemCount, ElemSize, CompFunc); } /* EOF */ diff --git a/win32ss/gdi/eng/string.c b/win32ss/gdi/eng/string.c index 14cbc5be3bf..3094af35ea4 100644 --- a/win32ss/gdi/eng/string.c +++ b/win32ss/gdi/eng/string.c @@ -8,82 +8,87 @@ BOOL APIENTRY STROBJ_bEnum( - IN STROBJ *pstro, - OUT ULONG *pc, - OUT PGLYPHPOS *ppgpos - ) + IN STROBJ *pstro, + OUT ULONG *pc, + OUT PGLYPHPOS *ppgpos) { - // www.osr.com/ddk/graphics/gdifncs_65uv.htm - UNIMPLEMENTED; - return FALSE; + // www.osr.com/ddk/graphics/gdifncs_65uv.htm + UNIMPLEMENTED; + return FALSE; } DWORD APIENTRY -STROBJ_dwGetCodePage ( IN STROBJ *pstro ) +STROBJ_dwGetCodePage( + IN STROBJ *pstro) { - // www.osr.com/ddk/graphics/gdifncs_9jmv.htm - PSTRGDI pStrGdi = (PSTRGDI) pstro; - return pStrGdi->dwCodePage; + // www.osr.com/ddk/graphics/gdifncs_9jmv.htm + PSTRGDI pStrGdi = (PSTRGDI) pstro; + return pStrGdi->dwCodePage; } VOID APIENTRY -STROBJ_vEnumStart ( IN STROBJ *pstro ) +STROBJ_vEnumStart( + IN STROBJ *pstro) { - // www.osr.com/ddk/graphics/gdifncs_32uf.htm - UNIMPLEMENTED; + // www.osr.com/ddk/graphics/gdifncs_32uf.htm + UNIMPLEMENTED; } /* * @unimplemented */ -BOOL APIENTRY +BOOL +APIENTRY STROBJ_bEnumPositionsOnly( - IN STROBJ *StringObj, - OUT ULONG *Count, - OUT PGLYPHPOS *Pos) + IN STROBJ *StringObj, + OUT ULONG *Count, + OUT PGLYPHPOS *Pos) { - UNIMPLEMENTED; - return (BOOL) DDI_ERROR; + UNIMPLEMENTED; + return (BOOL) DDI_ERROR; } /* * @unimplemented */ -BOOL APIENTRY +BOOL +APIENTRY STROBJ_bGetAdvanceWidths( - IN STROBJ *StringObj, - IN ULONG First, - IN ULONG Count, - OUT POINTQF *Widths) + IN STROBJ *StringObj, + IN ULONG First, + IN ULONG Count, + OUT POINTQF *Widths) { - UNIMPLEMENTED; - return FALSE; + UNIMPLEMENTED; + return FALSE; } /* * @implemented */ -FIX APIENTRY +FIX +APIENTRY STROBJ_fxBreakExtra( - IN STROBJ *StringObj) + IN STROBJ *StringObj) { - PSTRGDI pStrGdi = (PSTRGDI) StringObj; - if (pStrGdi->StrObj.flAccel & SO_BREAK_EXTRA) return pStrGdi->fxBreakExtra; - return (FIX) 0; + PSTRGDI pStrGdi = (PSTRGDI) StringObj; + if (pStrGdi->StrObj.flAccel & SO_BREAK_EXTRA) return pStrGdi->fxBreakExtra; + return (FIX) 0; } /* * @implemented */ -FIX APIENTRY +FIX +APIENTRY STROBJ_fxCharacterExtra( - IN STROBJ *StringObj) + IN STROBJ *StringObj) { - PSTRGDI pStrGdi = (PSTRGDI) StringObj; - if (pStrGdi->StrObj.flAccel & SO_CHARACTER_EXTRA) return pStrGdi->fxExtra; - return (FIX) 0; + PSTRGDI pStrGdi = (PSTRGDI) StringObj; + if (pStrGdi->StrObj.flAccel & SO_CHARACTER_EXTRA) return pStrGdi->fxExtra; + return (FIX)0; } /* EOF */ diff --git a/win32ss/gdi/eng/stubs.c b/win32ss/gdi/eng/stubs.c index 24a61135ada..1157e792419 100644 --- a/win32ss/gdi/eng/stubs.c +++ b/win32ss/gdi/eng/stubs.c @@ -8,28 +8,26 @@ #define UNIMPLEMENTED DbgPrint("(%s:%i) WIN32K: %s UNIMPLEMENTED\n", __FILE__, __LINE__, __FUNCTION__ ) - /* * @unimplemented */ BOOL APIENTRY -EngTextOut ( - SURFOBJ *pso, - STROBJ *pstro, - FONTOBJ *pfo, - CLIPOBJ *pco, - RECTL *prclExtra, - RECTL *prclOpaque, - BRUSHOBJ *pboFore, - BRUSHOBJ *pboOpaque, - POINTL *pptlOrg, - MIX mix - ) +EngTextOut( + SURFOBJ *pso, + STROBJ *pstro, + FONTOBJ *pfo, + CLIPOBJ *pco, + RECTL *prclExtra, + RECTL *prclOpaque, + BRUSHOBJ *pboFore, + BRUSHOBJ *pboOpaque, + POINTL *pptlOrg, + MIX mix) { - // www.osr.com/ddk/graphics/gdifncs_4tgn.htm - UNIMPLEMENTED; - return FALSE; + // www.osr.com/ddk/graphics/gdifncs_4tgn.htm + UNIMPLEMENTED; + return FALSE; } /* @@ -37,11 +35,11 @@ EngTextOut ( */ PATHOBJ* APIENTRY -CLIPOBJ_ppoGetPath ( IN CLIPOBJ *pco ) +CLIPOBJ_ppoGetPath(IN CLIPOBJ *pco) { - // www.osr.com/ddk/graphics/gdifncs_6hbb.htm - UNIMPLEMENTED; - return 0; + // www.osr.com/ddk/graphics/gdifncs_6hbb.htm + UNIMPLEMENTED; + return 0; } /* @@ -49,11 +47,11 @@ CLIPOBJ_ppoGetPath ( IN CLIPOBJ *pco ) */ BOOL APIENTRY -EngCheckAbort ( IN SURFOBJ *pso ) +EngCheckAbort(IN SURFOBJ *pso) { - // www.osr.com/ddk/graphics/gdifncs_3u7b.htm - UNIMPLEMENTED; - return FALSE; + // www.osr.com/ddk/graphics/gdifncs_3u7b.htm + UNIMPLEMENTED; + return FALSE; } /* @@ -62,14 +60,13 @@ EngCheckAbort ( IN SURFOBJ *pso ) FD_GLYPHSET* APIENTRY EngComputeGlyphSet( - IN INT nCodePage, - IN INT nFirstChar, - IN INT cChars - ) + IN INT nCodePage, + IN INT nFirstChar, + IN INT cChars) { - // www.osr.com/ddk/graphics/gdifncs_9607.htm - UNIMPLEMENTED; - return NULL; + // www.osr.com/ddk/graphics/gdifncs_9607.htm + UNIMPLEMENTED; + return NULL; } /* @@ -77,11 +74,11 @@ EngComputeGlyphSet( */ PATHOBJ* APIENTRY -EngCreatePath ( VOID ) +EngCreatePath(VOID) { - // www.osr.com/ddk/graphics/gdifncs_4aav.htm - UNIMPLEMENTED; - return NULL; + // www.osr.com/ddk/graphics/gdifncs_4aav.htm + UNIMPLEMENTED; + return NULL; } /* @@ -89,10 +86,10 @@ EngCreatePath ( VOID ) */ VOID APIENTRY -EngDeletePath ( IN PATHOBJ *ppo ) +EngDeletePath(IN PATHOBJ *ppo) { - // www.osr.com/ddk/graphics/gdifncs_3fl3.htm - UNIMPLEMENTED; + // www.osr.com/ddk/graphics/gdifncs_3fl3.htm + UNIMPLEMENTED; } /* @@ -100,18 +97,17 @@ EngDeletePath ( IN PATHOBJ *ppo ) */ BOOL APIENTRY -EngEnumForms ( - IN HANDLE hPrinter, - IN DWORD Level, - OUT LPBYTE pForm, - IN DWORD cbBuf, - OUT LPDWORD pcbNeeded, - OUT LPDWORD pcReturned - ) +EngEnumForms( + IN HANDLE hPrinter, + IN DWORD Level, + OUT LPBYTE pForm, + IN DWORD cbBuf, + OUT LPDWORD pcbNeeded, + OUT LPDWORD pcReturned) { - // www.osr.com/ddk/graphics/gdifncs_5e07.htm - UNIMPLEMENTED; - return FALSE; + // www.osr.com/ddk/graphics/gdifncs_5e07.htm + UNIMPLEMENTED; + return FALSE; } /* @@ -119,19 +115,18 @@ EngEnumForms ( */ BOOL APIENTRY -EngFillPath ( - IN SURFOBJ *pso, - IN PATHOBJ *ppo, - IN CLIPOBJ *pco, - IN BRUSHOBJ *pbo, - IN POINTL *pptlBrushOrg, - IN MIX mix, - IN FLONG flOptions - ) +EngFillPath( + IN SURFOBJ *pso, + IN PATHOBJ *ppo, + IN CLIPOBJ *pco, + IN BRUSHOBJ *pbo, + IN POINTL *pptlBrushOrg, + IN MIX mix, + IN FLONG flOptions) { - // www.osr.com/ddk/graphics/gdifncs_9pyf.htm - UNIMPLEMENTED; - return FALSE; + // www.osr.com/ddk/graphics/gdifncs_9pyf.htm + UNIMPLEMENTED; + return FALSE; } /* @@ -140,15 +135,14 @@ EngFillPath ( PVOID APIENTRY EngFindResource( - IN HANDLE h, - IN int iName, - IN int iType, - OUT PULONG pulSize - ) + IN HANDLE h, + IN int iName, + IN int iType, + OUT PULONG pulSize) { - // www.osr.com/ddk/graphics/gdifncs_7rjb.htm - UNIMPLEMENTED; - return NULL; + // www.osr.com/ddk/graphics/gdifncs_7rjb.htm + UNIMPLEMENTED; + return NULL; } /* @@ -157,13 +151,12 @@ EngFindResource( BOOL APIENTRY EngGetFileChangeTime( - IN HANDLE h, - OUT LARGE_INTEGER *pChangeTime - ) + IN HANDLE h, + OUT LARGE_INTEGER *pChangeTime) { - // www.osr.com/ddk/graphics/gdifncs_1i1z.htm - UNIMPLEMENTED; - return FALSE; + // www.osr.com/ddk/graphics/gdifncs_1i1z.htm + UNIMPLEMENTED; + return FALSE; } /* @@ -172,13 +165,12 @@ EngGetFileChangeTime( BOOL APIENTRY EngGetFilePath( - IN HANDLE h, - OUT WCHAR (*pDest)[MAX_PATH+1] - ) + IN HANDLE h, + OUT WCHAR (*pDest)[MAX_PATH + 1]) { - // www.osr.com/ddk/graphics/gdifncs_5g2v.htm - UNIMPLEMENTED; - return FALSE; + // www.osr.com/ddk/graphics/gdifncs_5g2v.htm + UNIMPLEMENTED; + return FALSE; } /* @@ -187,17 +179,16 @@ EngGetFilePath( BOOL APIENTRY EngGetForm( - IN HANDLE hPrinter, - IN LPWSTR pFormName, - IN DWORD Level, - OUT LPBYTE pForm, - IN DWORD cbBuf, - OUT LPDWORD pcbNeeded - ) + IN HANDLE hPrinter, + IN LPWSTR pFormName, + IN DWORD Level, + OUT LPBYTE pForm, + IN DWORD cbBuf, + OUT LPDWORD pcbNeeded) { - // www.osr.com/ddk/graphics/gdifncs_5vvr.htm - UNIMPLEMENTED; - return FALSE; + // www.osr.com/ddk/graphics/gdifncs_5vvr.htm + UNIMPLEMENTED; + return FALSE; } /* @@ -206,16 +197,15 @@ EngGetForm( BOOL APIENTRY EngGetPrinter( - IN HANDLE hPrinter, - IN DWORD dwLevel, - OUT LPBYTE pPrinter, - IN DWORD cbBuf, - OUT LPDWORD pcbNeeded - ) + IN HANDLE hPrinter, + IN DWORD dwLevel, + OUT LPBYTE pPrinter, + IN DWORD cbBuf, + OUT LPDWORD pcbNeeded) { - // www.osr.com/ddk/graphics/gdifncs_50h3.htm - UNIMPLEMENTED; - return FALSE; + // www.osr.com/ddk/graphics/gdifncs_50h3.htm + UNIMPLEMENTED; + return FALSE; } /* @@ -224,17 +214,16 @@ EngGetPrinter( DWORD APIENTRY EngGetPrinterData( - IN HANDLE hPrinter, - IN LPWSTR pValueName, - OUT LPDWORD pType, - OUT LPBYTE pData, - IN DWORD nSize, - OUT LPDWORD pcbNeeded - ) + IN HANDLE hPrinter, + IN LPWSTR pValueName, + OUT LPDWORD pType, + OUT LPBYTE pData, + IN DWORD nSize, + OUT LPDWORD pcbNeeded) { - // www.osr.com/ddk/graphics/gdifncs_8t5z.htm - UNIMPLEMENTED; - return 0; + // www.osr.com/ddk/graphics/gdifncs_8t5z.htm + UNIMPLEMENTED; + return 0; } /* @@ -242,11 +231,11 @@ EngGetPrinterData( */ LPWSTR APIENTRY -EngGetPrinterDataFileName ( IN HDEV hdev ) +EngGetPrinterDataFileName(IN HDEV hdev) { - // www.osr.com/ddk/graphics/gdifncs_2giv.htm - UNIMPLEMENTED; - return NULL; + // www.osr.com/ddk/graphics/gdifncs_2giv.htm + UNIMPLEMENTED; + return NULL; } /* @@ -255,17 +244,16 @@ EngGetPrinterDataFileName ( IN HDEV hdev ) BOOL APIENTRY EngGetType1FontList( - IN HDEV hdev, - OUT TYPE1_FONT *pType1Buffer, - IN ULONG cjType1Buffer, - OUT PULONG pulLocalFonts, - OUT PULONG pulRemoteFonts, - OUT LARGE_INTEGER *pLastModified - ) + IN HDEV hdev, + OUT TYPE1_FONT *pType1Buffer, + IN ULONG cjType1Buffer, + OUT PULONG pulLocalFonts, + OUT PULONG pulRemoteFonts, + OUT LARGE_INTEGER *pLastModified) { - // www.osr.com/ddk/graphics/gdifncs_6e5j.htm - UNIMPLEMENTED; - return FALSE; + // www.osr.com/ddk/graphics/gdifncs_6e5j.htm + UNIMPLEMENTED; + return FALSE; } /* @@ -273,130 +261,123 @@ EngGetType1FontList( */ BOOL APIENTRY -EngMarkBandingSurface ( IN HSURF hsurf ) +EngMarkBandingSurface(IN HSURF hsurf) { - // www.osr.com/ddk/graphics/gdifncs_2jon.htm - UNIMPLEMENTED; - return FALSE; + // www.osr.com/ddk/graphics/gdifncs_2jon.htm + UNIMPLEMENTED; + return FALSE; } INT APIENTRY EngMultiByteToWideChar( - IN UINT CodePage, - OUT LPWSTR WideCharString, - IN INT BytesInWideCharString, - IN LPSTR MultiByteString, - IN INT BytesInMultiByteString - ) + IN UINT CodePage, + OUT LPWSTR WideCharString, + IN INT BytesInWideCharString, + IN LPSTR MultiByteString, + IN INT BytesInMultiByteString) { - // www.osr.com/ddk/graphics/gdifncs_32cn.htm - UNIMPLEMENTED; - return 0; + // www.osr.com/ddk/graphics/gdifncs_32cn.htm + UNIMPLEMENTED; + return 0; } VOID APIENTRY -EngQueryLocalTime ( OUT PENG_TIME_FIELDS ptf ) +EngQueryLocalTime(OUT PENG_TIME_FIELDS ptf) { - // www.osr.com/ddk/graphics/gdifncs_389z.htm - UNIMPLEMENTED; + // www.osr.com/ddk/graphics/gdifncs_389z.htm + UNIMPLEMENTED; } ULONG APIENTRY EngQueryPalette( - IN HPALETTE hPal, - OUT ULONG *piMode, - IN ULONG cColors, - OUT ULONG *pulColors - ) + IN HPALETTE hPal, + OUT ULONG *piMode, + IN ULONG cColors, + OUT ULONG *pulColors) { - // www.osr.com/ddk/graphics/gdifncs_21t3.htm - UNIMPLEMENTED; - return 0; + // www.osr.com/ddk/graphics/gdifncs_21t3.htm + UNIMPLEMENTED; + return 0; } DWORD APIENTRY EngSetPrinterData( - IN HANDLE hPrinter, - IN LPWSTR pType, - IN DWORD dwType, - IN LPBYTE lpbPrinterData, - IN DWORD cjPrinterData - ) + IN HANDLE hPrinter, + IN LPWSTR pType, + IN DWORD dwType, + IN LPBYTE lpbPrinterData, + IN DWORD cjPrinterData) { - // www.osr.com/ddk/graphics/gdifncs_8drb.htm - UNIMPLEMENTED; - return 0; + // www.osr.com/ddk/graphics/gdifncs_8drb.htm + UNIMPLEMENTED; + return 0; } BOOL APIENTRY EngStrokeAndFillPath( - IN SURFOBJ *pso, - IN PATHOBJ *ppo, - IN CLIPOBJ *pco, - IN XFORMOBJ *pxo, - IN BRUSHOBJ *pboStroke, - IN LINEATTRS *plineattrs, - IN BRUSHOBJ *pboFill, - IN POINTL *pptlBrushOrg, - IN MIX mixFill, - IN FLONG flOptions - ) + IN SURFOBJ *pso, + IN PATHOBJ *ppo, + IN CLIPOBJ *pco, + IN XFORMOBJ *pxo, + IN BRUSHOBJ *pboStroke, + IN LINEATTRS *plineattrs, + IN BRUSHOBJ *pboFill, + IN POINTL *pptlBrushOrg, + IN MIX mixFill, + IN FLONG flOptions) { - // www.osr.com/ddk/graphics/gdifncs_2xwn.htm - UNIMPLEMENTED; - return FALSE; + // www.osr.com/ddk/graphics/gdifncs_2xwn.htm + UNIMPLEMENTED; + return FALSE; } BOOL APIENTRY EngStrokePath( - IN SURFOBJ *pso, - IN PATHOBJ *ppo, - IN CLIPOBJ *pco, - IN XFORMOBJ *pxo, - IN BRUSHOBJ *pbo, - IN POINTL *pptlBrushOrg, - IN LINEATTRS *plineattrs, - IN MIX mix - ) + IN SURFOBJ *pso, + IN PATHOBJ *ppo, + IN CLIPOBJ *pco, + IN XFORMOBJ *pxo, + IN BRUSHOBJ *pbo, + IN POINTL *pptlBrushOrg, + IN LINEATTRS *plineattrs, + IN MIX mix) { - // www.osr.com/ddk/graphics/gdifncs_4yaw.htm - UNIMPLEMENTED; - return FALSE; + // www.osr.com/ddk/graphics/gdifncs_4yaw.htm + UNIMPLEMENTED; + return FALSE; } INT APIENTRY EngWideCharToMultiByte( - IN UINT CodePage, - IN LPWSTR WideCharString, - IN INT BytesInWideCharString, - OUT LPSTR MultiByteString, - IN INT BytesInMultiByteString - ) + IN UINT CodePage, + IN LPWSTR WideCharString, + IN INT BytesInWideCharString, + OUT LPSTR MultiByteString, + IN INT BytesInMultiByteString) { - // www.osr.com/ddk/graphics/gdifncs_35wn.htm - UNIMPLEMENTED; - return 0; + // www.osr.com/ddk/graphics/gdifncs_35wn.htm + UNIMPLEMENTED; + return 0; } BOOL APIENTRY -EngWritePrinter ( - IN HANDLE hPrinter, - IN LPVOID pBuf, - IN DWORD cbBuf, - OUT LPDWORD pcWritten - ) +EngWritePrinter( + IN HANDLE hPrinter, + IN LPVOID pBuf, + IN DWORD cbBuf, + OUT LPDWORD pcWritten) { - // www.osr.com/ddk/graphics/gdifncs_9v6v.htm - UNIMPLEMENTED; - return FALSE; + // www.osr.com/ddk/graphics/gdifncs_9v6v.htm + UNIMPLEMENTED; + return FALSE; } /* @@ -404,13 +385,12 @@ EngWritePrinter ( */ ULONG APIENTRY -FONTOBJ_cGetAllGlyphHandles ( - IN FONTOBJ *FontObj, - IN HGLYPH *Glyphs - ) +FONTOBJ_cGetAllGlyphHandles( + IN FONTOBJ *FontObj, + IN HGLYPH *Glyphs) { - UNIMPLEMENTED; - return 0; + UNIMPLEMENTED; + return 0; } /* @@ -419,15 +399,14 @@ FONTOBJ_cGetAllGlyphHandles ( ULONG APIENTRY FONTOBJ_cGetGlyphs( - IN FONTOBJ *FontObj, - IN ULONG Mode, - IN ULONG NumGlyphs, - IN HGLYPH *GlyphHandles, - IN PVOID *OutGlyphs - ) + IN FONTOBJ *FontObj, + IN ULONG Mode, + IN ULONG NumGlyphs, + IN HGLYPH *GlyphHandles, + IN PVOID *OutGlyphs) { - UNIMPLEMENTED; - return 0; + UNIMPLEMENTED; + return 0; } /* @@ -435,10 +414,10 @@ FONTOBJ_cGetGlyphs( */ IFIMETRICS* APIENTRY -FONTOBJ_pifi ( IN FONTOBJ *FontObj ) +FONTOBJ_pifi(IN FONTOBJ *FontObj) { - UNIMPLEMENTED; - return NULL; + UNIMPLEMENTED; + return NULL; } /* @@ -446,12 +425,12 @@ FONTOBJ_pifi ( IN FONTOBJ *FontObj ) */ PVOID APIENTRY -FONTOBJ_pvTrueTypeFontFile ( - IN FONTOBJ *FontObj, - IN ULONG *FileSize) +FONTOBJ_pvTrueTypeFontFile( + IN FONTOBJ *FontObj, + IN ULONG *FileSize) { - UNIMPLEMENTED; - return NULL; + UNIMPLEMENTED; + return NULL; } /* @@ -459,10 +438,10 @@ FONTOBJ_pvTrueTypeFontFile ( */ XFORMOBJ* APIENTRY -FONTOBJ_pxoGetXform ( IN FONTOBJ *FontObj ) +FONTOBJ_pxoGetXform(IN FONTOBJ *FontObj) { - UNIMPLEMENTED; - return NULL; + UNIMPLEMENTED; + return NULL; } /* @@ -470,157 +449,149 @@ FONTOBJ_pxoGetXform ( IN FONTOBJ *FontObj ) */ VOID APIENTRY -FONTOBJ_vGetInfo ( - IN FONTOBJ *FontObj, - IN ULONG InfoSize, - OUT PFONTINFO FontInfo) +FONTOBJ_vGetInfo( + IN FONTOBJ *FontObj, + IN ULONG InfoSize, + OUT PFONTINFO FontInfo) { - UNIMPLEMENTED; + UNIMPLEMENTED; } LONG APIENTRY HT_ComputeRGBGammaTable( - IN USHORT GammaTableEntries, - IN USHORT GammaTableType, - IN USHORT RedGamma, - IN USHORT GreenGamma, - IN USHORT BlueGamma, - OUT LPBYTE pGammaTable - ) + IN USHORT GammaTableEntries, + IN USHORT GammaTableType, + IN USHORT RedGamma, + IN USHORT GreenGamma, + IN USHORT BlueGamma, + OUT LPBYTE pGammaTable) { - // www.osr.com/ddk/graphics/gdifncs_9dpj.htm - UNIMPLEMENTED; - return 0; + // www.osr.com/ddk/graphics/gdifncs_9dpj.htm + UNIMPLEMENTED; + return 0; } LONG APIENTRY HT_Get8BPPFormatPalette( - OUT LPPALETTEENTRY pPaletteEntry, - IN USHORT RedGamma, - IN USHORT GreenGamma, - IN USHORT BlueGamma - ) + OUT LPPALETTEENTRY pPaletteEntry, + IN USHORT RedGamma, + IN USHORT GreenGamma, + IN USHORT BlueGamma) { - // www.osr.com/ddk/graphics/gdifncs_8kvb.htm - UNIMPLEMENTED; - return 0; + // www.osr.com/ddk/graphics/gdifncs_8kvb.htm + UNIMPLEMENTED; + return 0; } BOOL APIENTRY -PATHOBJ_bCloseFigure ( IN PATHOBJ *ppo ) +PATHOBJ_bCloseFigure(IN PATHOBJ *ppo) { - // www.osr.com/ddk/graphics/gdifncs_5mhz.htm - UNIMPLEMENTED; - return FALSE; + // www.osr.com/ddk/graphics/gdifncs_5mhz.htm + UNIMPLEMENTED; + return FALSE; } BOOL APIENTRY -PATHOBJ_bEnum ( - IN PATHOBJ *ppo, - OUT PATHDATA *ppd - ) +PATHOBJ_bEnum( + IN PATHOBJ *ppo, + OUT PATHDATA *ppd) { - // www.osr.com/ddk/graphics/gdifncs_98o7.htm - UNIMPLEMENTED; - return FALSE; + // www.osr.com/ddk/graphics/gdifncs_98o7.htm + UNIMPLEMENTED; + return FALSE; } BOOL APIENTRY PATHOBJ_bEnumClipLines( - IN PATHOBJ *ppo, - IN ULONG cb, - OUT CLIPLINE *pcl - ) + IN PATHOBJ *ppo, + IN ULONG cb, + OUT CLIPLINE *pcl) { - // www.osr.com/ddk/graphics/gdifncs_4147.htm - UNIMPLEMENTED; - return FALSE; + // www.osr.com/ddk/graphics/gdifncs_4147.htm + UNIMPLEMENTED; + return FALSE; } BOOL APIENTRY PATHOBJ_bMoveTo( - IN PATHOBJ *ppo, - IN POINTFIX ptfx - ) + IN PATHOBJ *ppo, + IN POINTFIX ptfx) { - // www.osr.com/ddk/graphics/gdifncs_70vb.htm - UNIMPLEMENTED; - return FALSE; + // www.osr.com/ddk/graphics/gdifncs_70vb.htm + UNIMPLEMENTED; + return FALSE; } BOOL APIENTRY PATHOBJ_bPolyBezierTo( - IN PATHOBJ *ppo, - IN POINTFIX *pptfx, - IN ULONG cptfx - ) + IN PATHOBJ *ppo, + IN POINTFIX *pptfx, + IN ULONG cptfx) { - // www.osr.com/ddk/graphics/gdifncs_2c9z.htm - UNIMPLEMENTED; - return FALSE; + // www.osr.com/ddk/graphics/gdifncs_2c9z.htm + UNIMPLEMENTED; + return FALSE; } BOOL APIENTRY PATHOBJ_bPolyLineTo( - IN PATHOBJ *ppo, - IN POINTFIX *pptfx, - IN ULONG cptfx - ) + IN PATHOBJ *ppo, + IN POINTFIX *pptfx, + IN ULONG cptfx) { - // www.osr.com/ddk/graphics/gdifncs_0x47.htm - UNIMPLEMENTED; - return FALSE; + // www.osr.com/ddk/graphics/gdifncs_0x47.htm + UNIMPLEMENTED; + return FALSE; } VOID APIENTRY -PATHOBJ_vEnumStart ( IN PATHOBJ *ppo ) +PATHOBJ_vEnumStart(IN PATHOBJ *ppo) { - // www.osr.com/ddk/graphics/gdifncs_74br.htm - UNIMPLEMENTED; + // www.osr.com/ddk/graphics/gdifncs_74br.htm + UNIMPLEMENTED; } VOID APIENTRY PATHOBJ_vEnumStartClipLines( - IN PATHOBJ *ppo, - IN CLIPOBJ *pco, - IN SURFOBJ *pso, - IN LINEATTRS *pla - ) + IN PATHOBJ *ppo, + IN CLIPOBJ *pco, + IN SURFOBJ *pso, + IN LINEATTRS *pla) { - // www.osr.com/ddk/graphics/gdifncs_5grr.htm - UNIMPLEMENTED; + // www.osr.com/ddk/graphics/gdifncs_5grr.htm + UNIMPLEMENTED; } VOID APIENTRY PATHOBJ_vGetBounds( - IN PATHOBJ *ppo, - OUT PRECTFX prectfx - ) + IN PATHOBJ *ppo, + OUT PRECTFX prectfx) { - // www.osr.com/ddk/graphics/gdifncs_8qp3.htm - UNIMPLEMENTED; + // www.osr.com/ddk/graphics/gdifncs_8qp3.htm + UNIMPLEMENTED; } /* * @unimplemented */ -ULONG APIENTRY +ULONG +APIENTRY EngDitherColor( - IN HDEV hdev, - IN ULONG iMode, - IN ULONG rgb, - OUT ULONG *pul) + IN HDEV hdev, + IN ULONG iMode, + IN ULONG rgb, + OUT ULONG *pul) { *pul = 0; return DCR_SOLID; @@ -629,12 +600,13 @@ EngDitherColor( /* * @unimplemented */ -HANDLE APIENTRY +HANDLE +APIENTRY BRUSHOBJ_hGetColorTransform( - IN BRUSHOBJ *Brush) + IN BRUSHOBJ *Brush) { - UNIMPLEMENTED; - return NULL; + UNIMPLEMENTED; + return NULL; } /* @@ -643,85 +615,90 @@ BRUSHOBJ_hGetColorTransform( BOOL APIENTRY EngDeleteFile( - IN LPWSTR FileName) + IN LPWSTR FileName) { - UNIMPLEMENTED; - return FALSE; + UNIMPLEMENTED; + return FALSE; } /* * @unimplemented */ -BOOL APIENTRY +BOOL +APIENTRY EngGetPrinterDriver( - IN HANDLE Printer, - IN LPWSTR Environment, - IN DWORD Level, - OUT BYTE *DrvInfo, - IN DWORD Buf, - OUT DWORD *Needed) + IN HANDLE Printer, + IN LPWSTR Environment, + IN DWORD Level, + OUT BYTE *DrvInfo, + IN DWORD Buf, + OUT DWORD *Needed) { - UNIMPLEMENTED; - return FALSE; + UNIMPLEMENTED; + return FALSE; } /* * @unimplemented */ -ULONG APIENTRY +ULONG +APIENTRY EngHangNotification( - IN HDEV Dev, - IN PVOID Reserved) + IN HDEV Dev, + IN PVOID Reserved) { - UNIMPLEMENTED; - return EHN_ERROR; + UNIMPLEMENTED; + return EHN_ERROR; } /* * @unimplemented */ -BOOL APIENTRY +BOOL +APIENTRY EngLpkInstalled() { - UNIMPLEMENTED; - return FALSE; + UNIMPLEMENTED; + return FALSE; } /* * @unimplemented */ -BOOL APIENTRY +BOOL +APIENTRY EngPlgBlt( - IN SURFOBJ *Dest, - IN SURFOBJ *Source, - IN SURFOBJ *Mask, - IN CLIPOBJ *Clip, - IN XLATEOBJ *Xlate, - IN COLORADJUSTMENT *ColorAdjustment, - IN POINTL *BrusOrigin, - IN POINTFIX *DestPoints, - IN RECTL *SourceRect, - IN POINTL *MaskPoint, - IN ULONG Mode) + IN SURFOBJ *Dest, + IN SURFOBJ *Source, + IN SURFOBJ *Mask, + IN CLIPOBJ *Clip, + IN XLATEOBJ *Xlate, + IN COLORADJUSTMENT *ColorAdjustment, + IN POINTL *BrusOrigin, + IN POINTFIX *DestPoints, + IN RECTL *SourceRect, + IN POINTL *MaskPoint, + IN ULONG Mode) { - UNIMPLEMENTED; - return FALSE; + UNIMPLEMENTED; + return FALSE; } /* * @unimplemented */ -BOOL APIENTRY +BOOL +APIENTRY EngQueryDeviceAttribute( - IN HDEV Device, - IN ENG_DEVICE_ATTRIBUTE Attribute, - IN VOID *In, - IN ULONG InSize, - OUT VOID *Out, - OUT ULONG OutSize) + IN HDEV Device, + IN ENG_DEVICE_ATTRIBUTE Attribute, + IN VOID *In, + IN ULONG InSize, + OUT VOID *Out, + OUT ULONG OutSize) { - UNIMPLEMENTED; - return FALSE; + UNIMPLEMENTED; + return FALSE; } /* @@ -731,74 +708,79 @@ LARGE_INTEGER APIENTRY EngQueryFileTimeStamp(IN LPWSTR FileName) { - LARGE_INTEGER FileTime; - FileTime.QuadPart = 0; - UNIMPLEMENTED; - return FileTime; + LARGE_INTEGER FileTime; + FileTime.QuadPart = 0; + UNIMPLEMENTED; + return FileTime; } /* * @unimplemented */ -FD_GLYPHSET * APIENTRY +FD_GLYPHSET * +APIENTRY FONTOBJ_pfdg( - IN FONTOBJ *FontObj) + IN FONTOBJ *FontObj) { - UNIMPLEMENTED; - return NULL; + UNIMPLEMENTED; + return NULL; } /* * @unimplemented */ -PBYTE APIENTRY +PBYTE +APIENTRY FONTOBJ_pjOpenTypeTablePointer( - IN FONTOBJ *FontObj, - IN ULONG Tag, - OUT ULONG *Table) + IN FONTOBJ *FontObj, + IN ULONG Tag, + OUT ULONG *Table) { - UNIMPLEMENTED; - return NULL; + UNIMPLEMENTED; + return NULL; } /* * @unimplemented */ -PFD_GLYPHATTR APIENTRY +PFD_GLYPHATTR +APIENTRY FONTOBJ_pQueryGlyphAttrs( - IN FONTOBJ *FontObj, - IN ULONG Mode) + IN FONTOBJ *FontObj, + IN ULONG Mode) { - UNIMPLEMENTED; - return NULL; + UNIMPLEMENTED; + return NULL; } /* * @unimplemented */ -LPWSTR APIENTRY +LPWSTR +APIENTRY FONTOBJ_pwszFontFilePaths( - IN FONTOBJ *FontObj, - OUT ULONG *PathLength) + IN FONTOBJ *FontObj, + OUT ULONG *PathLength) { - UNIMPLEMENTED; - return NULL; + UNIMPLEMENTED; + return NULL; } /* * @unimplemented */ -LONG APIENTRY +LONG +APIENTRY HT_Get8BPPMaskPalette( - IN OUT LPPALETTEENTRY PaletteEntry, - IN BOOL Use8BPPMaskPal, - IN BYTE CMYMask, - IN USHORT RedGamma, - IN USHORT GreenGamma, - IN USHORT BlueGamma) + IN OUT LPPALETTEENTRY PaletteEntry, + IN BOOL Use8BPPMaskPal, + IN BYTE CMYMask, + IN USHORT RedGamma, + IN USHORT GreenGamma, + IN USHORT BlueGamma) { - UNIMPLEMENTED; - return 0; + UNIMPLEMENTED; + return 0; } /* @@ -808,8 +790,8 @@ BOOL APIENTRY NtGdiAnyLinkedFonts() { - UNIMPLEMENTED; - return FALSE; + UNIMPLEMENTED; + return FALSE; } /* @@ -848,8 +830,7 @@ NtGdiAddFontMemResourceEx( IN DWORD cjBuffer, IN DESIGNVECTOR *pdv, IN ULONG cjDV, - OUT DWORD *pNumFonts -) + OUT DWORD *pNumFonts) { UNIMPLEMENTED; return NULL; @@ -1208,7 +1189,7 @@ NtGdiGetEudcTimeStampEx( */ BOOL APIENTRY -NtGdiInitSpool() +NtGdiInitSpool(VOID) { UNIMPLEMENTED; return FALSE; @@ -1219,9 +1200,10 @@ NtGdiInitSpool() */ INT APIENTRY -NtGdiQueryFonts( OUT PUNIVERSAL_FONT_ID pufiFontList, - IN ULONG nBufferSize, - OUT PLARGE_INTEGER pTimeStamp) +NtGdiQueryFonts( + OUT PUNIVERSAL_FONT_ID pufiFontList, + IN ULONG nBufferSize, + OUT PLARGE_INTEGER pTimeStamp) { UNIMPLEMENTED; return 0; @@ -1232,10 +1214,11 @@ NtGdiQueryFonts( OUT PUNIVERSAL_FONT_ID pufiFontList, */ INT APIENTRY -NtGdiGetSpoolMessage( DWORD u1, - DWORD u2, - DWORD u3, - DWORD u4) +NtGdiGetSpoolMessage( + DWORD u1, + DWORD u2, + DWORD u3, + DWORD u4) { /* FIXME: The prototypes */ UNIMPLEMENTED; @@ -1559,7 +1542,7 @@ NtGdiIcmBrushInfo( */ BOOL APIENTRY -NtGdiInit() +NtGdiInit(VOID) { return TRUE; } @@ -1686,17 +1669,18 @@ NtGdiUnmapMemFont( BOOL APIENTRY EngControlSprites( - IN WNDOBJ *pwo, - IN FLONG fl) + IN WNDOBJ *pwo, + IN FLONG fl) { - UNIMPLEMENTED; - return FALSE; + UNIMPLEMENTED; + return FALSE; } PVOID APIENTRY -EngFntCacheAlloc(IN ULONG FastCheckSum, - IN ULONG ulSize) +EngFntCacheAlloc( + IN ULONG FastCheckSum, + IN ULONG ulSize) { UNIMPLEMENTED; return NULL; @@ -1704,16 +1688,18 @@ EngFntCacheAlloc(IN ULONG FastCheckSum, VOID APIENTRY -EngFntCacheFault(IN ULONG ulFastCheckSum, - IN ULONG iFaultMode) +EngFntCacheFault( + IN ULONG ulFastCheckSum, + IN ULONG iFaultMode) { UNIMPLEMENTED; } PVOID APIENTRY -EngFntCacheLookUp(IN ULONG FastCheckSum, - OUT PULONG pulSize) +EngFntCacheLookUp( + IN ULONG FastCheckSum, + OUT PULONG pulSize) { UNIMPLEMENTED; return NULL; @@ -1721,15 +1707,16 @@ EngFntCacheLookUp(IN ULONG FastCheckSum, BOOLEAN APIENTRY -EngNineGrid(IN SURFOBJ* pDestSurfaceObj, - IN SURFOBJ* pSourceSurfaceObj, - IN CLIPOBJ* pClipObj, - IN XLATEOBJ* pXlateObj, - IN RECTL* prclSource, - IN RECTL* prclDest, - PVOID pvUnknown1, - PVOID pvUnknown2, - DWORD dwReserved) +EngNineGrid( + IN SURFOBJ* pDestSurfaceObj, + IN SURFOBJ* pSourceSurfaceObj, + IN CLIPOBJ* pClipObj, + IN XLATEOBJ* pXlateObj, + IN RECTL* prclSource, + IN RECTL* prclDest, + PVOID pvUnknown1, + PVOID pvUnknown2, + DWORD dwReserved) { UNIMPLEMENTED; return FALSE; diff --git a/win32ss/gdi/eng/surface.h b/win32ss/gdi/eng/surface.h index cbfeac99484..2ab6037f947 100644 --- a/win32ss/gdi/eng/surface.h +++ b/win32ss/gdi/eng/surface.h @@ -126,8 +126,8 @@ SURFACE_AllocSurface( _In_opt_ ULONG cjWidth, _In_opt_ PVOID pvBits); -VOID FORCEINLINE +VOID SURFACE_vSetPalette( _Inout_ PSURFACE psurf, _In_ PPALETTE ppal) diff --git a/win32ss/gdi/eng/transblt.c b/win32ss/gdi/eng/transblt.c index 0b931cd4212..a4eaaebc471 100644 --- a/win32ss/gdi/eng/transblt.c +++ b/win32ss/gdi/eng/transblt.c @@ -11,277 +11,293 @@ #define NDEBUG #include -BOOL APIENTRY -EngTransparentBlt(SURFOBJ *psoDest, - SURFOBJ *psoSource, - CLIPOBJ *Clip, - XLATEOBJ *ColorTranslation, - PRECTL DestRect, - PRECTL SourceRect, - ULONG iTransColor, - ULONG Reserved) +BOOL +APIENTRY +EngTransparentBlt( + SURFOBJ *psoDest, + SURFOBJ *psoSource, + CLIPOBJ *Clip, + XLATEOBJ *ColorTranslation, + PRECTL DestRect, + PRECTL SourceRect, + ULONG iTransColor, + ULONG Reserved) { - BOOL Ret = TRUE; - BYTE ClippingType; - INTENG_ENTER_LEAVE EnterLeaveSource, EnterLeaveDest; - SURFOBJ *InputObj, *OutputObj; - RECTL OutputRect, InputRect; - POINTL Translate; + BOOL Ret = TRUE; + BYTE ClippingType; + INTENG_ENTER_LEAVE EnterLeaveSource, EnterLeaveDest; + SURFOBJ *InputObj, *OutputObj; + RECTL OutputRect, InputRect; + POINTL Translate; - LONG DstHeight; - LONG DstWidth; - LONG SrcHeight; - LONG SrcWidth; + LONG DstHeight; + LONG DstWidth; + LONG SrcHeight; + LONG SrcWidth; - InputRect = *SourceRect; + InputRect = *SourceRect; - if(!IntEngEnter(&EnterLeaveSource, psoSource, &InputRect, TRUE, &Translate, &InputObj)) - { - return FALSE; - } - InputRect.left += Translate.x; - InputRect.right += Translate.x; - InputRect.top += Translate.y; - InputRect.bottom += Translate.y; - - OutputRect = *DestRect; - if (OutputRect.right < OutputRect.left) - { - OutputRect.left = DestRect->right; - OutputRect.right = DestRect->left; - } - if (OutputRect.bottom < OutputRect.top) - { - OutputRect.top = DestRect->bottom; - OutputRect.bottom = DestRect->top; - } - - if(Clip) - { - if(OutputRect.left < Clip->rclBounds.left) + if (!IntEngEnter(&EnterLeaveSource, psoSource, &InputRect, TRUE, &Translate, &InputObj)) { - InputRect.left += Clip->rclBounds.left - OutputRect.left; - OutputRect.left = Clip->rclBounds.left; + return FALSE; } - if(Clip->rclBounds.right < OutputRect.right) + InputRect.left += Translate.x; + InputRect.right += Translate.x; + InputRect.top += Translate.y; + InputRect.bottom += Translate.y; + + OutputRect = *DestRect; + if (OutputRect.right < OutputRect.left) { - InputRect.right -= OutputRect.right - Clip->rclBounds.right; - OutputRect.right = Clip->rclBounds.right; + OutputRect.left = DestRect->right; + OutputRect.right = DestRect->left; } - if(OutputRect.top < Clip->rclBounds.top) + if (OutputRect.bottom < OutputRect.top) { - InputRect.top += Clip->rclBounds.top - OutputRect.top; - OutputRect.top = Clip->rclBounds.top; + OutputRect.top = DestRect->bottom; + OutputRect.bottom = DestRect->top; } - if(Clip->rclBounds.bottom < OutputRect.bottom) + + if (Clip) { - InputRect.bottom -= OutputRect.bottom - Clip->rclBounds.bottom; - OutputRect.bottom = Clip->rclBounds.bottom; - } - } - - /* Check for degenerate case: if height or width of OutputRect is 0 pixels there's - nothing to do */ - if(OutputRect.right <= OutputRect.left || OutputRect.bottom <= OutputRect.top) - { - IntEngLeave(&EnterLeaveSource); - return TRUE; - } - - if(!IntEngEnter(&EnterLeaveDest, psoDest, &OutputRect, FALSE, &Translate, &OutputObj)) - { - IntEngLeave(&EnterLeaveSource); - return FALSE; - } - - OutputRect.left = DestRect->left + Translate.x; - OutputRect.right = DestRect->right + Translate.x; - OutputRect.top = DestRect->top + Translate.y; - OutputRect.bottom = DestRect->bottom + Translate.y; - - ClippingType = (Clip ? Clip->iDComplexity : DC_TRIVIAL); - - DstHeight = OutputRect.bottom - OutputRect.top; - DstWidth = OutputRect.right - OutputRect.left; - SrcHeight = InputRect.bottom - InputRect.top; - SrcWidth = InputRect.right - InputRect.left; - switch(ClippingType) - { - case DC_TRIVIAL: - { - Ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_TransparentBlt( - OutputObj, InputObj, &OutputRect, &InputRect, ColorTranslation, iTransColor); - break; - } - case DC_RECT: - { - RECTL ClipRect, CombinedRect; - RECTL InputToCombinedRect; - - ClipRect.left = Clip->rclBounds.left + Translate.x; - ClipRect.right = Clip->rclBounds.right + Translate.x; - ClipRect.top = Clip->rclBounds.top + Translate.y; - ClipRect.bottom = Clip->rclBounds.bottom + Translate.y; - if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect)) - { - InputToCombinedRect.top = InputRect.top + (CombinedRect.top - OutputRect.top) * SrcHeight / DstHeight; - InputToCombinedRect.bottom = InputRect.top + (CombinedRect.bottom - OutputRect.top) * SrcHeight / DstHeight; - InputToCombinedRect.left = InputRect.left + (CombinedRect.left - OutputRect.left) * SrcWidth / DstWidth; - InputToCombinedRect.right = InputRect.left + (CombinedRect.right - OutputRect.left) * SrcWidth / DstWidth; - Ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_TransparentBlt( - OutputObj, InputObj, &CombinedRect, &InputToCombinedRect, ColorTranslation, iTransColor); - } - break; - } - case DC_COMPLEX: - { - ULONG Direction, i; - RECT_ENUM RectEnum; - BOOL EnumMore; - - if(OutputObj == InputObj) - { - if(OutputRect.top < InputRect.top) + if (OutputRect.left < Clip->rclBounds.left) { - Direction = OutputRect.left < (InputRect.left ? CD_RIGHTDOWN : CD_LEFTDOWN); + InputRect.left += Clip->rclBounds.left - OutputRect.left; + OutputRect.left = Clip->rclBounds.left; } - else + if (Clip->rclBounds.right < OutputRect.right) { - Direction = OutputRect.left < (InputRect.left ? CD_RIGHTUP : CD_LEFTUP); + InputRect.right -= OutputRect.right - Clip->rclBounds.right; + OutputRect.right = Clip->rclBounds.right; } - } - else - { - Direction = CD_ANY; - } - - CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, Direction, 0); - do - { - EnumMore = CLIPOBJ_bEnum(Clip, sizeof(RectEnum), (PVOID)&RectEnum); - for (i = 0; i < RectEnum.c; i++) + if (OutputRect.top < Clip->rclBounds.top) { - RECTL ClipRect, CombinedRect; - RECTL InputToCombinedRect; + InputRect.top += Clip->rclBounds.top - OutputRect.top; + OutputRect.top = Clip->rclBounds.top; + } + if (Clip->rclBounds.bottom < OutputRect.bottom) + { + InputRect.bottom -= OutputRect.bottom - Clip->rclBounds.bottom; + OutputRect.bottom = Clip->rclBounds.bottom; + } + } - ClipRect.left = RectEnum.arcl[i].left + Translate.x; - ClipRect.right = RectEnum.arcl[i].right + Translate.x; - ClipRect.top = RectEnum.arcl[i].top + Translate.y; - ClipRect.bottom = RectEnum.arcl[i].bottom + Translate.y; - if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect)) - { - InputToCombinedRect.top = InputRect.top + (CombinedRect.top - OutputRect.top) * SrcHeight / DstHeight; - InputToCombinedRect.bottom = InputRect.top + (CombinedRect.bottom - OutputRect.top) * SrcHeight / DstHeight; - InputToCombinedRect.left = InputRect.left + (CombinedRect.left - OutputRect.left) * SrcWidth / DstWidth; - InputToCombinedRect.right = InputRect.left + (CombinedRect.right - OutputRect.left) * SrcWidth / DstWidth; + /* Check for degenerate case: if height or width of OutputRect is 0 pixels there's + nothing to do */ + if (OutputRect.right <= OutputRect.left || OutputRect.bottom <= OutputRect.top) + { + IntEngLeave(&EnterLeaveSource); + return TRUE; + } + if (!IntEngEnter(&EnterLeaveDest, psoDest, &OutputRect, FALSE, &Translate, &OutputObj)) + { + IntEngLeave(&EnterLeaveSource); + return FALSE; + } + + OutputRect.left = DestRect->left + Translate.x; + OutputRect.right = DestRect->right + Translate.x; + OutputRect.top = DestRect->top + Translate.y; + OutputRect.bottom = DestRect->bottom + Translate.y; + + ClippingType = (Clip ? Clip->iDComplexity : DC_TRIVIAL); + + DstHeight = OutputRect.bottom - OutputRect.top; + DstWidth = OutputRect.right - OutputRect.left; + SrcHeight = InputRect.bottom - InputRect.top; + SrcWidth = InputRect.right - InputRect.left; + switch (ClippingType) + { + case DC_TRIVIAL: + { Ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_TransparentBlt( - OutputObj, InputObj, &CombinedRect, &InputToCombinedRect, ColorTranslation, iTransColor); - if(!Ret) - { - break; - } - } + OutputObj, InputObj, &OutputRect, &InputRect, ColorTranslation, iTransColor); + break; } - } while(EnumMore && Ret); - break; - } - default: - { - Ret = FALSE; - break; - } - } + case DC_RECT: + { + RECTL ClipRect, CombinedRect; + RECTL InputToCombinedRect; - IntEngLeave(&EnterLeaveDest); - IntEngLeave(&EnterLeaveSource); + ClipRect.left = Clip->rclBounds.left + Translate.x; + ClipRect.right = Clip->rclBounds.right + Translate.x; + ClipRect.top = Clip->rclBounds.top + Translate.y; + ClipRect.bottom = Clip->rclBounds.bottom + Translate.y; + if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect)) + { + InputToCombinedRect.top = InputRect.top + (CombinedRect.top - OutputRect.top) * SrcHeight / DstHeight; + InputToCombinedRect.bottom = InputRect.top + (CombinedRect.bottom - OutputRect.top) * SrcHeight / DstHeight; + InputToCombinedRect.left = InputRect.left + (CombinedRect.left - OutputRect.left) * SrcWidth / DstWidth; + InputToCombinedRect.right = InputRect.left + (CombinedRect.right - OutputRect.left) * SrcWidth / DstWidth; + Ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_TransparentBlt( + OutputObj, InputObj, &CombinedRect, &InputToCombinedRect, ColorTranslation, iTransColor); + } + break; + } + case DC_COMPLEX: + { + ULONG Direction, i; + RECT_ENUM RectEnum; + BOOL EnumMore; - return Ret; + if (OutputObj == InputObj) + { + if (OutputRect.top < InputRect.top) + { + Direction = OutputRect.left < (InputRect.left ? CD_RIGHTDOWN : CD_LEFTDOWN); + } + else + { + Direction = OutputRect.left < (InputRect.left ? CD_RIGHTUP : CD_LEFTUP); + } + } + else + { + Direction = CD_ANY; + } + + CLIPOBJ_cEnumStart(Clip, FALSE, CT_RECTANGLES, Direction, 0); + do + { + EnumMore = CLIPOBJ_bEnum(Clip, sizeof(RectEnum), (PVOID)&RectEnum); + for (i = 0; i < RectEnum.c; i++) + { + RECTL ClipRect, CombinedRect; + RECTL InputToCombinedRect; + + ClipRect.left = RectEnum.arcl[i].left + Translate.x; + ClipRect.right = RectEnum.arcl[i].right + Translate.x; + ClipRect.top = RectEnum.arcl[i].top + Translate.y; + ClipRect.bottom = RectEnum.arcl[i].bottom + Translate.y; + if (RECTL_bIntersectRect(&CombinedRect, &OutputRect, &ClipRect)) + { + InputToCombinedRect.top = InputRect.top + (CombinedRect.top - OutputRect.top) * SrcHeight / DstHeight; + InputToCombinedRect.bottom = InputRect.top + (CombinedRect.bottom - OutputRect.top) * SrcHeight / DstHeight; + InputToCombinedRect.left = InputRect.left + (CombinedRect.left - OutputRect.left) * SrcWidth / DstWidth; + InputToCombinedRect.right = InputRect.left + (CombinedRect.right - OutputRect.left) * SrcWidth / DstWidth; + + Ret = DibFunctionsForBitmapFormat[psoDest->iBitmapFormat].DIB_TransparentBlt( + OutputObj, InputObj, &CombinedRect, &InputToCombinedRect, ColorTranslation, iTransColor); + if (!Ret) + { + break; + } + } + } + } + while (EnumMore && Ret); + break; + } + default: + { + Ret = FALSE; + break; + } + } + + IntEngLeave(&EnterLeaveDest); + IntEngLeave(&EnterLeaveSource); + + return Ret; } -BOOL FASTCALL -IntEngTransparentBlt(SURFOBJ *psoDest, - SURFOBJ *psoSource, - CLIPOBJ *Clip, - XLATEOBJ *ColorTranslation, - PRECTL DestRect, - PRECTL SourceRect, - ULONG iTransColor, - ULONG Reserved) +BOOL +FASTCALL +IntEngTransparentBlt( + SURFOBJ *psoDest, + SURFOBJ *psoSource, + CLIPOBJ *Clip, + XLATEOBJ *ColorTranslation, + PRECTL DestRect, + PRECTL SourceRect, + ULONG iTransColor, + ULONG Reserved) { - BOOL Ret; - RECTL OutputRect, InputClippedRect; - SURFACE *psurfDest; - SURFACE *psurfSource; - RECTL InputRect; - LONG InputClWidth, InputClHeight, InputWidth, InputHeight; + BOOL Ret; + RECTL OutputRect, InputClippedRect; + SURFACE *psurfDest; + SURFACE *psurfSource; + RECTL InputRect; + LONG InputClWidth, InputClHeight, InputWidth, InputHeight; - ASSERT(psoDest); - ASSERT(psoSource); - ASSERT(DestRect); + ASSERT(psoDest); + ASSERT(psoSource); + ASSERT(DestRect); - psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj); - psurfSource = CONTAINING_RECORD(psoSource, SURFACE, SurfObj); + psurfDest = CONTAINING_RECORD(psoDest, SURFACE, SurfObj); + psurfSource = CONTAINING_RECORD(psoSource, SURFACE, SurfObj); - ASSERT(psurfDest); - ASSERT(psurfSource); + ASSERT(psurfDest); + ASSERT(psurfSource); - /* If no clip object is given, use trivial one */ - if (!Clip) Clip = &gxcoTrivial.ClipObj; + /* If no clip object is given, use trivial one */ + if (!Clip) Clip = &gxcoTrivial.ClipObj; - InputClippedRect = *DestRect; - if(InputClippedRect.right < InputClippedRect.left) - { - InputClippedRect.left = DestRect->right; - InputClippedRect.right = DestRect->left; - } - if(InputClippedRect.bottom < InputClippedRect.top) - { - InputClippedRect.top = DestRect->bottom; - InputClippedRect.bottom = DestRect->top; - } - - InputRect = *SourceRect; - /* Clip against the bounds of the clipping region so we won't try to write - * outside the surface */ - if (Clip->iDComplexity != DC_TRIVIAL) - { - if(!RECTL_bIntersectRect(&OutputRect, &InputClippedRect, &Clip->rclBounds)) + InputClippedRect = *DestRect; + if (InputClippedRect.right < InputClippedRect.left) { - return TRUE; + InputClippedRect.left = DestRect->right; + InputClippedRect.right = DestRect->left; + } + if (InputClippedRect.bottom < InputClippedRect.top) + { + InputClippedRect.top = DestRect->bottom; + InputClippedRect.bottom = DestRect->top; } - /* Update source rect */ - InputClWidth = InputClippedRect.right - InputClippedRect.left; - InputClHeight = InputClippedRect.bottom - InputClippedRect.top; - InputWidth = InputRect.right - InputRect.left; - InputHeight = InputRect.bottom - InputRect.top; - InputRect.left += (InputWidth * (OutputRect.left - InputClippedRect.left)) / InputClWidth; - InputRect.right -= (InputWidth * (InputClippedRect.right - OutputRect.right)) / InputClWidth; - InputRect.top += (InputHeight * (OutputRect.top - InputClippedRect.top)) / InputClHeight; - InputRect.bottom -= (InputHeight * (InputClippedRect.bottom - OutputRect.bottom)) / InputClHeight; - } - else - { - OutputRect = InputClippedRect; - } + InputRect = *SourceRect; + /* Clip against the bounds of the clipping region so we won't try to write + * outside the surface */ + if (Clip->iDComplexity != DC_TRIVIAL) + { + if (!RECTL_bIntersectRect(&OutputRect, &InputClippedRect, &Clip->rclBounds)) + { + return TRUE; + } + /* Update source rect */ + InputClWidth = InputClippedRect.right - InputClippedRect.left; + InputClHeight = InputClippedRect.bottom - InputClippedRect.top; + InputWidth = InputRect.right - InputRect.left; + InputHeight = InputRect.bottom - InputRect.top; - if(psurfDest->flags & HOOK_TRANSPARENTBLT) - { - Ret = GDIDEVFUNCS(psoDest).TransparentBlt( - psoDest, psoSource, Clip, ColorTranslation, &OutputRect, - &InputRect, iTransColor, Reserved); - } - else - Ret = FALSE; + InputRect.left += (InputWidth * (OutputRect.left - InputClippedRect.left)) / InputClWidth; + InputRect.right -= (InputWidth * (InputClippedRect.right - OutputRect.right)) / InputClWidth; + InputRect.top += (InputHeight * (OutputRect.top - InputClippedRect.top)) / InputClHeight; + InputRect.bottom -= (InputHeight * (InputClippedRect.bottom - OutputRect.bottom)) / InputClHeight; + } + else + { + OutputRect = InputClippedRect; + } - if(!Ret) - { - Ret = EngTransparentBlt(psoDest, psoSource, Clip, ColorTranslation, - &OutputRect, &InputRect, iTransColor, Reserved); - } + if (psurfDest->flags & HOOK_TRANSPARENTBLT) + { + Ret = GDIDEVFUNCS(psoDest).TransparentBlt(psoDest, + psoSource, + Clip, + ColorTranslation, + &OutputRect, + &InputRect, + iTransColor, + Reserved); + } + else + Ret = FALSE; - return Ret; + if (!Ret) + { + Ret = EngTransparentBlt(psoDest, + psoSource, + Clip, + ColorTranslation, + &OutputRect, + &InputRect, + iTransColor, + Reserved); + } + + return Ret; } /* EOF */ diff --git a/win32ss/gdi/eng/xlateobj.h b/win32ss/gdi/eng/xlateobj.h index 3249c1d1bfe..7e338932e6f 100644 --- a/win32ss/gdi/eng/xlateobj.h +++ b/win32ss/gdi/eng/xlateobj.h @@ -46,8 +46,8 @@ typedef struct _EXLATEOBJ extern EXLATEOBJ gexloTrivial; _Notnull_ -PFN_XLATE FORCEINLINE +PFN_XLATE XLATEOBJ_pfnXlate( _In_ XLATEOBJ *pxlo) { diff --git a/win32ss/gdi/gdi32/gdi32.spec b/win32ss/gdi/gdi32/gdi32.spec index b3b0fdd34c9..e8c77267fcd 100644 --- a/win32ss/gdi/gdi32/gdi32.spec +++ b/win32ss/gdi/gdi32/gdi32.spec @@ -159,13 +159,10 @@ @ stdcall EngCheckAbort(ptr) NtGdiEngCheckAbort @ stdcall EngComputeGlyphSet(ptr ptr ptr) @ stdcall EngCopyBits(ptr ptr ptr ptr ptr ptr) NtGdiEngCopyBits -# @ stdcall EngCreateBitmap(longlong long long long ptr) NtGdiEngCreateBitmap -@ stdcall EngCreateBitmap(long long long long long ptr) NtGdiEngCreateBitmap +@ stdcall EngCreateBitmap(int64 long long long ptr) NtGdiEngCreateBitmap @ stdcall EngCreateClip() NtGdiEngCreateClip -# @ stdcall EngCreateDeviceBitmap(ptr longlong long) NtGdiEngCreateDeviceBitmap -@ stdcall EngCreateDeviceBitmap(ptr long long long) NtGdiEngCreateDeviceBitmap -# @ stdcall EngCreateDeviceSurface(ptr longlong long) NtGdiEngCreateDeviceSurface -@ stdcall EngCreateDeviceSurface(ptr long long long) NtGdiEngCreateDeviceSurface +@ stdcall EngCreateDeviceBitmap(ptr int64 long) NtGdiEngCreateDeviceBitmap +@ stdcall EngCreateDeviceSurface(ptr int64 long) NtGdiEngCreateDeviceSurface @ stdcall EngCreatePalette(long long ptr long long long) NtGdiEngCreatePalette @ stdcall EngCreateSemaphore() @ stdcall EngDeleteClip(ptr) NtGdiEngDeleteClip @@ -287,7 +284,6 @@ @ stdcall GdiFlush() @ stdcall GdiFullscreenControl(ptr ptr long ptr ptr) NtGdiFullscreenControl @ stdcall GdiGetBatchLimit() -@ stdcall GdiGetBitmapBitsSize(ptr) @ stdcall GdiGetCharDimensions(long ptr ptr) @ stdcall GdiGetCodePage(long) @ stdcall GdiGetDC(ptr) diff --git a/win32ss/gdi/ntgdi/brush.h b/win32ss/gdi/ntgdi/brush.h index 69288aea614..79a2e0edf83 100644 --- a/win32ss/gdi/ntgdi/brush.h +++ b/win32ss/gdi/ntgdi/brush.h @@ -142,8 +142,8 @@ EBRUSHOBJ_psoPattern(EBRUSHOBJ *pebo); #define BRUSHOBJ_psoPattern(pbo) \ EBRUSHOBJ_psoPattern(CONTAINING_RECORD(pbo, EBRUSHOBJ, BrushObject)) -ULONG FORCEINLINE +ULONG EBRUSHOBJ_iSetSolidColor(EBRUSHOBJ *pebo, ULONG iSolidColor) { ULONG iOldColor = pebo->BrushObject.iSolidColor; diff --git a/win32ss/gdi/ntgdi/coord.h b/win32ss/gdi/ntgdi/coord.h index 6b80232f9ac..c433f76cc3d 100644 --- a/win32ss/gdi/ntgdi/coord.h +++ b/win32ss/gdi/ntgdi/coord.h @@ -57,8 +57,8 @@ VOID FASTCALL DC_vUpdateDeviceToWorld(PDC pdc); -PSIZEL FORCEINLINE +PSIZEL DC_pszlViewportExt(PDC pdc) { PDC_ATTR pdcattr = pdc->pdcattr; @@ -74,15 +74,15 @@ DC_pszlViewportExt(PDC pdc) return &pdcattr->szlViewportExt; } -PMATRIX FORCEINLINE +PMATRIX DC_pmxWorldToPage(PDC pdc) { return &pdc->pdcattr->mxWorldToPage; } -PMATRIX FORCEINLINE +PMATRIX DC_pmxWorldToDevice(PDC pdc) { /* Check if world or page xform was changed */ @@ -95,8 +95,8 @@ DC_pmxWorldToDevice(PDC pdc) return &pdc->pdcattr->mxWorldToDevice; } -PMATRIX FORCEINLINE +PMATRIX DC_pmxDeviceToWorld(PDC pdc) { /* Check if the device-to-world xform is invalid */ @@ -109,8 +109,8 @@ DC_pmxDeviceToWorld(PDC pdc) return &pdc->pdcattr->mxDeviceToWorld; } -VOID FORCEINLINE +VOID DC_vXformDeviceToWorld( IN PDC pdc, IN ULONG cNumPoints, @@ -125,8 +125,8 @@ DC_vXformDeviceToWorld( XFORMOBJ_bApplyXform(&xo, XF_LTOL, cNumPoints, pptlDest, pptlSource); } -VOID FORCEINLINE +VOID DC_vXformWorldToDevice( IN PDC pdc, IN ULONG cNumPoints, diff --git a/win32ss/gdi/ntgdi/dc.h b/win32ss/gdi/ntgdi/dc.h index 7d646f75679..a1a11701cf9 100644 --- a/win32ss/gdi/ntgdi/dc.h +++ b/win32ss/gdi/ntgdi/dc.h @@ -247,8 +247,8 @@ DC_UnlockDc(PDC pdc) GDIOBJ_vUnlockObject(&pdc->BaseObject); } -VOID FORCEINLINE +VOID DC_vSelectSurface(PDC pdc, PSURFACE psurfNew) { PSURFACE psurfOld = pdc->dclevel.pSurface; @@ -262,8 +262,8 @@ DC_vSelectSurface(PDC pdc, PSURFACE psurfNew) pdc->dclevel.pSurface = psurfNew; } -VOID FORCEINLINE +VOID DC_vSelectFillBrush(PDC pdc, PBRUSH pbrFill) { PBRUSH pbrFillOld = pdc->dclevel.pbrFill; @@ -274,8 +274,8 @@ DC_vSelectFillBrush(PDC pdc, PBRUSH pbrFill) pdc->dclevel.pbrFill = pbrFill; } -VOID FORCEINLINE +VOID DC_vSelectLineBrush(PDC pdc, PBRUSH pbrLine) { PBRUSH pbrLineOld = pdc->dclevel.pbrLine; @@ -286,8 +286,8 @@ DC_vSelectLineBrush(PDC pdc, PBRUSH pbrLine) pdc->dclevel.pbrLine = pbrLine; } -VOID FORCEINLINE +VOID DC_vSelectPalette(PDC pdc, PPALETTE ppal) { PPALETTE ppalOld = pdc->dclevel.ppal; diff --git a/win32ss/gdi/ntgdi/dcutil.c b/win32ss/gdi/ntgdi/dcutil.c index e4a6f40bb19..695d7e29a78 100644 --- a/win32ss/gdi/ntgdi/dcutil.c +++ b/win32ss/gdi/ntgdi/dcutil.c @@ -236,8 +236,8 @@ GreSetStretchBltMode(HDC hDC, int iStretchMode) if ((iStretchMode <= 0) || (iStretchMode > MAXSTRETCHBLTMODE)) iStretchMode = WHITEONBLACK; pdcattr->jStretchBltMode = iStretchMode; + DC_UnlockDc(pdc); } - DC_UnlockDc(pdc); return oSMode; } diff --git a/win32ss/gdi/ntgdi/freetype.c b/win32ss/gdi/ntgdi/freetype.c index 953b9e4c2be..c30b46b038d 100644 --- a/win32ss/gdi/ntgdi/freetype.c +++ b/win32ss/gdi/ntgdi/freetype.c @@ -3162,8 +3162,8 @@ NtGdiGetFontFamilyInfo(HDC Dc, return Count; } -LONG FORCEINLINE +LONG ScaleLong(LONG lValue, PFLOATOBJ pef) { FLOATOBJ efTemp; @@ -3533,6 +3533,7 @@ GreExtTextOutW( { DPRINT1("Failed to load and render glyph! [index: %d]\n", glyph_index); IntUnLockFreeType; + DC_vFinishBlit(dc, NULL); goto fail2; } glyph = face->glyph; @@ -3546,6 +3547,7 @@ GreExtTextOutW( { DPRINT1("Failed to render glyph! [index: %d]\n", glyph_index); IntUnLockFreeType; + DC_vFinishBlit(dc, NULL); goto fail2; } } @@ -3609,6 +3611,7 @@ GreExtTextOutW( DPRINT1("WARNING: EngLockSurface() failed!\n"); // FT_Done_Glyph(realglyph); IntUnLockFreeType; + DC_vFinishBlit(dc, NULL); goto fail2; } SourceGlyphSurf = EngLockSurface((HSURF)HSourceGlyph); @@ -3617,6 +3620,7 @@ GreExtTextOutW( EngDeleteSurface((HSURF)HSourceGlyph); DPRINT1("WARNING: EngLockSurface() failed!\n"); IntUnLockFreeType; + DC_vFinishBlit(dc, NULL); goto fail2; } diff --git a/win32ss/gdi/ntgdi/palette.h b/win32ss/gdi/ntgdi/palette.h index 8ff54a252c1..3dd16dbb271 100644 --- a/win32ss/gdi/ntgdi/palette.h +++ b/win32ss/gdi/ntgdi/palette.h @@ -121,8 +121,8 @@ BOOL NTAPI PALETTE_Cleanup(PVOID ObjectBody); -ULONG FORCEINLINE +ULONG CalculateShift(ULONG ulMask1, ULONG ulMask2) { ULONG ulShift1, ulShift2; diff --git a/win32ss/gdi/ntgdi/path.c b/win32ss/gdi/ntgdi/path.c index c318bea7652..434518a940b 100644 --- a/win32ss/gdi/ntgdi/path.c +++ b/win32ss/gdi/ntgdi/path.c @@ -32,25 +32,25 @@ */ VOID FASTCALL -PATH_DestroyGdiPath ( PPATH pPath ) +PATH_DestroyGdiPath(PPATH pPath) { - ASSERT(pPath!=NULL); + ASSERT(pPath != NULL); - if (pPath->pPoints) ExFreePoolWithTag(pPath->pPoints, TAG_PATH); - if (pPath->pFlags) ExFreePoolWithTag(pPath->pFlags, TAG_PATH); + if (pPath->pPoints) ExFreePoolWithTag(pPath->pPoints, TAG_PATH); + if (pPath->pFlags) ExFreePoolWithTag(pPath->pFlags, TAG_PATH); } BOOL FASTCALL PATH_Delete(HPATH hPath) { - PPATH pPath; - if (!hPath) return FALSE; - pPath = PATH_LockPath( hPath ); - if (!pPath) return FALSE; - PATH_DestroyGdiPath( pPath ); - GDIOBJ_vDeleteObject(&pPath->BaseObject); - return TRUE; + PPATH pPath; + if (!hPath) return FALSE; + pPath = PATH_LockPath(hPath); + if (!pPath) return FALSE; + PATH_DestroyGdiPath(pPath); + GDIOBJ_vDeleteObject(&pPath->BaseObject); + return TRUE; } @@ -58,27 +58,30 @@ VOID FASTCALL IntGdiCloseFigure(PPATH pPath) { - ASSERT(pPath->state == PATH_Open); + ASSERT(pPath->state == PATH_Open); - // FIXME: Shouldn't we draw a line to the beginning of the figure? - // Set PT_CLOSEFIGURE on the last entry and start a new stroke - if(pPath->numEntriesUsed) - { - pPath->pFlags[pPath->numEntriesUsed-1]|=PT_CLOSEFIGURE; - pPath->newStroke=TRUE; - } + // FIXME: Shouldn't we draw a line to the beginning of the figure? + // Set PT_CLOSEFIGURE on the last entry and start a new stroke + if (pPath->numEntriesUsed) + { + pPath->pFlags[pPath->numEntriesUsed - 1] |= PT_CLOSEFIGURE; + pPath->newStroke = TRUE; + } } /* MSDN: This fails if the device coordinates exceed 27 bits, or if the converted logical coordinates exceed 32 bits. */ BOOL FASTCALL -GdiPathDPtoLP(PDC pdc, PPOINT ppt, INT count) +GdiPathDPtoLP( + PDC pdc, + PPOINT ppt, + INT count) { - XFORMOBJ xo; + XFORMOBJ xo; - XFORMOBJ_vInit(&xo, &pdc->pdcattr->mxDeviceToWorld); - return XFORMOBJ_bApplyXform(&xo, XF_LTOL, count, (PPOINTL)ppt, (PPOINTL)ppt); + XFORMOBJ_vInit(&xo, &pdc->pdcattr->mxDeviceToWorld); + return XFORMOBJ_bApplyXform(&xo, XF_LTOL, count, (PPOINTL)ppt, (PPOINTL)ppt); } /* PATH_FillPath @@ -87,76 +90,78 @@ GdiPathDPtoLP(PDC pdc, PPOINT ppt, INT count) */ BOOL FASTCALL -PATH_FillPath( PDC dc, PPATH pPath ) +PATH_FillPath( + PDC dc, + PPATH pPath) { - //INT mapMode, graphicsMode; - //SIZE ptViewportExt, ptWindowExt; - //POINTL ptViewportOrg, ptWindowOrg; - XFORM xform; - HRGN hrgn; - PDC_ATTR pdcattr = dc->pdcattr; + //INT mapMode, graphicsMode; + //SIZE ptViewportExt, ptWindowExt; + //POINTL ptViewportOrg, ptWindowOrg; + XFORM xform; + HRGN hrgn; + PDC_ATTR pdcattr = dc->pdcattr; - if( pPath->state != PATH_Closed ) - { - EngSetLastError(ERROR_CAN_NOT_COMPLETE); - return FALSE; - } + if (pPath->state != PATH_Closed) + { + EngSetLastError(ERROR_CAN_NOT_COMPLETE); + return FALSE; + } - if( PATH_PathToRegion( pPath, pdcattr->jFillMode, &hrgn )) - { - /* Since PaintRgn interprets the region as being in logical coordinates - * but the points we store for the path are already in device - * coordinates, we have to set the mapping mode to MM_TEXT temporarily. - * Using SaveDC to save information about the mapping mode / world - * transform would be easier but would require more overhead, especially - * now that SaveDC saves the current path. - */ + if (PATH_PathToRegion(pPath, pdcattr->jFillMode, &hrgn)) + { + /* Since PaintRgn interprets the region as being in logical coordinates + * but the points we store for the path are already in device + * coordinates, we have to set the mapping mode to MM_TEXT temporarily. + * Using SaveDC to save information about the mapping mode / world + * transform would be easier but would require more overhead, especially + * now that SaveDC saves the current path. + */ - /* Save the information about the old mapping mode */ - //mapMode = pdcattr->iMapMode; - //ptViewportExt = pdcattr->szlViewportExt; - //ptViewportOrg = pdcattr->ptlViewportOrg; - //ptWindowExt = pdcattr->szlWindowExt; - //ptWindowOrg = pdcattr->ptlWindowOrg; + /* Save the information about the old mapping mode */ + //mapMode = pdcattr->iMapMode; + //ptViewportExt = pdcattr->szlViewportExt; + //ptViewportOrg = pdcattr->ptlViewportOrg; + //ptWindowExt = pdcattr->szlWindowExt; + //ptWindowOrg = pdcattr->ptlWindowOrg; - /* Save world transform - * NB: The Windows documentation on world transforms would lead one to - * believe that this has to be done only in GM_ADVANCED; however, my - * tests show that resetting the graphics mode to GM_COMPATIBLE does - * not reset the world transform. - */ - MatrixS2XForm(&xform, &dc->pdcattr->mxWorldToPage); + /* Save world transform + * NB: The Windows documentation on world transforms would lead one to + * believe that this has to be done only in GM_ADVANCED; however, my + * tests show that resetting the graphics mode to GM_COMPATIBLE does + * not reset the world transform. + */ + MatrixS2XForm(&xform, &dc->pdcattr->mxWorldToPage); - /* Set MM_TEXT */ -// IntGdiSetMapMode( dc, MM_TEXT ); + /* Set MM_TEXT */ +// IntGdiSetMapMode(dc, MM_TEXT); // pdcattr->ptlViewportOrg.x = 0; // pdcattr->ptlViewportOrg.y = 0; // pdcattr->ptlWindowOrg.x = 0; // pdcattr->ptlWindowOrg.y = 0; - // graphicsMode = pdcattr->iGraphicsMode; + // graphicsMode = pdcattr->iGraphicsMode; // pdcattr->iGraphicsMode = GM_ADVANCED; -// IntGdiModifyWorldTransform( dc, &xform, MWT_IDENTITY ); +// IntGdiModifyWorldTransform(dc, &xform, MWT_IDENTITY); // pdcattr->iGraphicsMode = graphicsMode; - /* Paint the region */ - IntGdiPaintRgn( dc, hrgn ); - GreDeleteObject( hrgn ); - /* Restore the old mapping mode */ -// IntGdiSetMapMode( dc, mapMode ); + /* Paint the region */ + IntGdiPaintRgn(dc, hrgn); + GreDeleteObject(hrgn); + /* Restore the old mapping mode */ +// IntGdiSetMapMode(dc, mapMode); // pdcattr->szlViewportExt = ptViewportExt; // pdcattr->ptlViewportOrg = ptViewportOrg; // pdcattr->szlWindowExt = ptWindowExt; // pdcattr->ptlWindowOrg = ptWindowOrg; - /* Go to GM_ADVANCED temporarily to restore the world transform */ - //graphicsMode = pdcattr->iGraphicsMode; + /* Go to GM_ADVANCED temporarily to restore the world transform */ + //graphicsMode = pdcattr->iGraphicsMode; // pdcattr->iGraphicsMode = GM_ADVANCED; -// IntGdiModifyWorldTransform( dc, &xform, MWT_MAX+1 ); +// IntGdiModifyWorldTransform(dc, &xform, MWT_MAX+1); // pdcattr->iGraphicsMode = graphicsMode; - return TRUE; - } - return FALSE; + return TRUE; + } + return FALSE; } /* PATH_InitGdiPath @@ -165,15 +170,16 @@ PATH_FillPath( PDC dc, PPATH pPath ) */ VOID FASTCALL -PATH_InitGdiPath ( PPATH pPath ) +PATH_InitGdiPath( + PPATH pPath) { - ASSERT(pPath!=NULL); + ASSERT(pPath != NULL); - pPath->state=PATH_Null; - pPath->pPoints=NULL; - pPath->pFlags=NULL; - pPath->numEntriesUsed=0; - pPath->numEntriesAllocated=0; + pPath->state = PATH_Null; + pPath->pPoints = NULL; + pPath->pFlags = NULL; + pPath->numEntriesUsed = 0; + pPath->numEntriesAllocated = 0; } /* PATH_AssignGdiPath @@ -188,24 +194,26 @@ PATH_InitGdiPath ( PPATH pPath ) */ BOOL FASTCALL -PATH_AssignGdiPath ( PPATH pPathDest, const PPATH pPathSrc ) +PATH_AssignGdiPath( + PPATH pPathDest, + const PPATH pPathSrc) { - ASSERT(pPathDest!=NULL && pPathSrc!=NULL); + ASSERT(pPathDest != NULL && pPathSrc != NULL); - /* Make sure destination arrays are big enough */ - if ( !PATH_ReserveEntries(pPathDest, pPathSrc->numEntriesUsed) ) - return FALSE; + /* Make sure destination arrays are big enough */ + if (!PATH_ReserveEntries(pPathDest, pPathSrc->numEntriesUsed)) + return FALSE; - /* Perform the copy operation */ - memcpy(pPathDest->pPoints, pPathSrc->pPoints, - sizeof(POINT)*pPathSrc->numEntriesUsed); - memcpy(pPathDest->pFlags, pPathSrc->pFlags, - sizeof(BYTE)*pPathSrc->numEntriesUsed); + /* Perform the copy operation */ + memcpy(pPathDest->pPoints, pPathSrc->pPoints, + sizeof(POINT)*pPathSrc->numEntriesUsed); + memcpy(pPathDest->pFlags, pPathSrc->pFlags, + sizeof(BYTE)*pPathSrc->numEntriesUsed); - pPathDest->state=pPathSrc->state; - pPathDest->numEntriesUsed=pPathSrc->numEntriesUsed; - pPathDest->newStroke=pPathSrc->newStroke; - return TRUE; + pPathDest->state = pPathSrc->state; + pPathDest->numEntriesUsed = pPathSrc->numEntriesUsed; + pPathDest->newStroke = pPathSrc->newStroke; + return TRUE; } /* PATH_MoveTo @@ -216,22 +224,23 @@ PATH_AssignGdiPath ( PPATH pPathDest, const PPATH pPathSrc ) */ BOOL FASTCALL -PATH_MoveTo ( PDC dc ) +PATH_MoveTo( + PDC dc) { - PPATH pPath = PATH_LockPath( dc->dclevel.hPath ); - if (!pPath) return FALSE; + PPATH pPath = PATH_LockPath(dc->dclevel.hPath); + if (!pPath) return FALSE; - /* Check that path is open */ - if ( pPath->state != PATH_Open ) - { - PATH_UnlockPath( pPath ); - /* FIXME: Do we have to call SetLastError? */ - return FALSE; - } - /* Start a new stroke */ - pPath->newStroke = TRUE; - PATH_UnlockPath( pPath ); - return TRUE; + /* Check that path is open */ + if (pPath->state != PATH_Open) + { + PATH_UnlockPath(pPath); + /* FIXME: Do we have to call SetLastError? */ + return FALSE; + } + /* Start a new stroke */ + pPath->newStroke = TRUE; + PATH_UnlockPath(pPath); + return TRUE; } /* PATH_LineTo @@ -243,44 +252,47 @@ PATH_MoveTo ( PDC dc ) */ BOOL FASTCALL -PATH_LineTo ( PDC dc, INT x, INT y ) +PATH_LineTo( + PDC dc, + INT x, + INT y) { - BOOL Ret; - PPATH pPath; - POINT point, pointCurPos; + BOOL Ret; + PPATH pPath; + POINT point, pointCurPos; - pPath = PATH_LockPath( dc->dclevel.hPath ); - if (!pPath) return FALSE; + pPath = PATH_LockPath(dc->dclevel.hPath); + if (!pPath) return FALSE; - /* Check that path is open */ - if ( pPath->state != PATH_Open ) - { - PATH_UnlockPath( pPath ); - return FALSE; - } - - /* Convert point to device coordinates */ - point.x=x; - point.y=y; - CoordLPtoDP ( dc, &point ); - - /* Add a PT_MOVETO if necessary */ - if ( pPath->newStroke ) - { - pPath->newStroke = FALSE; - IntGetCurrentPositionEx ( dc, &pointCurPos ); - CoordLPtoDP ( dc, &pointCurPos ); - if ( !PATH_AddEntry(pPath, &pointCurPos, PT_MOVETO) ) + /* Check that path is open */ + if (pPath->state != PATH_Open) { - PATH_UnlockPath( pPath ); - return FALSE; + PATH_UnlockPath(pPath); + return FALSE; } - } - /* Add a PT_LINETO entry */ - Ret = PATH_AddEntry(pPath, &point, PT_LINETO); - PATH_UnlockPath( pPath ); - return Ret; + /* Convert point to device coordinates */ + point.x = x; + point.y = y; + CoordLPtoDP(dc, &point); + + /* Add a PT_MOVETO if necessary */ + if (pPath->newStroke) + { + pPath->newStroke = FALSE; + IntGetCurrentPositionEx(dc, &pointCurPos); + CoordLPtoDP(dc, &pointCurPos); + if (!PATH_AddEntry(pPath, &pointCurPos, PT_MOVETO)) + { + PATH_UnlockPath(pPath); + return FALSE; + } + } + + /* Add a PT_LINETO entry */ + Ret = PATH_AddEntry(pPath, &point, PT_LINETO); + PATH_UnlockPath(pPath); + return Ret; } /* PATH_Rectangle @@ -290,83 +302,88 @@ PATH_LineTo ( PDC dc, INT x, INT y ) */ BOOL FASTCALL -PATH_Rectangle ( PDC dc, INT x1, INT y1, INT x2, INT y2 ) +PATH_Rectangle( + PDC dc, + INT x1, + INT y1, + INT x2, + INT y2) { - PPATH pPath; - POINT corners[2], pointTemp; - INT temp; + PPATH pPath; + POINT corners[2], pointTemp; + INT temp; - pPath = PATH_LockPath( dc->dclevel.hPath ); - if (!pPath) return FALSE; + pPath = PATH_LockPath(dc->dclevel.hPath); + if (!pPath) return FALSE; - /* Check that path is open */ - if ( pPath->state != PATH_Open ) - { - PATH_UnlockPath( pPath ); - return FALSE; - } + /* Check that path is open */ + if (pPath->state != PATH_Open) + { + PATH_UnlockPath(pPath); + return FALSE; + } - /* Convert points to device coordinates */ - corners[0].x=x1; - corners[0].y=y1; - corners[1].x=x2; - corners[1].y=y2; - IntLPtoDP ( dc, corners, 2 ); + /* Convert points to device coordinates */ + corners[0].x = x1; + corners[0].y = y1; + corners[1].x = x2; + corners[1].y = y2; + IntLPtoDP(dc, corners, 2); - /* Make sure first corner is top left and second corner is bottom right */ - if ( corners[0].x > corners[1].x ) - { - temp=corners[0].x; - corners[0].x=corners[1].x; - corners[1].x=temp; - } - if ( corners[0].y > corners[1].y ) - { - temp=corners[0].y; - corners[0].y=corners[1].y; - corners[1].y=temp; - } + /* Make sure first corner is top left and second corner is bottom right */ + if (corners[0].x > corners[1].x) + { + temp = corners[0].x; + corners[0].x = corners[1].x; + corners[1].x = temp; + } + if (corners[0].y > corners[1].y) + { + temp = corners[0].y; + corners[0].y = corners[1].y; + corners[1].y = temp; + } - /* In GM_COMPATIBLE, don't include bottom and right edges */ - if (dc->pdcattr->iGraphicsMode == GM_COMPATIBLE) - { - corners[1].x--; - corners[1].y--; - } + /* In GM_COMPATIBLE, don't include bottom and right edges */ + if (dc->pdcattr->iGraphicsMode == GM_COMPATIBLE) + { + corners[1].x--; + corners[1].y--; + } - /* Close any previous figure */ - IntGdiCloseFigure(pPath); + /* Close any previous figure */ + IntGdiCloseFigure(pPath); - /* Add four points to the path */ - pointTemp.x=corners[1].x; - pointTemp.y=corners[0].y; - if ( !PATH_AddEntry(pPath, &pointTemp, PT_MOVETO) ) - { - PATH_UnlockPath( pPath ); - return FALSE; - } - if ( !PATH_AddEntry(pPath, corners, PT_LINETO) ) - { - PATH_UnlockPath( pPath ); - return FALSE; - } - pointTemp.x=corners[0].x; - pointTemp.y=corners[1].y; - if ( !PATH_AddEntry(pPath, &pointTemp, PT_LINETO) ) - { - PATH_UnlockPath( pPath ); - return FALSE; - } - if ( !PATH_AddEntry(pPath, corners+1, PT_LINETO) ) - { - PATH_UnlockPath( pPath ); - return FALSE; - } + /* Add four points to the path */ + pointTemp.x = corners[1].x; + pointTemp.y = corners[0].y; + if (!PATH_AddEntry(pPath, &pointTemp, PT_MOVETO)) + { + PATH_UnlockPath(pPath); + return FALSE; + } + if (!PATH_AddEntry(pPath, corners, PT_LINETO)) + { + PATH_UnlockPath(pPath); + return FALSE; + } + pointTemp.x = corners[0].x; + pointTemp.y = corners[1].y; + if (!PATH_AddEntry(pPath, &pointTemp, PT_LINETO)) + { + PATH_UnlockPath(pPath); + return FALSE; + } + if (!PATH_AddEntry(pPath, corners + 1, PT_LINETO)) + { + PATH_UnlockPath(pPath); + return FALSE; + } - /* Close the rectangle figure */ - IntGdiCloseFigure(pPath) ; - PATH_UnlockPath( pPath ); - return TRUE; + /* Close the rectangle figure */ + IntGdiCloseFigure(pPath) ; + PATH_UnlockPath(pPath); + return TRUE; } /* PATH_RoundRect @@ -378,84 +395,93 @@ PATH_Rectangle ( PDC dc, INT x1, INT y1, INT x2, INT y2 ) * is an error in the bezier drawing code so that there are small pixel-size * gaps when the resulting path is drawn by StrokePath() */ -BOOL FASTCALL PATH_RoundRect(DC *dc, INT x1, INT y1, INT x2, INT y2, INT ell_width, INT ell_height) +BOOL +FASTCALL +PATH_RoundRect( + DC *dc, + INT x1, + INT y1, + INT x2, + INT y2, + INT ell_width, + INT ell_height) { - PPATH pPath; - POINT corners[2], pointTemp; - FLOAT_POINT ellCorners[2]; + PPATH pPath; + POINT corners[2], pointTemp; + FLOAT_POINT ellCorners[2]; - pPath = PATH_LockPath( dc->dclevel.hPath ); - if (!pPath) return FALSE; + pPath = PATH_LockPath(dc->dclevel.hPath); + if (!pPath) return FALSE; - /* Check that path is open */ - if(pPath->state!=PATH_Open) - { - PATH_UnlockPath( pPath ); - return FALSE; - } + /* Check that path is open */ + if (pPath->state != PATH_Open) + { + PATH_UnlockPath(pPath); + return FALSE; + } - if(!PATH_CheckCorners(dc,corners,x1,y1,x2,y2)) - { - PATH_UnlockPath( pPath ); - return FALSE; - } + if (!PATH_CheckCorners(dc, corners, x1, y1, x2, y2)) + { + PATH_UnlockPath(pPath); + return FALSE; + } - /* Add points to the roundrect path */ - ellCorners[0].x = corners[1].x-ell_width; - ellCorners[0].y = corners[0].y; - ellCorners[1].x = corners[1].x; - ellCorners[1].y = corners[0].y+ell_height; - if(!PATH_DoArcPart(pPath, ellCorners, 0, -M_PI_2, PT_MOVETO)) - { - PATH_UnlockPath( pPath ); - return FALSE; - } - pointTemp.x = corners[0].x+ell_width/2; - pointTemp.y = corners[0].y; - if(!PATH_AddEntry(pPath, &pointTemp, PT_LINETO)) - { - PATH_UnlockPath( pPath ); - return FALSE; - } - ellCorners[0].x = corners[0].x; - ellCorners[1].x = corners[0].x+ell_width; - if(!PATH_DoArcPart(pPath, ellCorners, -M_PI_2, -M_PI, FALSE)) - { - PATH_UnlockPath( pPath ); - return FALSE; - } - pointTemp.x = corners[0].x; - pointTemp.y = corners[1].y-ell_height/2; - if(!PATH_AddEntry(pPath, &pointTemp, PT_LINETO)) - { - PATH_UnlockPath( pPath ); - return FALSE; - } - ellCorners[0].y = corners[1].y-ell_height; - ellCorners[1].y = corners[1].y; - if(!PATH_DoArcPart(pPath, ellCorners, M_PI, M_PI_2, FALSE)) - { - PATH_UnlockPath( pPath ); - return FALSE; - } - pointTemp.x = corners[1].x-ell_width/2; - pointTemp.y = corners[1].y; - if(!PATH_AddEntry(pPath, &pointTemp, PT_LINETO)) - { - PATH_UnlockPath( pPath ); - return FALSE; - } - ellCorners[0].x = corners[1].x-ell_width; - ellCorners[1].x = corners[1].x; - if(!PATH_DoArcPart(pPath, ellCorners, M_PI_2, 0, FALSE)) - { - PATH_UnlockPath( pPath ); - return FALSE; - } + /* Add points to the roundrect path */ + ellCorners[0].x = corners[1].x - ell_width; + ellCorners[0].y = corners[0].y; + ellCorners[1].x = corners[1].x; + ellCorners[1].y = corners[0].y + ell_height; + if (!PATH_DoArcPart(pPath, ellCorners, 0, -M_PI_2, PT_MOVETO)) + { + PATH_UnlockPath(pPath); + return FALSE; + } + pointTemp.x = corners[0].x + ell_width / 2; + pointTemp.y = corners[0].y; + if (!PATH_AddEntry(pPath, &pointTemp, PT_LINETO)) + { + PATH_UnlockPath(pPath); + return FALSE; + } + ellCorners[0].x = corners[0].x; + ellCorners[1].x = corners[0].x + ell_width; + if (!PATH_DoArcPart(pPath, ellCorners, -M_PI_2, -M_PI, FALSE)) + { + PATH_UnlockPath(pPath); + return FALSE; + } + pointTemp.x = corners[0].x; + pointTemp.y = corners[1].y - ell_height / 2; + if (!PATH_AddEntry(pPath, &pointTemp, PT_LINETO)) + { + PATH_UnlockPath(pPath); + return FALSE; + } + ellCorners[0].y = corners[1].y - ell_height; + ellCorners[1].y = corners[1].y; + if (!PATH_DoArcPart(pPath, ellCorners, M_PI, M_PI_2, FALSE)) + { + PATH_UnlockPath(pPath); + return FALSE; + } + pointTemp.x = corners[1].x - ell_width / 2; + pointTemp.y = corners[1].y; + if (!PATH_AddEntry(pPath, &pointTemp, PT_LINETO)) + { + PATH_UnlockPath(pPath); + return FALSE; + } + ellCorners[0].x = corners[1].x - ell_width; + ellCorners[1].x = corners[1].x; + if (!PATH_DoArcPart(pPath, ellCorners, M_PI_2, 0, FALSE)) + { + PATH_UnlockPath(pPath); + return FALSE; + } - IntGdiCloseFigure(pPath); - PATH_UnlockPath( pPath ); - return TRUE; + IntGdiCloseFigure(pPath); + PATH_UnlockPath(pPath); + return TRUE; } /* PATH_Ellipse @@ -466,20 +492,25 @@ BOOL FASTCALL PATH_RoundRect(DC *dc, INT x1, INT y1, INT x2, INT y2, INT ell_wid */ BOOL FASTCALL -PATH_Ellipse ( PDC dc, INT x1, INT y1, INT x2, INT y2 ) +PATH_Ellipse( + PDC dc, + INT x1, + INT y1, + INT x2, + INT y2) { - PPATH pPath; - /* TODO: This should probably be revised to call PATH_AngleArc */ - /* (once it exists) */ - BOOL Ret = PATH_Arc ( dc, x1, y1, x2, y2, x1, (y1+y2)/2, x1, (y1+y2)/2, GdiTypeArc ); - if (Ret) - { - pPath = PATH_LockPath( dc->dclevel.hPath ); - if (!pPath) return FALSE; - IntGdiCloseFigure(pPath); - PATH_UnlockPath( pPath ); - } - return Ret; + PPATH pPath; + /* TODO: This should probably be revised to call PATH_AngleArc */ + /* (once it exists) */ + BOOL Ret = PATH_Arc(dc, x1, y1, x2, y2, x1, (y1 + y2) / 2, x1, (y1 + y2) / 2, GdiTypeArc); + if (Ret) + { + pPath = PATH_LockPath(dc->dclevel.hPath); + if (!pPath) return FALSE; + IntGdiCloseFigure(pPath); + PATH_UnlockPath(pPath); + } + return Ret; } /* PATH_Arc @@ -494,532 +525,577 @@ PATH_Ellipse ( PDC dc, INT x1, INT y1, INT x2, INT y2 ) */ BOOL FASTCALL -PATH_Arc ( PDC dc, INT x1, INT y1, INT x2, INT y2, - INT xStart, INT yStart, INT xEnd, INT yEnd, INT lines) +PATH_Arc( + PDC dc, + INT x1, + INT y1, + INT x2, + INT y2, + INT xStart, + INT yStart, + INT xEnd, + INT yEnd, + INT lines) { - double angleStart, angleEnd, angleStartQuadrant, angleEndQuadrant=0.0; - /* Initialize angleEndQuadrant to silence gcc's warning */ - double x, y; - FLOAT_POINT corners[2], pointStart, pointEnd; - POINT centre, pointCurPos; - BOOL start, end, Ret = TRUE; - INT temp; - BOOL clockwise; - PPATH pPath; + double angleStart, angleEnd, angleStartQuadrant, angleEndQuadrant = 0.0; + /* Initialize angleEndQuadrant to silence gcc's warning */ + double x, y; + FLOAT_POINT corners[2], pointStart, pointEnd; + POINT centre, pointCurPos; + BOOL start, end, Ret = TRUE; + INT temp; + BOOL clockwise; + PPATH pPath; - /* FIXME: This function should check for all possible error returns */ - /* FIXME: Do we have to respect newStroke? */ + /* FIXME: This function should check for all possible error returns */ + /* FIXME: Do we have to respect newStroke? */ - ASSERT ( dc ); + ASSERT(dc); - pPath = PATH_LockPath( dc->dclevel.hPath ); - if (!pPath) return FALSE; + pPath = PATH_LockPath(dc->dclevel.hPath); + if (!pPath) return FALSE; - clockwise = ((dc->dclevel.flPath & DCPATH_CLOCKWISE) != 0); + clockwise = ((dc->dclevel.flPath & DCPATH_CLOCKWISE) != 0); - /* Check that path is open */ - if ( pPath->state != PATH_Open ) - { - Ret = FALSE; - goto ArcExit; - } - - /* Check for zero height / width */ - /* FIXME: Only in GM_COMPATIBLE? */ - if ( x1==x2 || y1==y2 ) - { - Ret = TRUE; - goto ArcExit; - } - /* Convert points to device coordinates */ - corners[0].x=(FLOAT)x1; - corners[0].y=(FLOAT)y1; - corners[1].x=(FLOAT)x2; - corners[1].y=(FLOAT)y2; - pointStart.x=(FLOAT)xStart; - pointStart.y=(FLOAT)yStart; - pointEnd.x=(FLOAT)xEnd; - pointEnd.y=(FLOAT)yEnd; - INTERNAL_LPTODP_FLOAT(dc, corners); - INTERNAL_LPTODP_FLOAT(dc, corners+1); - INTERNAL_LPTODP_FLOAT(dc, &pointStart); - INTERNAL_LPTODP_FLOAT(dc, &pointEnd); - - /* Make sure first corner is top left and second corner is bottom right */ - if ( corners[0].x > corners[1].x ) - { - temp=corners[0].x; - corners[0].x=corners[1].x; - corners[1].x=temp; - } - if ( corners[0].y > corners[1].y ) - { - temp=corners[0].y; - corners[0].y=corners[1].y; - corners[1].y=temp; - } - - /* Compute start and end angle */ - PATH_NormalizePoint(corners, &pointStart, &x, &y); - angleStart=atan2(y, x); - PATH_NormalizePoint(corners, &pointEnd, &x, &y); - angleEnd=atan2(y, x); - - /* Make sure the end angle is "on the right side" of the start angle */ - if ( clockwise ) - { - if ( angleEnd <= angleStart ) + /* Check that path is open */ + if (pPath->state != PATH_Open) { - angleEnd+=2*M_PI; - ASSERT(angleEnd>=angleStart); + Ret = FALSE; + goto ArcExit; } - } - else - { - if(angleEnd>=angleStart) + + /* Check for zero height / width */ + /* FIXME: Only in GM_COMPATIBLE? */ + if (x1 == x2 || y1 == y2) { - angleEnd-=2*M_PI; - ASSERT(angleEnd<=angleStart); + Ret = TRUE; + goto ArcExit; } - } + /* Convert points to device coordinates */ + corners[0].x = (FLOAT)x1; + corners[0].y = (FLOAT)y1; + corners[1].x = (FLOAT)x2; + corners[1].y = (FLOAT)y2; + pointStart.x = (FLOAT)xStart; + pointStart.y = (FLOAT)yStart; + pointEnd.x = (FLOAT)xEnd; + pointEnd.y = (FLOAT)yEnd; + INTERNAL_LPTODP_FLOAT(dc, corners); + INTERNAL_LPTODP_FLOAT(dc, corners + 1); + INTERNAL_LPTODP_FLOAT(dc, &pointStart); + INTERNAL_LPTODP_FLOAT(dc, &pointEnd); - /* In GM_COMPATIBLE, don't include bottom and right edges */ - if (dc->pdcattr->iGraphicsMode == GM_COMPATIBLE ) - { - corners[1].x--; - corners[1].y--; - } - - /* arcto: Add a PT_MOVETO only if this is the first entry in a stroke */ - if(lines==GdiTypeArcTo && pPath->newStroke) // -1 - { - pPath->newStroke=FALSE; - IntGetCurrentPositionEx ( dc, &pointCurPos ); - CoordLPtoDP(dc, &pointCurPos); - if(!PATH_AddEntry(pPath, &pointCurPos, PT_MOVETO)) - { - Ret = FALSE; - goto ArcExit; - } - } - - /* Add the arc to the path with one Bezier spline per quadrant that the - * arc spans */ - start=TRUE; - end=FALSE; - do - { - /* Determine the start and end angles for this quadrant */ - if(start) + /* Make sure first corner is top left and second corner is bottom right */ + if (corners[0].x > corners[1].x) { - angleStartQuadrant=angleStart; - if ( clockwise ) - angleEndQuadrant=(floor(angleStart/M_PI_2)+1.0)*M_PI_2; - else - angleEndQuadrant=(ceil(angleStart/M_PI_2)-1.0)*M_PI_2; + temp = corners[0].x; + corners[0].x = corners[1].x; + corners[1].x = temp; + } + if (corners[0].y > corners[1].y) + { + temp = corners[0].y; + corners[0].y = corners[1].y; + corners[1].y = temp; + } + + /* Compute start and end angle */ + PATH_NormalizePoint(corners, &pointStart, &x, &y); + angleStart = atan2(y, x); + PATH_NormalizePoint(corners, &pointEnd, &x, &y); + angleEnd = atan2(y, x); + + /* Make sure the end angle is "on the right side" of the start angle */ + if (clockwise) + { + if (angleEnd <= angleStart) + { + angleEnd += 2 * M_PI; + ASSERT(angleEnd >= angleStart); + } } else { - angleStartQuadrant=angleEndQuadrant; - if ( clockwise ) - angleEndQuadrant+=M_PI_2; - else - angleEndQuadrant-=M_PI_2; + if (angleEnd >= angleStart) + { + angleEnd -= 2 * M_PI; + ASSERT(angleEnd <= angleStart); + } } - /* Have we reached the last part of the arc? */ - if ( (clockwise && angleEndangleEndQuadrant) - ) + /* In GM_COMPATIBLE, don't include bottom and right edges */ + if (dc->pdcattr->iGraphicsMode == GM_COMPATIBLE) { - /* Adjust the end angle for this quadrant */ - angleEndQuadrant = angleEnd; - end = TRUE; + corners[1].x--; + corners[1].y--; } - /* Add the Bezier spline to the path */ - PATH_DoArcPart ( pPath, corners, angleStartQuadrant, angleEndQuadrant, - start ? (lines==GdiTypeArcTo ? PT_LINETO : PT_MOVETO) : FALSE ); // -1 - start = FALSE; - } while(!end); + /* arcto: Add a PT_MOVETO only if this is the first entry in a stroke */ + if (lines == GdiTypeArcTo && pPath->newStroke) // -1 + { + pPath->newStroke = FALSE; + IntGetCurrentPositionEx(dc, &pointCurPos); + CoordLPtoDP(dc, &pointCurPos); + if (!PATH_AddEntry(pPath, &pointCurPos, PT_MOVETO)) + { + Ret = FALSE; + goto ArcExit; + } + } - /* chord: close figure. pie: add line and close figure */ - if (lines==GdiTypeChord) // 1 - { - IntGdiCloseFigure(pPath); - } - else if (lines==GdiTypePie) // 2 - { - centre.x = (corners[0].x+corners[1].x)/2; - centre.y = (corners[0].y+corners[1].y)/2; - if(!PATH_AddEntry(pPath, ¢re, PT_LINETO | PT_CLOSEFIGURE)) - Ret = FALSE; - } + /* Add the arc to the path with one Bezier spline per quadrant that the + * arc spans */ + start = TRUE; + end = FALSE; + do + { + /* Determine the start and end angles for this quadrant */ + if (start) + { + angleStartQuadrant = angleStart; + if (clockwise) + angleEndQuadrant = (floor(angleStart / M_PI_2) + 1.0) * M_PI_2; + else + angleEndQuadrant = (ceil(angleStart / M_PI_2) - 1.0) * M_PI_2; + } + else + { + angleStartQuadrant = angleEndQuadrant; + if (clockwise) + angleEndQuadrant += M_PI_2; + else + angleEndQuadrant -= M_PI_2; + } + + /* Have we reached the last part of the arc? */ + if ((clockwise && angleEnd < angleEndQuadrant) || + (!clockwise && angleEnd > angleEndQuadrant)) + { + /* Adjust the end angle for this quadrant */ + angleEndQuadrant = angleEnd; + end = TRUE; + } + + /* Add the Bezier spline to the path */ + PATH_DoArcPart(pPath, + corners, + angleStartQuadrant, + angleEndQuadrant, + start ? (lines == GdiTypeArcTo ? PT_LINETO : PT_MOVETO) : FALSE); // -1 + start = FALSE; + } + while (!end); + + /* chord: close figure. pie: add line and close figure */ + if (lines == GdiTypeChord) // 1 + { + IntGdiCloseFigure(pPath); + } + else if (lines == GdiTypePie) // 2 + { + centre.x = (corners[0].x + corners[1].x) / 2; + centre.y = (corners[0].y + corners[1].y) / 2; + if (!PATH_AddEntry(pPath, ¢re, PT_LINETO | PT_CLOSEFIGURE)) + Ret = FALSE; + } ArcExit: - PATH_UnlockPath( pPath ); - return Ret; + PATH_UnlockPath(pPath); + return Ret; } BOOL FASTCALL -PATH_PolyBezierTo ( PDC dc, const POINT *pts, DWORD cbPoints ) +PATH_PolyBezierTo( + PDC dc, + const POINT *pts, + DWORD cbPoints) { - POINT pt; - ULONG i; - PPATH pPath; + POINT pt; + ULONG i; + PPATH pPath; - ASSERT ( dc ); - ASSERT ( pts ); - ASSERT ( cbPoints ); + ASSERT(dc); + ASSERT(pts); + ASSERT(cbPoints); - pPath = PATH_LockPath( dc->dclevel.hPath ); - if (!pPath) return FALSE; + pPath = PATH_LockPath(dc->dclevel.hPath); + if (!pPath) return FALSE; - /* Check that path is open */ - if ( pPath->state != PATH_Open ) - { - PATH_UnlockPath( pPath ); - return FALSE; - } - - /* Add a PT_MOVETO if necessary */ - if ( pPath->newStroke ) - { - pPath->newStroke=FALSE; - IntGetCurrentPositionEx ( dc, &pt ); - CoordLPtoDP ( dc, &pt ); - if ( !PATH_AddEntry(pPath, &pt, PT_MOVETO) ) + /* Check that path is open */ + if (pPath->state != PATH_Open) { - PATH_UnlockPath( pPath ); + PATH_UnlockPath(pPath); return FALSE; } - } - for(i = 0; i < cbPoints; i++) - { - pt = pts[i]; - CoordLPtoDP ( dc, &pt ); - PATH_AddEntry(pPath, &pt, PT_BEZIERTO); - } - PATH_UnlockPath( pPath ); - return TRUE; -} - -BOOL -FASTCALL -PATH_PolyBezier ( PDC dc, const POINT *pts, DWORD cbPoints ) -{ - POINT pt; - ULONG i; - PPATH pPath; - - ASSERT ( dc ); - ASSERT ( pts ); - ASSERT ( cbPoints ); - - pPath = PATH_LockPath( dc->dclevel.hPath ); - if (!pPath) return FALSE; - - /* Check that path is open */ - if ( pPath->state != PATH_Open ) - { - PATH_UnlockPath( pPath ); - return FALSE; - } - - for ( i = 0; i < cbPoints; i++ ) - { - pt = pts[i]; - CoordLPtoDP ( dc, &pt ); - PATH_AddEntry ( pPath, &pt, (i == 0) ? PT_MOVETO : PT_BEZIERTO ); - } - PATH_UnlockPath( pPath ); - return TRUE; -} - -BOOL -FASTCALL -PATH_PolyDraw(PDC dc, const POINT *pts, const BYTE *types, DWORD cbPoints) -{ - PPATH pPath; - POINT lastmove, orig_pos; - ULONG i; - PDC_ATTR pdcattr; - BOOL State = FALSE, Ret = FALSE; - - pPath = PATH_LockPath( dc->dclevel.hPath ); - if (!pPath) return FALSE; - - if ( pPath->state != PATH_Open ) - { - PATH_UnlockPath( pPath ); - return FALSE; - } - - pdcattr = dc->pdcattr; - - lastmove.x = orig_pos.x = pdcattr->ptlCurrent.x; - lastmove.y = orig_pos.y = pdcattr->ptlCurrent.y; - - i = pPath->numEntriesUsed; - - while (i != 0) - { - i--; - if (pPath->pFlags[i] == PT_MOVETO) - { - lastmove.x = pPath->pPoints[i].x; - lastmove.y = pPath->pPoints[i].y; - if (!GdiPathDPtoLP(dc, &lastmove, 1)) - { - PATH_UnlockPath( pPath ); + /* Add a PT_MOVETO if necessary */ + if (pPath->newStroke) + { + pPath->newStroke = FALSE; + IntGetCurrentPositionEx(dc, &pt); + CoordLPtoDP(dc, &pt); + if (!PATH_AddEntry(pPath, &pt, PT_MOVETO)) + { + PATH_UnlockPath(pPath); return FALSE; - } - break; - } - } + } + } - for (i = 0; i < cbPoints; i++) - { - if (types[i] == PT_MOVETO) - { - pPath->newStroke = TRUE; - lastmove.x = pts[i].x; - lastmove.y = pts[i].y; - } - else if((types[i] & ~PT_CLOSEFIGURE) == PT_LINETO) - { - PATH_LineTo(dc, pts[i].x, pts[i].y); - } - else if(types[i] == PT_BEZIERTO) - { - if (!((i + 2 < cbPoints) && (types[i + 1] == PT_BEZIERTO) - && ((types[i + 2] & ~PT_CLOSEFIGURE) == PT_BEZIERTO))) - goto err; - PATH_PolyBezierTo(dc, &(pts[i]), 3); - i += 2; - } - else - goto err; + for (i = 0; i < cbPoints; i++) + { + pt = pts[i]; + CoordLPtoDP(dc, &pt); + PATH_AddEntry(pPath, &pt, PT_BEZIERTO); + } - pdcattr->ptlCurrent.x = pts[i].x; - pdcattr->ptlCurrent.y = pts[i].y; - State = TRUE; + PATH_UnlockPath(pPath); + return TRUE; +} - if (types[i] & PT_CLOSEFIGURE) - { - pPath->pFlags[pPath->numEntriesUsed-1] |= PT_CLOSEFIGURE; - pPath->newStroke = TRUE; - pdcattr->ptlCurrent.x = lastmove.x; - pdcattr->ptlCurrent.y = lastmove.y; +BOOL +FASTCALL +PATH_PolyBezier( + PDC dc, + const POINT *pts, + DWORD cbPoints) +{ + POINT pt; + ULONG i; + PPATH pPath; + + ASSERT(dc); + ASSERT(pts); + ASSERT(cbPoints); + + pPath = PATH_LockPath(dc->dclevel.hPath); + if (!pPath) return FALSE; + + /* Check that path is open */ + if (pPath->state != PATH_Open) + { + PATH_UnlockPath(pPath); + return FALSE; + } + + for (i = 0; i < cbPoints; i++) + { + pt = pts[i]; + CoordLPtoDP(dc, &pt); + PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO : PT_BEZIERTO); + } + + PATH_UnlockPath(pPath); + return TRUE; +} + +BOOL +FASTCALL +PATH_PolyDraw( + PDC dc, + const POINT *pts, + const BYTE *types, + DWORD cbPoints) +{ + PPATH pPath; + POINT lastmove, orig_pos; + ULONG i; + PDC_ATTR pdcattr; + BOOL State = FALSE, Ret = FALSE; + + pPath = PATH_LockPath(dc->dclevel.hPath); + if (!pPath) return FALSE; + + if (pPath->state != PATH_Open) + { + PATH_UnlockPath(pPath); + return FALSE; + } + + pdcattr = dc->pdcattr; + + lastmove.x = orig_pos.x = pdcattr->ptlCurrent.x; + lastmove.y = orig_pos.y = pdcattr->ptlCurrent.y; + + i = pPath->numEntriesUsed; + + while (i != 0) + { + i--; + if (pPath->pFlags[i] == PT_MOVETO) + { + lastmove.x = pPath->pPoints[i].x; + lastmove.y = pPath->pPoints[i].y; + if (!GdiPathDPtoLP(dc, &lastmove, 1)) + { + PATH_UnlockPath(pPath); + return FALSE; + } + break; + } + } + + for (i = 0; i < cbPoints; i++) + { + if (types[i] == PT_MOVETO) + { + pPath->newStroke = TRUE; + lastmove.x = pts[i].x; + lastmove.y = pts[i].y; + } + else if ((types[i] & ~PT_CLOSEFIGURE) == PT_LINETO) + { + PATH_LineTo(dc, pts[i].x, pts[i].y); + } + else if (types[i] == PT_BEZIERTO) + { + if (!((i + 2 < cbPoints) && (types[i + 1] == PT_BEZIERTO) + && ((types[i + 2] & ~PT_CLOSEFIGURE) == PT_BEZIERTO))) + goto err; + PATH_PolyBezierTo(dc, &(pts[i]), 3); + i += 2; + } + else + goto err; + + pdcattr->ptlCurrent.x = pts[i].x; + pdcattr->ptlCurrent.y = pts[i].y; State = TRUE; - } - } - Ret = TRUE; - goto Exit; + + if (types[i] & PT_CLOSEFIGURE) + { + pPath->pFlags[pPath->numEntriesUsed - 1] |= PT_CLOSEFIGURE; + pPath->newStroke = TRUE; + pdcattr->ptlCurrent.x = lastmove.x; + pdcattr->ptlCurrent.y = lastmove.y; + State = TRUE; + } + } + Ret = TRUE; + goto Exit; err: - if ((pdcattr->ptlCurrent.x != orig_pos.x) || (pdcattr->ptlCurrent.y != orig_pos.y)) - { - pPath->newStroke = TRUE; - pdcattr->ptlCurrent.x = orig_pos.x; - pdcattr->ptlCurrent.y = orig_pos.y; - State = TRUE; - } + if ((pdcattr->ptlCurrent.x != orig_pos.x) || (pdcattr->ptlCurrent.y != orig_pos.y)) + { + pPath->newStroke = TRUE; + pdcattr->ptlCurrent.x = orig_pos.x; + pdcattr->ptlCurrent.y = orig_pos.y; + State = TRUE; + } Exit: - if (State) // State change? - { - pdcattr->ptfxCurrent = pdcattr->ptlCurrent; - CoordLPtoDP(dc, &pdcattr->ptfxCurrent); // Update fx - pdcattr->ulDirty_ &= ~(DIRTY_PTLCURRENT|DIRTY_PTFXCURRENT|DIRTY_STYLESTATE); - } - PATH_UnlockPath( pPath ); - return Ret; -} - -BOOL -FASTCALL -PATH_Polyline ( PDC dc, const POINT *pts, DWORD cbPoints ) -{ - POINT pt; - ULONG i; - PPATH pPath; - - ASSERT ( dc ); - ASSERT ( pts ); - ASSERT ( cbPoints ); - - pPath = PATH_LockPath( dc->dclevel.hPath ); - if (!pPath) return FALSE; - - /* Check that path is open */ - if ( pPath->state != PATH_Open ) - { - PATH_UnlockPath( pPath ); - return FALSE; - } - for ( i = 0; i < cbPoints; i++ ) - { - pt = pts[i]; - CoordLPtoDP ( dc, &pt ); - PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO : PT_LINETO); - } - PATH_UnlockPath( pPath ); - return TRUE; -} - -BOOL -FASTCALL -PATH_PolylineTo ( PDC dc, const POINT *pts, DWORD cbPoints ) -{ - POINT pt; - ULONG i; - PPATH pPath; - - ASSERT ( dc ); - ASSERT ( pts ); - ASSERT ( cbPoints ); - - pPath = PATH_LockPath( dc->dclevel.hPath ); - if (!pPath) return FALSE; - - /* Check that path is open */ - if ( pPath->state != PATH_Open ) - { - PATH_UnlockPath( pPath ); - return FALSE; - } - - /* Add a PT_MOVETO if necessary */ - if ( pPath->newStroke ) - { - pPath->newStroke = FALSE; - IntGetCurrentPositionEx ( dc, &pt ); - CoordLPtoDP ( dc, &pt ); - if ( !PATH_AddEntry(pPath, &pt, PT_MOVETO) ) + if (State) // State change? { - PATH_UnlockPath( pPath ); - return FALSE; + pdcattr->ptfxCurrent = pdcattr->ptlCurrent; + CoordLPtoDP(dc, &pdcattr->ptfxCurrent); // Update fx + pdcattr->ulDirty_ &= ~(DIRTY_PTLCURRENT | DIRTY_PTFXCURRENT | DIRTY_STYLESTATE); } - } - - for(i = 0; i < cbPoints; i++) - { - pt = pts[i]; - CoordLPtoDP ( dc, &pt ); - PATH_AddEntry(pPath, &pt, PT_LINETO); - } - PATH_UnlockPath( pPath ); - return TRUE; -} - - -BOOL -FASTCALL -PATH_Polygon ( PDC dc, const POINT *pts, DWORD cbPoints ) -{ - POINT pt; - ULONG i; - PPATH pPath; - - ASSERT ( dc ); - ASSERT ( pts ); - - pPath = PATH_LockPath( dc->dclevel.hPath ); - if (!pPath) return FALSE; - - /* Check that path is open */ - if ( pPath->state != PATH_Open ) - { - PATH_UnlockPath( pPath ); - return FALSE; - } - - for(i = 0; i < cbPoints; i++) - { - pt = pts[i]; - CoordLPtoDP ( dc, &pt ); - PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO : - ((i == cbPoints-1) ? PT_LINETO | PT_CLOSEFIGURE : - PT_LINETO)); - } - PATH_UnlockPath( pPath ); - return TRUE; + PATH_UnlockPath(pPath); + return Ret; } BOOL FASTCALL -PATH_PolyPolygon ( PDC dc, const POINT* pts, const INT* counts, UINT polygons ) +PATH_Polyline( + PDC dc, + const POINT *pts, + DWORD cbPoints) { - POINT pt, startpt; - ULONG poly, point, i; - PPATH pPath; + POINT pt; + ULONG i; + PPATH pPath; - ASSERT ( dc ); - ASSERT ( pts ); - ASSERT ( counts ); - ASSERT ( polygons ); + ASSERT(dc); + ASSERT(pts); + ASSERT(cbPoints); - pPath = PATH_LockPath( dc->dclevel.hPath ); - if (!pPath) return FALSE; + pPath = PATH_LockPath(dc->dclevel.hPath); + if (!pPath) return FALSE; - /* Check that path is open */ - if ( pPath->state != PATH_Open ) - { - PATH_UnlockPath( pPath ); - return FALSE; - } - - for(i = 0, poly = 0; poly < polygons; poly++) - { - for(point = 0; point < (ULONG) counts[poly]; point++, i++) + /* Check that path is open */ + if (pPath->state != PATH_Open) { - pt = pts[i]; - CoordLPtoDP ( dc, &pt ); - if(point == 0) startpt = pt; - PATH_AddEntry(pPath, &pt, (point == 0) ? PT_MOVETO : PT_LINETO); + PATH_UnlockPath(pPath); + return FALSE; } - /* Win98 adds an extra line to close the figure for some reason */ - PATH_AddEntry(pPath, &startpt, PT_LINETO | PT_CLOSEFIGURE); - } - PATH_UnlockPath( pPath ); - return TRUE; + for (i = 0; i < cbPoints; i++) + { + pt = pts[i]; + CoordLPtoDP(dc, &pt); + PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO : PT_LINETO); + } + PATH_UnlockPath(pPath); + return TRUE; } BOOL FASTCALL -PATH_PolyPolyline ( PDC dc, const POINT* pts, const DWORD* counts, DWORD polylines ) +PATH_PolylineTo( + PDC dc, + const POINT *pts, + DWORD cbPoints) { - POINT pt; - ULONG poly, point, i; - PPATH pPath; + POINT pt; + ULONG i; + PPATH pPath; - ASSERT ( dc ); - ASSERT ( pts ); - ASSERT ( counts ); - ASSERT ( polylines ); + ASSERT(dc); + ASSERT(pts); + ASSERT(cbPoints); - pPath = PATH_LockPath( dc->dclevel.hPath ); - if (!pPath) return FALSE; + pPath = PATH_LockPath(dc->dclevel.hPath); + if (!pPath) return FALSE; - /* Check that path is open */ - if ( pPath->state != PATH_Open ) - { - PATH_UnlockPath( pPath ); - return FALSE; - } - - for(i = 0, poly = 0; poly < polylines; poly++) - { - for(point = 0; point < counts[poly]; point++, i++) + /* Check that path is open */ + if (pPath->state != PATH_Open) { - pt = pts[i]; - CoordLPtoDP ( dc, &pt ); - PATH_AddEntry(pPath, &pt, (point == 0) ? PT_MOVETO : PT_LINETO); + PATH_UnlockPath(pPath); + return FALSE; } - } - PATH_UnlockPath( pPath ); - return TRUE; + + /* Add a PT_MOVETO if necessary */ + if (pPath->newStroke) + { + pPath->newStroke = FALSE; + IntGetCurrentPositionEx(dc, &pt); + CoordLPtoDP(dc, &pt); + if (!PATH_AddEntry(pPath, &pt, PT_MOVETO)) + { + PATH_UnlockPath(pPath); + return FALSE; + } + } + + for (i = 0; i < cbPoints; i++) + { + pt = pts[i]; + CoordLPtoDP(dc, &pt); + PATH_AddEntry(pPath, &pt, PT_LINETO); + } + PATH_UnlockPath(pPath); + return TRUE; +} + + +BOOL +FASTCALL +PATH_Polygon( + PDC dc, + const POINT *pts, + DWORD cbPoints) +{ + POINT pt; + ULONG i; + PPATH pPath; + + ASSERT(dc); + ASSERT(pts); + + pPath = PATH_LockPath(dc->dclevel.hPath); + if (!pPath) return FALSE; + + /* Check that path is open */ + if (pPath->state != PATH_Open) + { + PATH_UnlockPath(pPath); + return FALSE; + } + + for (i = 0; i < cbPoints; i++) + { + pt = pts[i]; + CoordLPtoDP(dc, &pt); + PATH_AddEntry(pPath, &pt, (i == 0) ? PT_MOVETO : + ((i == cbPoints - 1) ? PT_LINETO | PT_CLOSEFIGURE : + PT_LINETO)); + } + + PATH_UnlockPath(pPath); + return TRUE; +} + +BOOL +FASTCALL +PATH_PolyPolygon( + PDC dc, + const POINT* pts, + const INT* counts, + UINT polygons) +{ + POINT pt, startpt; + ULONG poly, point, i; + PPATH pPath; + + ASSERT(dc); + ASSERT(pts); + ASSERT(counts); + ASSERT(polygons); + + pPath = PATH_LockPath(dc->dclevel.hPath); + if (!pPath) return FALSE; + + /* Check that path is open */ + if (pPath->state != PATH_Open) + { + PATH_UnlockPath(pPath); + return FALSE; + } + + for (i = 0, poly = 0; poly < polygons; poly++) + { + for (point = 0; point < (ULONG) counts[poly]; point++, i++) + { + pt = pts[i]; + CoordLPtoDP(dc, &pt); + if (point == 0) startpt = pt; + PATH_AddEntry(pPath, &pt, (point == 0) ? PT_MOVETO : PT_LINETO); + } + + /* Win98 adds an extra line to close the figure for some reason */ + PATH_AddEntry(pPath, &startpt, PT_LINETO | PT_CLOSEFIGURE); + } + + PATH_UnlockPath(pPath); + return TRUE; +} + +BOOL +FASTCALL +PATH_PolyPolyline( + PDC dc, + const POINT* pts, + const DWORD* counts, + DWORD polylines) +{ + POINT pt; + ULONG poly, point, i; + PPATH pPath; + + ASSERT(dc); + ASSERT(pts); + ASSERT(counts); + ASSERT(polylines); + + pPath = PATH_LockPath(dc->dclevel.hPath); + if (!pPath) return FALSE; + + /* Check that path is open */ + if (pPath->state != PATH_Open) + { + PATH_UnlockPath(pPath); + return FALSE; + } + + for (i = 0, poly = 0; poly < polylines; poly++) + { + for (point = 0; point < counts[poly]; point++, i++) + { + pt = pts[i]; + CoordLPtoDP(dc, &pt); + PATH_AddEntry(pPath, &pt, (point == 0) ? PT_MOVETO : PT_LINETO); + } + } + + PATH_UnlockPath(pPath); + return TRUE; } @@ -1027,41 +1103,49 @@ PATH_PolyPolyline ( PDC dc, const POINT* pts, const DWORD* counts, DWORD polylin * * Helper function for PATH_RoundRect() and PATH_Rectangle() */ -BOOL PATH_CheckCorners(DC *dc, POINT corners[], INT x1, INT y1, INT x2, INT y2) +BOOL +PATH_CheckCorners( + DC *dc, + POINT corners[], + INT x1, + INT y1, + INT x2, + INT y2) { - INT temp; - PDC_ATTR pdcattr = dc->pdcattr; + INT temp; + PDC_ATTR pdcattr = dc->pdcattr; - /* Convert points to device coordinates */ - corners[0].x=x1; - corners[0].y=y1; - corners[1].x=x2; - corners[1].y=y2; - CoordLPtoDP(dc, &corners[0]); - CoordLPtoDP(dc, &corners[1]); + /* Convert points to device coordinates */ + corners[0].x = x1; + corners[0].y = y1; + corners[1].x = x2; + corners[1].y = y2; + CoordLPtoDP(dc, &corners[0]); + CoordLPtoDP(dc, &corners[1]); - /* Make sure first corner is top left and second corner is bottom right */ - if(corners[0].x>corners[1].x) - { - temp=corners[0].x; - corners[0].x=corners[1].x; - corners[1].x=temp; - } - if(corners[0].y>corners[1].y) - { - temp=corners[0].y; - corners[0].y=corners[1].y; - corners[1].y=temp; - } + /* Make sure first corner is top left and second corner is bottom right */ + if (corners[0].x > corners[1].x) + { + temp = corners[0].x; + corners[0].x = corners[1].x; + corners[1].x = temp; + } - /* In GM_COMPATIBLE, don't include bottom and right edges */ - if(pdcattr->iGraphicsMode==GM_COMPATIBLE) - { - corners[1].x--; - corners[1].y--; - } + if (corners[0].y > corners[1].y) + { + temp = corners[0].y; + corners[0].y = corners[1].y; + corners[1].y = temp; + } - return TRUE; + /* In GM_COMPATIBLE, don't include bottom and right edges */ + if (pdcattr->iGraphicsMode == GM_COMPATIBLE) + { + corners[1].x--; + corners[1].y--; + } + + return TRUE; } @@ -1070,19 +1154,22 @@ BOOL PATH_CheckCorners(DC *dc, POINT corners[], INT x1, INT y1, INT x2, INT y2) */ BOOL FASTCALL -PATH_AddFlatBezier ( PPATH pPath, POINT *pt, BOOL closed ) +PATH_AddFlatBezier( + PPATH pPath, + POINT *pt, + BOOL closed) { - POINT *pts; - INT no, i; + POINT *pts; + INT no, i; - pts = GDI_Bezier( pt, 4, &no ); - if ( !pts ) return FALSE; + pts = GDI_Bezier(pt, 4, &no); + if (!pts) return FALSE; - for(i = 1; i < no; i++) - PATH_AddEntry(pPath, &pts[i], (i == no-1 && closed) ? PT_LINETO | PT_CLOSEFIGURE : PT_LINETO); + for (i = 1; i < no; i++) + PATH_AddEntry(pPath, &pts[i], (i == no - 1 && closed) ? PT_LINETO | PT_CLOSEFIGURE : PT_LINETO); - ExFreePoolWithTag(pts, TAG_BEZIER); - return TRUE; + ExFreePoolWithTag(pts, TAG_BEZIER); + return TRUE; } /* PATH_FlattenPath @@ -1094,27 +1181,30 @@ BOOL FASTCALL PATH_FlattenPath(PPATH pPath) { - PATH newPath; - INT srcpt; + PATH newPath; + INT srcpt; - RtlZeroMemory(&newPath, sizeof(newPath)); - newPath.state = PATH_Open; - for(srcpt = 0; srcpt < pPath->numEntriesUsed; srcpt++) { - switch(pPath->pFlags[srcpt] & ~PT_CLOSEFIGURE) { - case PT_MOVETO: - case PT_LINETO: - PATH_AddEntry(&newPath, &pPath->pPoints[srcpt], pPath->pFlags[srcpt]); - break; - case PT_BEZIERTO: - PATH_AddFlatBezier(&newPath, &pPath->pPoints[srcpt-1], pPath->pFlags[srcpt+2] & PT_CLOSEFIGURE); - srcpt += 2; - break; + RtlZeroMemory(&newPath, sizeof(newPath)); + newPath.state = PATH_Open; + for (srcpt = 0; srcpt < pPath->numEntriesUsed; srcpt++) + { + switch(pPath->pFlags[srcpt] & ~PT_CLOSEFIGURE) + { + case PT_MOVETO: + case PT_LINETO: + PATH_AddEntry(&newPath, &pPath->pPoints[srcpt], pPath->pFlags[srcpt]); + break; + case PT_BEZIERTO: + PATH_AddFlatBezier(&newPath, &pPath->pPoints[srcpt - 1], pPath->pFlags[srcpt + 2] & PT_CLOSEFIGURE); + srcpt += 2; + break; + } } - } - newPath.state = PATH_Closed; - PATH_AssignGdiPath(pPath, &newPath); - PATH_EmptyPath(&newPath); - return TRUE; + + newPath.state = PATH_Closed; + PATH_AssignGdiPath(pPath, &newPath); + PATH_EmptyPath(&newPath); + return TRUE; } @@ -1128,70 +1218,73 @@ PATH_FlattenPath(PPATH pPath) */ BOOL FASTCALL -PATH_PathToRegion ( PPATH pPath, INT nPolyFillMode, HRGN *pHrgn ) +PATH_PathToRegion( + PPATH pPath, + INT nPolyFillMode, + HRGN *pHrgn) { - int numStrokes, iStroke, i; - PULONG pNumPointsInStroke; - HRGN hrgn = 0; + int numStrokes, iStroke, i; + PULONG pNumPointsInStroke; + HRGN hrgn = 0; - ASSERT(pPath!=NULL); - ASSERT(pHrgn!=NULL); + ASSERT(pPath != NULL); + ASSERT(pHrgn != NULL); - PATH_FlattenPath ( pPath ); + PATH_FlattenPath(pPath); - /* First pass: Find out how many strokes there are in the path */ - /* FIXME: We could eliminate this with some bookkeeping in GdiPath */ - numStrokes=0; - for(i=0; inumEntriesUsed; i++) - if((pPath->pFlags[i] & ~PT_CLOSEFIGURE) == PT_MOVETO) - numStrokes++; + /* First pass: Find out how many strokes there are in the path */ + /* FIXME: We could eliminate this with some bookkeeping in GdiPath */ + numStrokes = 0; + for (i = 0; i < pPath->numEntriesUsed; i++) + if ((pPath->pFlags[i] & ~PT_CLOSEFIGURE) == PT_MOVETO) + numStrokes++; - if(numStrokes == 0) - { - return FALSE; - } - - /* Allocate memory for number-of-points-in-stroke array */ - pNumPointsInStroke = ExAllocatePoolWithTag(PagedPool, sizeof(ULONG) * numStrokes, TAG_PATH); - if(!pNumPointsInStroke) - { - EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } - - /* Second pass: remember number of points in each polygon */ - iStroke=-1; /* Will get incremented to 0 at beginning of first stroke */ - for(i=0; inumEntriesUsed; i++) - { - /* Is this the beginning of a new stroke? */ - if((pPath->pFlags[i] & ~PT_CLOSEFIGURE) == PT_MOVETO) + if (numStrokes == 0) { - iStroke++; - _PRAGMA_WARNING_SUPPRESS(__WARNING_WRITE_OVERRUN) - pNumPointsInStroke[iStroke]=0; + return FALSE; } - _PRAGMA_WARNING_SUPPRESS(__WARNING_READ_OVERRUN) - pNumPointsInStroke[iStroke]++; - } + /* Allocate memory for number-of-points-in-stroke array */ + pNumPointsInStroke = ExAllocatePoolWithTag(PagedPool, sizeof(ULONG) * numStrokes, TAG_PATH); + if (!pNumPointsInStroke) + { + EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } - /* Create a region from the strokes */ - hrgn = IntCreatePolyPolygonRgn( pPath->pPoints, - pNumPointsInStroke, - numStrokes, + /* Second pass: remember number of points in each polygon */ + iStroke = -1; /* Will get incremented to 0 at beginning of first stroke */ + for (i = 0; i < pPath->numEntriesUsed; i++) + { + /* Is this the beginning of a new stroke? */ + if ((pPath->pFlags[i] & ~PT_CLOSEFIGURE) == PT_MOVETO) + { + iStroke++; + _PRAGMA_WARNING_SUPPRESS(__WARNING_WRITE_OVERRUN) + pNumPointsInStroke[iStroke] = 0; + } + + _PRAGMA_WARNING_SUPPRESS(__WARNING_READ_OVERRUN) + pNumPointsInStroke[iStroke]++; + } + + /* Create a region from the strokes */ + hrgn = IntCreatePolyPolygonRgn(pPath->pPoints, + pNumPointsInStroke, + numStrokes, nPolyFillMode); - if(hrgn==(HRGN)0) - { - EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } + if (hrgn == (HRGN)0) + { + EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } - /* Free memory for number-of-points-in-stroke array */ - ExFreePoolWithTag(pNumPointsInStroke, TAG_PATH); + /* Free memory for number-of-points-in-stroke array */ + ExFreePoolWithTag(pNumPointsInStroke, TAG_PATH); - /* Success! */ - *pHrgn=hrgn; - return TRUE; + /* Success! */ + *pHrgn = hrgn; + return TRUE; } /* PATH_EmptyPath @@ -1200,12 +1293,12 @@ PATH_PathToRegion ( PPATH pPath, INT nPolyFillMode, HRGN *pHrgn ) */ VOID FASTCALL -PATH_EmptyPath ( PPATH pPath ) +PATH_EmptyPath(PPATH pPath) { - ASSERT(pPath!=NULL); + ASSERT(pPath != NULL); - pPath->state=PATH_Null; - pPath->numEntriesUsed=0; + pPath->state = PATH_Null; + pPath->numEntriesUsed = 0; } /* PATH_AddEntry @@ -1216,34 +1309,37 @@ PATH_EmptyPath ( PPATH pPath ) */ BOOL FASTCALL -PATH_AddEntry ( PPATH pPath, const POINT *pPoint, BYTE flags ) +PATH_AddEntry( + PPATH pPath, + const POINT *pPoint, + BYTE flags) { - ASSERT(pPath!=NULL); + ASSERT(pPath != NULL); - /* FIXME: If newStroke is true, perhaps we want to check that we're - * getting a PT_MOVETO - */ + /* FIXME: If newStroke is true, perhaps we want to check that we're + * getting a PT_MOVETO + */ - /* Check that path is open */ - if ( pPath->state != PATH_Open ) - return FALSE; + /* Check that path is open */ + if (pPath->state != PATH_Open) + return FALSE; - /* Reserve enough memory for an extra path entry */ - if ( !PATH_ReserveEntries(pPath, pPath->numEntriesUsed+1) ) - return FALSE; + /* Reserve enough memory for an extra path entry */ + if (!PATH_ReserveEntries(pPath, pPath->numEntriesUsed + 1)) + return FALSE; - /* Store information in path entry */ - pPath->pPoints[pPath->numEntriesUsed]=*pPoint; - pPath->pFlags[pPath->numEntriesUsed]=flags; + /* Store information in path entry */ + pPath->pPoints[pPath->numEntriesUsed] = *pPoint; + pPath->pFlags[pPath->numEntriesUsed] = flags; - /* If this is PT_CLOSEFIGURE, we have to start a new stroke next time */ - if((flags & PT_CLOSEFIGURE) == PT_CLOSEFIGURE) - pPath->newStroke=TRUE; + /* If this is PT_CLOSEFIGURE, we have to start a new stroke next time */ + if ((flags & PT_CLOSEFIGURE) == PT_CLOSEFIGURE) + pPath->newStroke = TRUE; - /* Increment entry count */ - pPath->numEntriesUsed++; + /* Increment entry count */ + pPath->numEntriesUsed++; - return TRUE; + return TRUE; } /* PATH_ReserveEntries @@ -1254,57 +1350,62 @@ PATH_AddEntry ( PPATH pPath, const POINT *pPoint, BYTE flags ) */ BOOL FASTCALL -PATH_ReserveEntries ( PPATH pPath, INT numEntries ) +PATH_ReserveEntries( + PPATH pPath, + INT numEntries) { - INT numEntriesToAllocate; - POINT *pPointsNew; - BYTE *pFlagsNew; + INT numEntriesToAllocate; + POINT *pPointsNew; + BYTE *pFlagsNew; - ASSERT(pPath!=NULL); - ASSERT(numEntries>=0); + ASSERT(pPath != NULL); + ASSERT(numEntries >= 0); - /* Do we have to allocate more memory? */ - if(numEntries > pPath->numEntriesAllocated) - { - /* Find number of entries to allocate. We let the size of the array - * grow exponentially, since that will guarantee linear time - * complexity. */ - if(pPath->numEntriesAllocated) + /* Do we have to allocate more memory? */ + if (numEntries > pPath->numEntriesAllocated) { - numEntriesToAllocate=pPath->numEntriesAllocated; - while(numEntriesToAllocatenumEntriesAllocated) + { + numEntriesToAllocate = pPath->numEntriesAllocated; + while (numEntriesToAllocate < numEntries) + numEntriesToAllocate = numEntriesToAllocate * GROW_FACTOR_NUMER / GROW_FACTOR_DENOM; + } + else + numEntriesToAllocate = numEntries; - /* Allocate new arrays */ - pPointsNew=(POINT *)ExAllocatePoolWithTag(PagedPool, numEntriesToAllocate * sizeof(POINT), TAG_PATH); - if(!pPointsNew) - return FALSE; - pFlagsNew=(BYTE *)ExAllocatePoolWithTag(PagedPool, numEntriesToAllocate * sizeof(BYTE), TAG_PATH); - if(!pFlagsNew) - { - ExFreePoolWithTag(pPointsNew, TAG_PATH); - return FALSE; + /* Allocate new arrays */ + pPointsNew = (POINT *)ExAllocatePoolWithTag(PagedPool, numEntriesToAllocate * sizeof(POINT), TAG_PATH); + if (!pPointsNew) + return FALSE; + + pFlagsNew = (BYTE *)ExAllocatePoolWithTag(PagedPool, numEntriesToAllocate * sizeof(BYTE), TAG_PATH); + if (!pFlagsNew) + { + ExFreePoolWithTag(pPointsNew, TAG_PATH); + return FALSE; + } + + /* Copy old arrays to new arrays and discard old arrays */ + if (pPath->pPoints) + { + ASSERT(pPath->pFlags); + + memcpy(pPointsNew, pPath->pPoints, sizeof(POINT)*pPath->numEntriesUsed); + memcpy(pFlagsNew, pPath->pFlags, sizeof(BYTE)*pPath->numEntriesUsed); + + ExFreePoolWithTag(pPath->pPoints, TAG_PATH); + ExFreePoolWithTag(pPath->pFlags, TAG_PATH); + } + + pPath->pPoints = pPointsNew; + pPath->pFlags = pFlagsNew; + pPath->numEntriesAllocated = numEntriesToAllocate; } - /* Copy old arrays to new arrays and discard old arrays */ - if(pPath->pPoints) - { - ASSERT(pPath->pFlags); - - memcpy(pPointsNew, pPath->pPoints, sizeof(POINT)*pPath->numEntriesUsed); - memcpy(pFlagsNew, pPath->pFlags, sizeof(BYTE)*pPath->numEntriesUsed); - - ExFreePoolWithTag(pPath->pPoints, TAG_PATH); - ExFreePoolWithTag(pPath->pFlags, TAG_PATH); - } - pPath->pPoints=pPointsNew; - pPath->pFlags=pFlagsNew; - pPath->numEntriesAllocated=numEntriesToAllocate; - } - - return TRUE; + return TRUE; } /* PATH_DoArcPart @@ -1318,55 +1419,60 @@ PATH_ReserveEntries ( PPATH pPath, INT numEntries ) */ BOOL FASTCALL -PATH_DoArcPart ( PPATH pPath, FLOAT_POINT corners[], - double angleStart, double angleEnd, BYTE startEntryType ) +PATH_DoArcPart( + PPATH pPath, + FLOAT_POINT corners[], + double angleStart, + double angleEnd, + BYTE startEntryType) { - double halfAngle, a; - double xNorm[4], yNorm[4]; - POINT point; - int i; + double halfAngle, a; + double xNorm[4], yNorm[4]; + POINT point; + int i; - ASSERT(fabs(angleEnd-angleStart)<=M_PI_2); + ASSERT(fabs(angleEnd - angleStart) <= M_PI_2); - /* FIXME: Is there an easier way of computing this? */ + /* FIXME: Is there an easier way of computing this? */ - /* Compute control points */ - halfAngle=(angleEnd-angleStart)/2.0; - if(fabs(halfAngle)>1e-8) - { - a=4.0/3.0*(1-cos(halfAngle))/sin(halfAngle); - xNorm[0]=cos(angleStart); - yNorm[0]=sin(angleStart); - xNorm[1]=xNorm[0] - a*yNorm[0]; - yNorm[1]=yNorm[0] + a*xNorm[0]; - xNorm[3]=cos(angleEnd); - yNorm[3]=sin(angleEnd); - xNorm[2]=xNorm[3] + a*yNorm[3]; - yNorm[2]=yNorm[3] - a*xNorm[3]; - } else - for(i=0; i<4; i++) + /* Compute control points */ + halfAngle = (angleEnd - angleStart) / 2.0; + if (fabs(halfAngle) > 1e-8) { - xNorm[i]=cos(angleStart); - yNorm[i]=sin(angleStart); + a = 4.0 / 3.0 * (1 - cos(halfAngle)) / sin(halfAngle); + xNorm[0] = cos(angleStart); + yNorm[0] = sin(angleStart); + xNorm[1] = xNorm[0] - a * yNorm[0]; + yNorm[1] = yNorm[0] + a * xNorm[0]; + xNorm[3] = cos(angleEnd); + yNorm[3] = sin(angleEnd); + xNorm[2] = xNorm[3] + a * yNorm[3]; + yNorm[2] = yNorm[3] - a * xNorm[3]; + } + else + for (i = 0; i < 4; i++) + { + xNorm[i] = cos(angleStart); + yNorm[i] = sin(angleStart); + } + + /* Add starting point to path if desired */ + if (startEntryType) + { + PATH_ScaleNormalizedPoint(corners, xNorm[0], yNorm[0], &point); + if (!PATH_AddEntry(pPath, &point, startEntryType)) + return FALSE; } - /* Add starting point to path if desired */ - if(startEntryType) - { - PATH_ScaleNormalizedPoint(corners, xNorm[0], yNorm[0], &point); - if(!PATH_AddEntry(pPath, &point, startEntryType)) - return FALSE; - } + /* Add remaining control points */ + for (i = 1; i < 4; i++) + { + PATH_ScaleNormalizedPoint(corners, xNorm[i], yNorm[i], &point); + if (!PATH_AddEntry(pPath, &point, PT_BEZIERTO)) + return FALSE; + } - /* Add remaining control points */ - for(i=1; i<4; i++) - { - PATH_ScaleNormalizedPoint(corners, xNorm[i], yNorm[i], &point); - if(!PATH_AddEntry(pPath, &point, PT_BEZIERTO)) - return FALSE; - } - - return TRUE; + return TRUE; } /* PATH_ScaleNormalizedPoint @@ -1378,13 +1484,17 @@ PATH_DoArcPart ( PPATH pPath, FLOAT_POINT corners[], */ VOID FASTCALL -PATH_ScaleNormalizedPoint ( FLOAT_POINT corners[], double x, - double y, POINT *pPoint ) +PATH_ScaleNormalizedPoint( + FLOAT_POINT corners[], + double x, + double y, + POINT *pPoint) { - ASSERT ( corners ); - ASSERT ( pPoint ); - pPoint->x=GDI_ROUND( (double)corners[0].x + (double)(corners[1].x-corners[0].x)*0.5*(x+1.0) ); - pPoint->y=GDI_ROUND( (double)corners[0].y + (double)(corners[1].y-corners[0].y)*0.5*(y+1.0) ); + ASSERT(corners); + ASSERT(pPoint); + + pPoint->x = GDI_ROUND((double)corners[0].x + (double)(corners[1].x - corners[0].x) * 0.5 * (x + 1.0)); + pPoint->y = GDI_ROUND((double)corners[0].y + (double)(corners[1].y - corners[0].y) * 0.5 * (y + 1.0)); } /* PATH_NormalizePoint @@ -1394,23 +1504,30 @@ PATH_ScaleNormalizedPoint ( FLOAT_POINT corners[], double x, */ VOID FASTCALL -PATH_NormalizePoint ( FLOAT_POINT corners[], - const FLOAT_POINT *pPoint, - double *pX, double *pY) +PATH_NormalizePoint( + FLOAT_POINT corners[], + const FLOAT_POINT *pPoint, + double *pX, + double *pY) { - ASSERT ( corners ); - ASSERT ( pPoint ); - ASSERT ( pX ); - ASSERT ( pY ); - *pX=(double)(pPoint->x-corners[0].x)/(double)(corners[1].x-corners[0].x) * 2.0 - 1.0; - *pY=(double)(pPoint->y-corners[0].y)/(double)(corners[1].y-corners[0].y) * 2.0 - 1.0; + ASSERT(corners); + ASSERT(pPoint); + ASSERT(pX); + ASSERT(pY); + + *pX = (double)(pPoint->x - corners[0].x) / (double)(corners[1].x - corners[0].x) * 2.0 - 1.0; + *pY = (double)(pPoint->y - corners[0].y) / (double)(corners[1].y - corners[0].y) * 2.0 - 1.0; } -BOOL FASTCALL PATH_StrokePath(DC *dc, PPATH pPath) +BOOL +FASTCALL +PATH_StrokePath( + DC *dc, + PPATH pPath) { BOOL ret = FALSE; - INT i=0; + INT i = 0; INT nLinePts, nAlloc; POINT *pLinePts = NULL; POINT ptViewportOrg, ptWindowOrg; @@ -1450,7 +1567,7 @@ BOOL FASTCALL PATH_StrokePath(DC *dc, PPATH pPath) * space in case we get one to keep the number of reallocations small. */ nAlloc = pPath->numEntriesUsed + 1 + 300; pLinePts = ExAllocatePoolWithTag(PagedPool, nAlloc * sizeof(POINT), TAG_PATH); - if(!pLinePts) + if (!pLinePts) { DPRINT1("Can't allocate pool!\n"); EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); @@ -1458,93 +1575,93 @@ BOOL FASTCALL PATH_StrokePath(DC *dc, PPATH pPath) } nLinePts = 0; - for(i = 0; i < pPath->numEntriesUsed; i++) + for (i = 0; i < pPath->numEntriesUsed; i++) { - if((i == 0 || (pPath->pFlags[i-1] & PT_CLOSEFIGURE)) + if ((i == 0 || (pPath->pFlags[i - 1] & PT_CLOSEFIGURE)) && (pPath->pFlags[i] != PT_MOVETO)) { DPRINT1("Expected PT_MOVETO %s, got path flag %d\n", - i == 0 ? "as first point" : "after PT_CLOSEFIGURE", - (INT)pPath->pFlags[i]); - goto end; + i == 0 ? "as first point" : "after PT_CLOSEFIGURE", + (INT)pPath->pFlags[i]); + goto end; } switch(pPath->pFlags[i]) { - case PT_MOVETO: - DPRINT("Got PT_MOVETO (%ld, %ld)\n", - pPath->pPoints[i].x, pPath->pPoints[i].y); - if(nLinePts >= 2) IntGdiPolyline(dc, pLinePts, nLinePts); - nLinePts = 0; - pLinePts[nLinePts++] = pPath->pPoints[i]; - break; - case PT_LINETO: - case (PT_LINETO | PT_CLOSEFIGURE): - DPRINT("Got PT_LINETO (%ld, %ld)\n", - pPath->pPoints[i].x, pPath->pPoints[i].y); - pLinePts[nLinePts++] = pPath->pPoints[i]; - break; - case PT_BEZIERTO: - DPRINT("Got PT_BEZIERTO\n"); - if(pPath->pFlags[i+1] != PT_BEZIERTO || - (pPath->pFlags[i+2] & ~PT_CLOSEFIGURE) != PT_BEZIERTO) - { - DPRINT1("Path didn't contain 3 successive PT_BEZIERTOs\n"); - ret = FALSE; - goto end; - } - else - { - INT nBzrPts, nMinAlloc; - POINT *pBzrPts = GDI_Bezier(&pPath->pPoints[i-1], 4, &nBzrPts); - /* Make sure we have allocated enough memory for the lines of - * this bezier and the rest of the path, assuming we won't get - * another one (since we won't reallocate again then). */ - nMinAlloc = nLinePts + (pPath->numEntriesUsed - i) + nBzrPts; - if(nAlloc < nMinAlloc) + case PT_MOVETO: + DPRINT("Got PT_MOVETO (%ld, %ld)\n", + pPath->pPoints[i].x, pPath->pPoints[i].y); + if (nLinePts >= 2) IntGdiPolyline(dc, pLinePts, nLinePts); + nLinePts = 0; + pLinePts[nLinePts++] = pPath->pPoints[i]; + break; + case PT_LINETO: + case (PT_LINETO | PT_CLOSEFIGURE): + DPRINT("Got PT_LINETO (%ld, %ld)\n", + pPath->pPoints[i].x, pPath->pPoints[i].y); + pLinePts[nLinePts++] = pPath->pPoints[i]; + break; + case PT_BEZIERTO: + DPRINT("Got PT_BEZIERTO\n"); + if (pPath->pFlags[i + 1] != PT_BEZIERTO || + (pPath->pFlags[i + 2] & ~PT_CLOSEFIGURE) != PT_BEZIERTO) { - // Reallocate memory - - POINT *Realloc = NULL; - nAlloc = nMinAlloc * 2; - - Realloc = ExAllocatePoolWithTag(PagedPool, - nAlloc * sizeof(POINT), - TAG_PATH); - - if(!Realloc) - { - DPRINT1("Can't allocate pool!\n"); - goto end; - } - - memcpy(Realloc, pLinePts, nLinePts*sizeof(POINT)); - ExFreePoolWithTag(pLinePts, TAG_PATH); - pLinePts = Realloc; + DPRINT1("Path didn't contain 3 successive PT_BEZIERTOs\n"); + ret = FALSE; + goto end; } - memcpy(&pLinePts[nLinePts], &pBzrPts[1], (nBzrPts - 1) * sizeof(POINT)); - nLinePts += nBzrPts - 1; - ExFreePoolWithTag(pBzrPts, TAG_BEZIER); - i += 2; - } - break; - default: - DPRINT1("Got path flag %d (not supported)\n", (INT)pPath->pFlags[i]); - goto end; + else + { + INT nBzrPts, nMinAlloc; + POINT *pBzrPts = GDI_Bezier(&pPath->pPoints[i - 1], 4, &nBzrPts); + /* Make sure we have allocated enough memory for the lines of + * this bezier and the rest of the path, assuming we won't get + * another one (since we won't reallocate again then). */ + nMinAlloc = nLinePts + (pPath->numEntriesUsed - i) + nBzrPts; + if (nAlloc < nMinAlloc) + { + // Reallocate memory + + POINT *Realloc = NULL; + nAlloc = nMinAlloc * 2; + + Realloc = ExAllocatePoolWithTag(PagedPool, + nAlloc * sizeof(POINT), + TAG_PATH); + + if (!Realloc) + { + DPRINT1("Can't allocate pool!\n"); + goto end; + } + + memcpy(Realloc, pLinePts, nLinePts * sizeof(POINT)); + ExFreePoolWithTag(pLinePts, TAG_PATH); + pLinePts = Realloc; + } + memcpy(&pLinePts[nLinePts], &pBzrPts[1], (nBzrPts - 1) * sizeof(POINT)); + nLinePts += nBzrPts - 1; + ExFreePoolWithTag(pBzrPts, TAG_BEZIER); + i += 2; + } + break; + default: + DPRINT1("Got path flag %d (not supported)\n", (INT)pPath->pFlags[i]); + goto end; } - if(pPath->pFlags[i] & PT_CLOSEFIGURE) + if (pPath->pFlags[i] & PT_CLOSEFIGURE) { pLinePts[nLinePts++] = pLinePts[0]; } } - if(nLinePts >= 2) + if (nLinePts >= 2) IntGdiPolyline(dc, pLinePts, nLinePts); ret = TRUE; end: - if(pLinePts) ExFreePoolWithTag(pLinePts, TAG_PATH); + if (pLinePts) ExFreePoolWithTag(pLinePts, TAG_PATH); /* Restore the old mapping mode */ pdcattr->iMapMode = mapMode; @@ -1567,7 +1684,7 @@ end: dc->CurPosX|Y so that their values are in the correct mapping mode. */ - if(i > 0) + if (i > 0) { POINT pt; IntGetCurrentPositionEx(dc, &pt); @@ -1592,22 +1709,22 @@ PATH_WidenPath(DC *dc) DWORD obj_type, joint, endcap, penType; PDC_ATTR pdcattr = dc->pdcattr; - pPath = PATH_LockPath( dc->dclevel.hPath ); + pPath = PATH_LockPath(dc->dclevel.hPath); if (!pPath) return FALSE; - if(pPath->state == PATH_Open) + if (pPath->state == PATH_Open) { - PATH_UnlockPath( pPath ); - EngSetLastError(ERROR_CAN_NOT_COMPLETE); - return FALSE; + PATH_UnlockPath(pPath); + EngSetLastError(ERROR_CAN_NOT_COMPLETE); + return FALSE; } PATH_FlattenPath(pPath); - size = GreGetObject( pdcattr->hpen, 0, NULL); + size = GreGetObject(pdcattr->hpen, 0, NULL); if (!size) { - PATH_UnlockPath( pPath ); + PATH_UnlockPath(pPath); EngSetLastError(ERROR_CAN_NOT_COMPLETE); return FALSE; } @@ -1616,11 +1733,11 @@ PATH_WidenPath(DC *dc) GreGetObject(pdcattr->hpen, size, elp); obj_type = GDI_HANDLE_GET_TYPE(pdcattr->hpen); - if(obj_type == GDI_OBJECT_TYPE_PEN) + if (obj_type == GDI_OBJECT_TYPE_PEN) { penStyle = ((LOGPEN*)elp)->lopnStyle; } - else if(obj_type == GDI_OBJECT_TYPE_EXTPEN) + else if (obj_type == GDI_OBJECT_TYPE_EXTPEN) { penStyle = elp->elpPenStyle; } @@ -1628,7 +1745,7 @@ PATH_WidenPath(DC *dc) { EngSetLastError(ERROR_CAN_NOT_COMPLETE); ExFreePoolWithTag(elp, TAG_PATH); - PATH_UnlockPath( pPath ); + PATH_UnlockPath(pPath); return FALSE; } @@ -1640,35 +1757,35 @@ PATH_WidenPath(DC *dc) penType = (PS_TYPE_MASK & penStyle); /* The function cannot apply to cosmetic pens */ - if(obj_type == GDI_OBJECT_TYPE_EXTPEN && penType == PS_COSMETIC) + if (obj_type == GDI_OBJECT_TYPE_EXTPEN && penType == PS_COSMETIC) { - PATH_UnlockPath( pPath ); + PATH_UnlockPath(pPath); EngSetLastError(ERROR_CAN_NOT_COMPLETE); return FALSE; } penWidthIn = penWidth / 2; penWidthOut = penWidth / 2; - if(penWidthIn + penWidthOut < penWidth) + if (penWidthIn + penWidthOut < penWidth) penWidthOut++; numStrokes = 0; - for(i = 0, j = 0; i < pPath->numEntriesUsed; i++, j++) + for (i = 0, j = 0; i < pPath->numEntriesUsed; i++, j++) { POINT point; - if((i == 0 || (pPath->pFlags[i-1] & PT_CLOSEFIGURE)) && - (pPath->pFlags[i] != PT_MOVETO)) + if ((i == 0 || (pPath->pFlags[i - 1] & PT_CLOSEFIGURE)) && + (pPath->pFlags[i] != PT_MOVETO)) { DPRINT1("Expected PT_MOVETO %s, got path flag %c\n", - i == 0 ? "as first point" : "after PT_CLOSEFIGURE", - pPath->pFlags[i]); + i == 0 ? "as first point" : "after PT_CLOSEFIGURE", + pPath->pFlags[i]); return FALSE; } switch(pPath->pFlags[i]) { case PT_MOVETO: - if(numStrokes > 0) + if (numStrokes > 0) { pStrokes[numStrokes - 1]->state = PATH_Closed; } @@ -1676,14 +1793,14 @@ PATH_WidenPath(DC *dc) numStrokes++; j = 0; if (numStrokes == 1) - pStrokes = ExAllocatePoolWithTag(PagedPool, numStrokes * sizeof(PPATH), TAG_PATH); + pStrokes = ExAllocatePoolWithTag(PagedPool, numStrokes * sizeof(PPATH), TAG_PATH); else { - pOldStrokes = pStrokes; // Save old pointer. - pStrokes = ExAllocatePoolWithTag(PagedPool, numStrokes * sizeof(PPATH), TAG_PATH); - if (!pStrokes) return FALSE; - RtlCopyMemory(pStrokes, pOldStrokes, numOldStrokes * sizeof(PPATH)); - ExFreePoolWithTag(pOldStrokes, TAG_PATH); // Free old pointer. + pOldStrokes = pStrokes; // Save old pointer. + pStrokes = ExAllocatePoolWithTag(PagedPool, numStrokes * sizeof(PPATH), TAG_PATH); + if (!pStrokes) return FALSE; + RtlCopyMemory(pStrokes, pOldStrokes, numOldStrokes * sizeof(PPATH)); + ExFreePoolWithTag(pOldStrokes, TAG_PATH); // Free old pointer. } if (!pStrokes) return FALSE; pStrokes[numStrokes - 1] = ExAllocatePoolWithTag(PagedPool, sizeof(PATH), TAG_PATH); @@ -1718,7 +1835,7 @@ PATH_WidenPath(DC *dc) PATH_InitGdiPath(pNewPath); pNewPath->state = PATH_Open; - for(i = 0; i < numStrokes; i++) + for (i = 0; i < numStrokes; i++) { pUpPath = ExAllocatePoolWithTag(PagedPool, sizeof(PATH), TAG_PATH); PATH_InitGdiPath(pUpPath); @@ -1727,16 +1844,16 @@ PATH_WidenPath(DC *dc) PATH_InitGdiPath(pDownPath); pDownPath->state = PATH_Open; - for(j = 0; j < pStrokes[i]->numEntriesUsed; j++) + for (j = 0; j < pStrokes[i]->numEntriesUsed; j++) { /* Beginning or end of the path if not closed */ - if((!(pStrokes[i]->pFlags[pStrokes[i]->numEntriesUsed - 1] & PT_CLOSEFIGURE)) && (j == 0 || j == pStrokes[i]->numEntriesUsed - 1) ) + if ((!(pStrokes[i]->pFlags[pStrokes[i]->numEntriesUsed - 1] & PT_CLOSEFIGURE)) && (j == 0 || j == pStrokes[i]->numEntriesUsed - 1)) { /* Compute segment angle */ double xo, yo, xa, ya, theta; POINT pt; FLOAT_POINT corners[2]; - if(j == 0) + if (j == 0) { xo = pStrokes[i]->pPoints[j].x; yo = pStrokes[i]->pPoints[j].y; @@ -1750,23 +1867,23 @@ PATH_WidenPath(DC *dc) xo = pStrokes[i]->pPoints[j].x; yo = pStrokes[i]->pPoints[j].y; } - theta = atan2( ya - yo, xa - xo ); + theta = atan2(ya - yo, xa - xo); switch(endcap) { case PS_ENDCAP_SQUARE : pt.x = xo + round(sqrt(2) * penWidthOut * cos(M_PI_4 + theta)); pt.y = yo + round(sqrt(2) * penWidthOut * sin(M_PI_4 + theta)); - PATH_AddEntry(pUpPath, &pt, (j == 0 ? PT_MOVETO : PT_LINETO) ); + PATH_AddEntry(pUpPath, &pt, (j == 0 ? PT_MOVETO : PT_LINETO)); pt.x = xo + round(sqrt(2) * penWidthIn * cos(- M_PI_4 + theta)); pt.y = yo + round(sqrt(2) * penWidthIn * sin(- M_PI_4 + theta)); PATH_AddEntry(pUpPath, &pt, PT_LINETO); break; case PS_ENDCAP_FLAT : - pt.x = xo + round( penWidthOut * cos(theta + M_PI_2) ); - pt.y = yo + round( penWidthOut * sin(theta + M_PI_2) ); + pt.x = xo + round(penWidthOut * cos(theta + M_PI_2)); + pt.y = yo + round(penWidthOut * sin(theta + M_PI_2)); PATH_AddEntry(pUpPath, &pt, (j == 0 ? PT_MOVETO : PT_LINETO)); - pt.x = xo - round( penWidthIn * cos(theta + M_PI_2) ); - pt.y = yo - round( penWidthIn * sin(theta + M_PI_2) ); + pt.x = xo - round(penWidthIn * cos(theta + M_PI_2)); + pt.y = yo - round(penWidthIn * sin(theta + M_PI_2)); PATH_AddEntry(pUpPath, &pt, PT_LINETO); break; case PS_ENDCAP_ROUND : @@ -1775,10 +1892,10 @@ PATH_WidenPath(DC *dc) corners[0].y = yo - penWidthIn; corners[1].x = xo + penWidthOut; corners[1].y = yo + penWidthOut; - PATH_DoArcPart(pUpPath ,corners, theta + M_PI_2 , theta + 3 * M_PI_4, (j == 0 ? PT_MOVETO : FALSE)); - PATH_DoArcPart(pUpPath ,corners, theta + 3 * M_PI_4 , theta + M_PI, FALSE); - PATH_DoArcPart(pUpPath ,corners, theta + M_PI, theta + 5 * M_PI_4, FALSE); - PATH_DoArcPart(pUpPath ,corners, theta + 5 * M_PI_4 , theta + 3 * M_PI_2, FALSE); + PATH_DoArcPart(pUpPath , corners, theta + M_PI_2 , theta + 3 * M_PI_4, (j == 0 ? PT_MOVETO : FALSE)); + PATH_DoArcPart(pUpPath , corners, theta + 3 * M_PI_4 , theta + M_PI, FALSE); + PATH_DoArcPart(pUpPath , corners, theta + M_PI, theta + 5 * M_PI_4, FALSE); + PATH_DoArcPart(pUpPath , corners, theta + 5 * M_PI_4 , theta + 3 * M_PI_2, FALSE); break; } } @@ -1791,8 +1908,8 @@ PATH_WidenPath(DC *dc) double alpha, theta, miterWidth; DWORD _joint = joint; POINT pt; - PPATH pInsidePath, pOutsidePath; - if(j > 0 && j < pStrokes[i]->numEntriesUsed - 1) + PPATH pInsidePath, pOutsidePath; + if (j > 0 && j < pStrokes[i]->numEntriesUsed - 1) { previous = j - 1; next = j + 1; @@ -1813,20 +1930,20 @@ PATH_WidenPath(DC *dc) ya = pStrokes[i]->pPoints[previous].y; xb = pStrokes[i]->pPoints[next].x; yb = pStrokes[i]->pPoints[next].y; - theta = atan2( yo - ya, xo - xa ); - alpha = atan2( yb - yo, xb - xo ) - theta; + theta = atan2(yo - ya, xo - xa); + alpha = atan2(yb - yo, xb - xo) - theta; if (alpha > 0) alpha -= M_PI; else alpha += M_PI; - if(_joint == PS_JOIN_MITER && dc->dclevel.laPath.eMiterLimit < fabs(1 / sin(alpha/2))) + if (_joint == PS_JOIN_MITER && dc->dclevel.laPath.eMiterLimit < fabs(1 / sin(alpha / 2))) { _joint = PS_JOIN_BEVEL; } - if(alpha > 0) + if (alpha > 0) { pInsidePath = pUpPath; pOutsidePath = pDownPath; } - else if(alpha < 0) + else if (alpha < 0) { pInsidePath = pDownPath; pOutsidePath = pUpPath; @@ -1836,105 +1953,105 @@ PATH_WidenPath(DC *dc) continue; } /* Inside angle points */ - if(alpha > 0) + if (alpha > 0) { - pt.x = xo - round( penWidthIn * cos(theta + M_PI_2) ); - pt.y = yo - round( penWidthIn * sin(theta + M_PI_2) ); + pt.x = xo - round(penWidthIn * cos(theta + M_PI_2)); + pt.y = yo - round(penWidthIn * sin(theta + M_PI_2)); } else { - pt.x = xo + round( penWidthIn * cos(theta + M_PI_2) ); - pt.y = yo + round( penWidthIn * sin(theta + M_PI_2) ); + pt.x = xo + round(penWidthIn * cos(theta + M_PI_2)); + pt.y = yo + round(penWidthIn * sin(theta + M_PI_2)); } PATH_AddEntry(pInsidePath, &pt, PT_LINETO); - if(alpha > 0) + if (alpha > 0) { - pt.x = xo + round( penWidthIn * cos(M_PI_2 + alpha + theta) ); - pt.y = yo + round( penWidthIn * sin(M_PI_2 + alpha + theta) ); + pt.x = xo + round(penWidthIn * cos(M_PI_2 + alpha + theta)); + pt.y = yo + round(penWidthIn * sin(M_PI_2 + alpha + theta)); } else { - pt.x = xo - round( penWidthIn * cos(M_PI_2 + alpha + theta) ); - pt.y = yo - round( penWidthIn * sin(M_PI_2 + alpha + theta) ); + pt.x = xo - round(penWidthIn * cos(M_PI_2 + alpha + theta)); + pt.y = yo - round(penWidthIn * sin(M_PI_2 + alpha + theta)); } PATH_AddEntry(pInsidePath, &pt, PT_LINETO); /* Outside angle point */ switch(_joint) { - case PS_JOIN_MITER : + case PS_JOIN_MITER : miterWidth = fabs(penWidthOut / cos(M_PI_2 - fabs(alpha) / 2)); - pt.x = xo + round( miterWidth * cos(theta + alpha / 2) ); - pt.y = yo + round( miterWidth * sin(theta + alpha / 2) ); + pt.x = xo + round(miterWidth * cos(theta + alpha / 2)); + pt.y = yo + round(miterWidth * sin(theta + alpha / 2)); PATH_AddEntry(pOutsidePath, &pt, PT_LINETO); break; case PS_JOIN_BEVEL : - if(alpha > 0) + if (alpha > 0) { - pt.x = xo + round( penWidthOut * cos(theta + M_PI_2) ); - pt.y = yo + round( penWidthOut * sin(theta + M_PI_2) ); + pt.x = xo + round(penWidthOut * cos(theta + M_PI_2)); + pt.y = yo + round(penWidthOut * sin(theta + M_PI_2)); } else { - pt.x = xo - round( penWidthOut * cos(theta + M_PI_2) ); - pt.y = yo - round( penWidthOut * sin(theta + M_PI_2) ); + pt.x = xo - round(penWidthOut * cos(theta + M_PI_2)); + pt.y = yo - round(penWidthOut * sin(theta + M_PI_2)); } PATH_AddEntry(pOutsidePath, &pt, PT_LINETO); - if(alpha > 0) + if (alpha > 0) { - pt.x = xo - round( penWidthOut * cos(M_PI_2 + alpha + theta) ); - pt.y = yo - round( penWidthOut * sin(M_PI_2 + alpha + theta) ); + pt.x = xo - round(penWidthOut * cos(M_PI_2 + alpha + theta)); + pt.y = yo - round(penWidthOut * sin(M_PI_2 + alpha + theta)); } else { - pt.x = xo + round( penWidthOut * cos(M_PI_2 + alpha + theta) ); - pt.y = yo + round( penWidthOut * sin(M_PI_2 + alpha + theta) ); + pt.x = xo + round(penWidthOut * cos(M_PI_2 + alpha + theta)); + pt.y = yo + round(penWidthOut * sin(M_PI_2 + alpha + theta)); } PATH_AddEntry(pOutsidePath, &pt, PT_LINETO); break; case PS_JOIN_ROUND : default : - if(alpha > 0) + if (alpha > 0) { - pt.x = xo + round( penWidthOut * cos(theta + M_PI_2) ); - pt.y = yo + round( penWidthOut * sin(theta + M_PI_2) ); + pt.x = xo + round(penWidthOut * cos(theta + M_PI_2)); + pt.y = yo + round(penWidthOut * sin(theta + M_PI_2)); } else { - pt.x = xo - round( penWidthOut * cos(theta + M_PI_2) ); - pt.y = yo - round( penWidthOut * sin(theta + M_PI_2) ); + pt.x = xo - round(penWidthOut * cos(theta + M_PI_2)); + pt.y = yo - round(penWidthOut * sin(theta + M_PI_2)); } PATH_AddEntry(pOutsidePath, &pt, PT_BEZIERTO); - pt.x = xo + round( penWidthOut * cos(theta + alpha / 2) ); - pt.y = yo + round( penWidthOut * sin(theta + alpha / 2) ); + pt.x = xo + round(penWidthOut * cos(theta + alpha / 2)); + pt.y = yo + round(penWidthOut * sin(theta + alpha / 2)); PATH_AddEntry(pOutsidePath, &pt, PT_BEZIERTO); - if(alpha > 0) + if (alpha > 0) { - pt.x = xo - round( penWidthOut * cos(M_PI_2 + alpha + theta) ); - pt.y = yo - round( penWidthOut * sin(M_PI_2 + alpha + theta) ); + pt.x = xo - round(penWidthOut * cos(M_PI_2 + alpha + theta)); + pt.y = yo - round(penWidthOut * sin(M_PI_2 + alpha + theta)); } else { - pt.x = xo + round( penWidthOut * cos(M_PI_2 + alpha + theta) ); - pt.y = yo + round( penWidthOut * sin(M_PI_2 + alpha + theta) ); + pt.x = xo + round(penWidthOut * cos(M_PI_2 + alpha + theta)); + pt.y = yo + round(penWidthOut * sin(M_PI_2 + alpha + theta)); } PATH_AddEntry(pOutsidePath, &pt, PT_BEZIERTO); break; } } } - for(j = 0; j < pUpPath->numEntriesUsed; j++) + for (j = 0; j < pUpPath->numEntriesUsed; j++) { POINT pt; pt.x = pUpPath->pPoints[j].x; pt.y = pUpPath->pPoints[j].y; PATH_AddEntry(pNewPath, &pt, (j == 0 ? PT_MOVETO : PT_LINETO)); } - for(j = 0; j < pDownPath->numEntriesUsed; j++) + for (j = 0; j < pDownPath->numEntriesUsed; j++) { POINT pt; pt.x = pDownPath->pPoints[pDownPath->numEntriesUsed - j - 1].x; pt.y = pDownPath->pPoints[pDownPath->numEntriesUsed - j - 1].y; - PATH_AddEntry(pNewPath, &pt, ( (j == 0 && (pStrokes[i]->pFlags[pStrokes[i]->numEntriesUsed - 1] & PT_CLOSEFIGURE)) ? PT_MOVETO : PT_LINETO)); + PATH_AddEntry(pNewPath, &pt, ((j == 0 && (pStrokes[i]->pFlags[pStrokes[i]->numEntriesUsed - 1] & PT_CLOSEFIGURE)) ? PT_MOVETO : PT_LINETO)); } PATH_DestroyGdiPath(pStrokes[i]); @@ -1968,7 +2085,10 @@ static inline INT int_from_fixed(FIXED f) static VOID FASTCALL -PATH_BezierTo(PPATH pPath, POINT *lppt, INT n) +PATH_BezierTo( + PPATH pPath, + POINT *lppt, + INT n) { if (n < 2) return; @@ -1993,17 +2113,17 @@ PATH_BezierTo(PPATH pPath, POINT *lppt, INT n) while (n > 2) { pt[0] = pt[2]; - pt[1] = lppt[i+1]; - pt[2].x = (lppt[i+2].x + lppt[i+1].x) / 2; - pt[2].y = (lppt[i+2].y + lppt[i+1].y) / 2; + pt[1] = lppt[i + 1]; + pt[2].x = (lppt[i + 2].x + lppt[i + 1].x) / 2; + pt[2].y = (lppt[i + 2].y + lppt[i + 1].y) / 2; PATH_BezierTo(pPath, pt, 3); n--; i++; } pt[0] = pt[2]; - pt[1] = lppt[i+1]; - pt[2] = lppt[i+2]; + pt[1] = lppt[i + 1]; + pt[2] = lppt[i + 2]; PATH_BezierTo(pPath, pt, 3); } } @@ -2011,98 +2131,103 @@ PATH_BezierTo(PPATH pPath, POINT *lppt, INT n) static BOOL FASTCALL -PATH_add_outline(PDC dc, INT x, INT y, TTPOLYGONHEADER *header, DWORD size) +PATH_add_outline( + PDC dc, + INT x, + INT y, + TTPOLYGONHEADER *header, + DWORD size) { - PPATH pPath; - TTPOLYGONHEADER *start; - POINT pt; - BOOL bResult = FALSE; + PPATH pPath; + TTPOLYGONHEADER *start; + POINT pt; + BOOL bResult = FALSE; - start = header; + start = header; - pPath = PATH_LockPath(dc->dclevel.hPath); - if (!pPath) - { - return FALSE; - } + pPath = PATH_LockPath(dc->dclevel.hPath); + if (!pPath) + { + return FALSE; + } - while ((char *)header < (char *)start + size) - { - TTPOLYCURVE *curve; + while ((char *)header < (char *)start + size) + { + TTPOLYCURVE *curve; - if (header->dwType != TT_POLYGON_TYPE) - { - DPRINT1("Unknown header type %lu\n", header->dwType); - goto cleanup; - } - - pt.x = x + int_from_fixed(header->pfxStart.x); - pt.y = y - int_from_fixed(header->pfxStart.y); - PATH_AddEntry(pPath, &pt, PT_MOVETO); - - curve = (TTPOLYCURVE *)(header + 1); - - while ((char *)curve < (char *)header + header->cb) - { - /*DPRINT1("curve->wType %d\n", curve->wType);*/ - - switch(curve->wType) + if (header->dwType != TT_POLYGON_TYPE) { - case TT_PRIM_LINE: - { - WORD i; - - for (i = 0; i < curve->cpfx; i++) - { - pt.x = x + int_from_fixed(curve->apfx[i].x); - pt.y = y - int_from_fixed(curve->apfx[i].y); - PATH_AddEntry(pPath, &pt, PT_LINETO); - } - break; - } - - case TT_PRIM_QSPLINE: - case TT_PRIM_CSPLINE: - { - WORD i; - POINTFX ptfx; - POINT *pts = ExAllocatePoolWithTag(PagedPool, (curve->cpfx + 1) * sizeof(POINT), TAG_PATH); - - if (!pts) goto cleanup; - - ptfx = *(POINTFX *)((char *)curve - sizeof(POINTFX)); - - pts[0].x = x + int_from_fixed(ptfx.x); - pts[0].y = y - int_from_fixed(ptfx.y); - - for (i = 0; i < curve->cpfx; i++) - { - pts[i + 1].x = x + int_from_fixed(curve->apfx[i].x); - pts[i + 1].y = y - int_from_fixed(curve->apfx[i].y); - } - - PATH_BezierTo(pPath, pts, curve->cpfx + 1); - - ExFreePoolWithTag(pts, TAG_PATH); - break; - } - - default: - DPRINT1("Unknown curve type %04x\n", curve->wType); - goto cleanup; + DPRINT1("Unknown header type %lu\n", header->dwType); + goto cleanup; } - curve = (TTPOLYCURVE *)&curve->apfx[curve->cpfx]; - } - header = (TTPOLYGONHEADER *)((char *)header + header->cb); - } + pt.x = x + int_from_fixed(header->pfxStart.x); + pt.y = y - int_from_fixed(header->pfxStart.y); + PATH_AddEntry(pPath, &pt, PT_MOVETO); - bResult = TRUE; + curve = (TTPOLYCURVE *)(header + 1); + + while ((char *)curve < (char *)header + header->cb) + { + /*DPRINT1("curve->wType %d\n", curve->wType);*/ + + switch(curve->wType) + { + case TT_PRIM_LINE: + { + WORD i; + + for (i = 0; i < curve->cpfx; i++) + { + pt.x = x + int_from_fixed(curve->apfx[i].x); + pt.y = y - int_from_fixed(curve->apfx[i].y); + PATH_AddEntry(pPath, &pt, PT_LINETO); + } + break; + } + + case TT_PRIM_QSPLINE: + case TT_PRIM_CSPLINE: + { + WORD i; + POINTFX ptfx; + POINT *pts = ExAllocatePoolWithTag(PagedPool, (curve->cpfx + 1) * sizeof(POINT), TAG_PATH); + + if (!pts) goto cleanup; + + ptfx = *(POINTFX *)((char *)curve - sizeof(POINTFX)); + + pts[0].x = x + int_from_fixed(ptfx.x); + pts[0].y = y - int_from_fixed(ptfx.y); + + for (i = 0; i < curve->cpfx; i++) + { + pts[i + 1].x = x + int_from_fixed(curve->apfx[i].x); + pts[i + 1].y = y - int_from_fixed(curve->apfx[i].y); + } + + PATH_BezierTo(pPath, pts, curve->cpfx + 1); + + ExFreePoolWithTag(pts, TAG_PATH); + break; + } + + default: + DPRINT1("Unknown curve type %04x\n", curve->wType); + goto cleanup; + } + + curve = (TTPOLYCURVE *)&curve->apfx[curve->cpfx]; + } + header = (TTPOLYGONHEADER *)((char *)header + header->cb); + } + + bResult = TRUE; cleanup: - IntGdiCloseFigure( pPath ); - PATH_UnlockPath( pPath ); - return bResult; + IntGdiCloseFigure(pPath); + PATH_UnlockPath(pPath); + return bResult; } /********************************************************************** @@ -2110,8 +2235,15 @@ cleanup: */ BOOL FASTCALL -PATH_ExtTextOut(PDC dc, INT x, INT y, UINT flags, const RECTL *lprc, - LPCWSTR str, UINT count, const INT *dx) +PATH_ExtTextOut( + PDC dc, + INT x, + INT y, + UINT flags, + const RECTL *lprc, + LPCWSTR str, + UINT count, + const INT *dx) { unsigned int idx; POINT offset = {0, 0}; @@ -2120,28 +2252,28 @@ PATH_ExtTextOut(PDC dc, INT x, INT y, UINT flags, const RECTL *lprc, for (idx = 0; idx < count; idx++) { - MAT2 identity = { {0,1},{0,0},{0,0},{0,1} }; + MAT2 identity = { {0, 1}, {0, 0}, {0, 0}, {0, 1} }; GLYPHMETRICS gm; DWORD dwSize; void *outline; - dwSize = ftGdiGetGlyphOutline( dc, - str[idx], - GGO_GLYPH_INDEX | GGO_NATIVE, - &gm, - 0, - NULL, - &identity, - TRUE); + dwSize = ftGdiGetGlyphOutline(dc, + str[idx], + GGO_GLYPH_INDEX | GGO_NATIVE, + &gm, + 0, + NULL, + &identity, + TRUE); if (dwSize == GDI_ERROR) return FALSE; /* Add outline only if char is printable */ if (dwSize) { - outline = ExAllocatePoolWithTag(PagedPool, dwSize, TAG_PATH); - if (!outline) return FALSE; + outline = ExAllocatePoolWithTag(PagedPool, dwSize, TAG_PATH); + if (!outline) return FALSE; - ftGdiGetGlyphOutline( dc, + ftGdiGetGlyphOutline(dc, str[idx], GGO_GLYPH_INDEX | GGO_NATIVE, &gm, @@ -2150,25 +2282,25 @@ PATH_ExtTextOut(PDC dc, INT x, INT y, UINT flags, const RECTL *lprc, &identity, TRUE); - PATH_add_outline(dc, x + offset.x, y + offset.y, outline, dwSize); + PATH_add_outline(dc, x + offset.x, y + offset.y, outline, dwSize); - ExFreePoolWithTag(outline, TAG_PATH); + ExFreePoolWithTag(outline, TAG_PATH); } if (dx) { - if (flags & ETO_PDY) - { - offset.x += dx[idx * 2]; - offset.y += dx[idx * 2 + 1]; - } - else - offset.x += dx[idx]; + if (flags & ETO_PDY) + { + offset.x += dx[idx * 2]; + offset.y += dx[idx * 2 + 1]; + } + else + offset.x += dx[idx]; } else { - offset.x += gm.gmCellIncX; - offset.y += gm.gmCellIncY; + offset.x += gm.gmCellIncX; + offset.y += gm.gmCellIncY; } } return TRUE; @@ -2181,252 +2313,258 @@ PATH_ExtTextOut(PDC dc, INT x, INT y, UINT flags, const RECTL *lprc, BOOL APIENTRY -NtGdiAbortPath(HDC hDC) +NtGdiAbortPath(HDC hDC) { - PPATH pPath; - PDC dc = DC_LockDc ( hDC ); - if ( !dc ) - { - EngSetLastError(ERROR_INVALID_HANDLE); - return FALSE; - } + PPATH pPath; + PDC dc = DC_LockDc(hDC); + if (!dc) + { + EngSetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } - pPath = PATH_LockPath(dc->dclevel.hPath); - if (!pPath) - { - DC_UnlockDc(dc); - return FALSE; - } + pPath = PATH_LockPath(dc->dclevel.hPath); + if (!pPath) + { + DC_UnlockDc(dc); + return FALSE; + } - PATH_EmptyPath(pPath); + PATH_EmptyPath(pPath); - PATH_UnlockPath(pPath); - dc->dclevel.flPath &= ~DCPATH_ACTIVE; + PATH_UnlockPath(pPath); + dc->dclevel.flPath &= ~DCPATH_ACTIVE; - DC_UnlockDc ( dc ); - return TRUE; + DC_UnlockDc(dc); + return TRUE; } BOOL APIENTRY -NtGdiBeginPath( HDC hDC ) +NtGdiBeginPath(HDC hDC) { - PPATH pPath; - PDC dc; + PPATH pPath; + PDC dc; - dc = DC_LockDc ( hDC ); - if ( !dc ) - { - EngSetLastError(ERROR_INVALID_HANDLE); - return FALSE; - } + dc = DC_LockDc(hDC); + if (!dc) + { + EngSetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } - /* If path is already open, do nothing. Check if not Save DC state */ + /* If path is already open, do nothing. Check if not Save DC state */ if ((dc->dclevel.flPath & DCPATH_ACTIVE) && !(dc->dclevel.flPath & DCPATH_SAVE)) - { - DC_UnlockDc ( dc ); - return TRUE; - } + { + DC_UnlockDc(dc); + return TRUE; + } - if ( dc->dclevel.hPath ) - { - DPRINT("BeginPath 1 0x%p\n", dc->dclevel.hPath); - if ( !(dc->dclevel.flPath & DCPATH_SAVE) ) - { // Remove previous handle. - if (!PATH_Delete(dc->dclevel.hPath)) + if (dc->dclevel.hPath) + { + DPRINT("BeginPath 1 0x%p\n", dc->dclevel.hPath); + if (!(dc->dclevel.flPath & DCPATH_SAVE)) { - DC_UnlockDc ( dc ); - return FALSE; + // Remove previous handle. + if (!PATH_Delete(dc->dclevel.hPath)) + { + DC_UnlockDc(dc); + return FALSE; + } } - } - else - { // Clear flags and Handle. - dc->dclevel.flPath &= ~(DCPATH_SAVE|DCPATH_ACTIVE); - dc->dclevel.hPath = NULL; - } - } - pPath = PATH_AllocPathWithHandle(); - if (!pPath) - { - EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } - dc->dclevel.flPath |= DCPATH_ACTIVE; // Set active ASAP! + else + { + // Clear flags and Handle. + dc->dclevel.flPath &= ~(DCPATH_SAVE | DCPATH_ACTIVE); + dc->dclevel.hPath = NULL; + } + } + pPath = PATH_AllocPathWithHandle(); + if (!pPath) + { + EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); + return FALSE; + } + dc->dclevel.flPath |= DCPATH_ACTIVE; // Set active ASAP! - dc->dclevel.hPath = pPath->BaseObject.hHmgr; + dc->dclevel.hPath = pPath->BaseObject.hHmgr; - DPRINT("BeginPath 2 h 0x%p p 0x%p\n", dc->dclevel.hPath, pPath); - // Path handles are shared. Also due to recursion with in the same thread. - GDIOBJ_vUnlockObject((POBJ)pPath); // Unlock - pPath = PATH_LockPath(dc->dclevel.hPath); // Share Lock. + DPRINT("BeginPath 2 h 0x%p p 0x%p\n", dc->dclevel.hPath, pPath); + // Path handles are shared. Also due to recursion with in the same thread. + GDIOBJ_vUnlockObject((POBJ)pPath); // Unlock + pPath = PATH_LockPath(dc->dclevel.hPath); // Share Lock. - /* Make sure that path is empty */ - PATH_EmptyPath( pPath ); + /* Make sure that path is empty */ + PATH_EmptyPath(pPath); - /* Initialize variables for new path */ - pPath->newStroke = TRUE; - pPath->state = PATH_Open; + /* Initialize variables for new path */ + pPath->newStroke = TRUE; + pPath->state = PATH_Open; - PATH_UnlockPath(pPath); - DC_UnlockDc ( dc ); - return TRUE; + PATH_UnlockPath(pPath); + DC_UnlockDc(dc); + return TRUE; } BOOL APIENTRY NtGdiCloseFigure(HDC hDC) { - BOOL Ret = FALSE; // Default to failure - PDC pDc; - PPATH pPath; + BOOL Ret = FALSE; // Default to failure + PDC pDc; + PPATH pPath; - DPRINT("Enter %s\n", __FUNCTION__); + DPRINT("Enter %s\n", __FUNCTION__); - pDc = DC_LockDc(hDC); - if (!pDc) - { - EngSetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - pPath = PATH_LockPath( pDc->dclevel.hPath ); - if (!pPath) - { - DC_UnlockDc(pDc); - return FALSE; - } + pDc = DC_LockDc(hDC); + if (!pDc) + { + EngSetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } - if (pPath->state==PATH_Open) - { - IntGdiCloseFigure(pPath); - Ret = TRUE; - } - else - { - // FIXME: Check if lasterror is set correctly - EngSetLastError(ERROR_CAN_NOT_COMPLETE); - } + pPath = PATH_LockPath(pDc->dclevel.hPath); + if (!pPath) + { + DC_UnlockDc(pDc); + return FALSE; + } - PATH_UnlockPath( pPath ); - DC_UnlockDc(pDc); - return Ret; + if (pPath->state == PATH_Open) + { + IntGdiCloseFigure(pPath); + Ret = TRUE; + } + else + { + // FIXME: Check if lasterror is set correctly + EngSetLastError(ERROR_CAN_NOT_COMPLETE); + } + + PATH_UnlockPath(pPath); + DC_UnlockDc(pDc); + return Ret; } BOOL APIENTRY NtGdiEndPath(HDC hDC) { - BOOL ret = TRUE; - PPATH pPath; - PDC dc = DC_LockDc ( hDC ); + BOOL ret = TRUE; + PPATH pPath; + PDC dc; - if ( !dc ) - { - EngSetLastError(ERROR_INVALID_HANDLE); - return FALSE; - } + dc = DC_LockDc(hDC); + if (!dc) + { + EngSetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } - pPath = PATH_LockPath( dc->dclevel.hPath ); - if (!pPath) - { - DC_UnlockDc ( dc ); - return FALSE; - } - /* Check that path is currently being constructed */ - if ( (pPath->state != PATH_Open) || !(dc->dclevel.flPath & DCPATH_ACTIVE) ) - { - DPRINT1("EndPath ERROR! 0x%p\n", dc->dclevel.hPath); - EngSetLastError(ERROR_CAN_NOT_COMPLETE); - ret = FALSE; - } - /* Set flag to indicate that path is finished */ - else - { - DPRINT("EndPath 0x%p\n", dc->dclevel.hPath); - pPath->state = PATH_Closed; - dc->dclevel.flPath &= ~DCPATH_ACTIVE; - } - PATH_UnlockPath( pPath ); - DC_UnlockDc ( dc ); - return ret; + pPath = PATH_LockPath(dc->dclevel.hPath); + if (!pPath) + { + DC_UnlockDc(dc); + return FALSE; + } + + /* Check that path is currently being constructed */ + if ((pPath->state != PATH_Open) || !(dc->dclevel.flPath & DCPATH_ACTIVE)) + { + DPRINT1("EndPath ERROR! 0x%p\n", dc->dclevel.hPath); + EngSetLastError(ERROR_CAN_NOT_COMPLETE); + ret = FALSE; + } + /* Set flag to indicate that path is finished */ + else + { + DPRINT("EndPath 0x%p\n", dc->dclevel.hPath); + pPath->state = PATH_Closed; + dc->dclevel.flPath &= ~DCPATH_ACTIVE; + } + + PATH_UnlockPath(pPath); + DC_UnlockDc(dc); + return ret; } BOOL APIENTRY NtGdiFillPath(HDC hDC) { - BOOL ret = FALSE; - PPATH pPath; - PDC_ATTR pdcattr; - PDC dc; + BOOL ret = FALSE; + PPATH pPath; + PDC_ATTR pdcattr; + PDC dc; - dc = DC_LockDc(hDC); - if (!dc) - { - EngSetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } + dc = DC_LockDc(hDC); + if (!dc) + { + EngSetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } - pPath = PATH_LockPath( dc->dclevel.hPath ); - if (!pPath) - { - DC_UnlockDc ( dc ); - return FALSE; - } + pPath = PATH_LockPath(dc->dclevel.hPath); + if (!pPath) + { + DC_UnlockDc(dc); + return FALSE; + } - DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds, - NULL, dc->rosdc.CombinedClip->rclBounds); + DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds, + NULL, dc->rosdc.CombinedClip->rclBounds); - pdcattr = dc->pdcattr; + pdcattr = dc->pdcattr; - if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY)) - DC_vUpdateLineBrush(dc); + if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY)) + DC_vUpdateLineBrush(dc); - if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)) - DC_vUpdateFillBrush(dc); + if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)) + DC_vUpdateFillBrush(dc); - ret = PATH_FillPath( dc, pPath ); - if ( ret ) - { - /* FIXME: Should the path be emptied even if conversion - failed? */ - PATH_EmptyPath( pPath ); - } + ret = PATH_FillPath(dc, pPath); + if (ret) + { + /* FIXME: Should the path be emptied even if conversion + failed? */ + PATH_EmptyPath(pPath); + } - PATH_UnlockPath( pPath ); - DC_vFinishBlit(dc, NULL); - DC_UnlockDc ( dc ); - return ret; + PATH_UnlockPath(pPath); + DC_vFinishBlit(dc, NULL); + DC_UnlockDc(dc); + return ret; } BOOL APIENTRY -NtGdiFlattenPath(HDC hDC) +NtGdiFlattenPath(HDC hDC) { - BOOL Ret = FALSE; - DC *pDc; - PPATH pPath; + BOOL Ret = FALSE; + DC *pDc; + PPATH pPath; - DPRINT("Enter %s\n", __FUNCTION__); + DPRINT("Enter %s\n", __FUNCTION__); - pDc = DC_LockDc(hDC); - if (!pDc) - { - EngSetLastError(ERROR_INVALID_HANDLE); - return FALSE; - } + pDc = DC_LockDc(hDC); + if (!pDc) + { + EngSetLastError(ERROR_INVALID_HANDLE); + return FALSE; + } - pPath = PATH_LockPath( pDc->dclevel.hPath ); - if (!pPath) - { - DC_UnlockDc ( pDc ); - return FALSE; - } - if (pPath->state == PATH_Open) - Ret = PATH_FlattenPath(pPath); + pPath = PATH_LockPath(pDc->dclevel.hPath); + if (!pPath) + { + DC_UnlockDc(pDc); + return FALSE; + } + if (pPath->state == PATH_Open) + Ret = PATH_FlattenPath(pPath); - PATH_UnlockPath( pPath ); - DC_UnlockDc(pDc); - return Ret; + PATH_UnlockPath(pPath); + DC_UnlockDc(pDc); + return Ret; } _Success_(return != FALSE) @@ -2436,144 +2574,144 @@ NtGdiGetMiterLimit( _In_ HDC hdc, _Out_ PDWORD pdwOut) { - DC *pDc; - BOOL bResult = TRUE; + DC *pDc; + BOOL bResult = TRUE; - if (!(pDc = DC_LockDc(hdc))) - { - EngSetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } + if (!(pDc = DC_LockDc(hdc))) + { + EngSetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } - _SEH2_TRY - { - ProbeForWrite(pdwOut, sizeof(DWORD), 1); - *pdwOut = pDc->dclevel.laPath.eMiterLimit; - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - SetLastNtError(_SEH2_GetExceptionCode()); - bResult = FALSE; - } - _SEH2_END; + _SEH2_TRY + { + ProbeForWrite(pdwOut, sizeof(DWORD), 1); + *pdwOut = pDc->dclevel.laPath.eMiterLimit; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + SetLastNtError(_SEH2_GetExceptionCode()); + bResult = FALSE; + } + _SEH2_END; - DC_UnlockDc(pDc); - return bResult; + DC_UnlockDc(pDc); + return bResult; } INT APIENTRY NtGdiGetPath( - HDC hDC, - LPPOINT Points, - LPBYTE Types, - INT nSize) + HDC hDC, + LPPOINT Points, + LPBYTE Types, + INT nSize) { - INT ret = -1; - PPATH pPath; + INT ret = -1; + PPATH pPath; - DC *dc = DC_LockDc(hDC); - if (!dc) - { - DPRINT1("Can't lock dc!\n"); - EngSetLastError(ERROR_INVALID_PARAMETER); - return -1; - } + DC *dc = DC_LockDc(hDC); + if (!dc) + { + DPRINT1("Can't lock dc!\n"); + EngSetLastError(ERROR_INVALID_PARAMETER); + return -1; + } - pPath = PATH_LockPath( dc->dclevel.hPath ); - if (!pPath) - { - DC_UnlockDc ( dc ); - return -1; - } + pPath = PATH_LockPath(dc->dclevel.hPath); + if (!pPath) + { + DC_UnlockDc(dc); + return -1; + } - if (pPath->state != PATH_Closed) - { - EngSetLastError(ERROR_CAN_NOT_COMPLETE); - goto done; - } + if (pPath->state != PATH_Closed) + { + EngSetLastError(ERROR_CAN_NOT_COMPLETE); + goto done; + } - if (nSize==0) - { - ret = pPath->numEntriesUsed; - } - else if(nSizenumEntriesUsed) - { - EngSetLastError(ERROR_INVALID_PARAMETER); - goto done; - } - else - { - _SEH2_TRY - { - memcpy(Points, pPath->pPoints, sizeof(POINT)*pPath->numEntriesUsed); - memcpy(Types, pPath->pFlags, sizeof(BYTE)*pPath->numEntriesUsed); + if (nSize == 0) + { + ret = pPath->numEntriesUsed; + } + else if (nSize < pPath->numEntriesUsed) + { + EngSetLastError(ERROR_INVALID_PARAMETER); + goto done; + } + else + { + _SEH2_TRY + { + memcpy(Points, pPath->pPoints, sizeof(POINT)*pPath->numEntriesUsed); + memcpy(Types, pPath->pFlags, sizeof(BYTE)*pPath->numEntriesUsed); - /* Convert the points to logical coordinates */ - if (!GdiPathDPtoLP(dc, Points, pPath->numEntriesUsed)) - { - EngSetLastError(ERROR_ARITHMETIC_OVERFLOW); - _SEH2_LEAVE; - } + /* Convert the points to logical coordinates */ + if (!GdiPathDPtoLP(dc, Points, pPath->numEntriesUsed)) + { + EngSetLastError(ERROR_ARITHMETIC_OVERFLOW); + _SEH2_LEAVE; + } - ret = pPath->numEntriesUsed; - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - SetLastNtError(_SEH2_GetExceptionCode()); - } - _SEH2_END - } + ret = pPath->numEntriesUsed; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + SetLastNtError(_SEH2_GetExceptionCode()); + } + _SEH2_END + } done: - PATH_UnlockPath( pPath ); - DC_UnlockDc(dc); - return ret; + PATH_UnlockPath(pPath); + DC_UnlockDc(dc); + return ret; } HRGN APIENTRY NtGdiPathToRegion(HDC hDC) { - PPATH pPath; - HRGN hrgnRval = 0; - DC *pDc; - PDC_ATTR pdcattr; + PPATH pPath; + HRGN hrgnRval = 0; + DC *pDc; + PDC_ATTR pdcattr; - DPRINT("Enter %s\n", __FUNCTION__); + DPRINT("Enter %s\n", __FUNCTION__); - pDc = DC_LockDc(hDC); - if (!pDc) - { - EngSetLastError(ERROR_INVALID_PARAMETER); - return NULL; - } + pDc = DC_LockDc(hDC); + if (!pDc) + { + EngSetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } - pdcattr = pDc->pdcattr; + pdcattr = pDc->pdcattr; - pPath = PATH_LockPath( pDc->dclevel.hPath ); - if (!pPath) - { - DC_UnlockDc ( pDc ); - return NULL; - } + pPath = PATH_LockPath(pDc->dclevel.hPath); + if (!pPath) + { + DC_UnlockDc(pDc); + return NULL; + } - if (pPath->state!=PATH_Closed) - { - // FIXME: Check that setlasterror is being called correctly - EngSetLastError(ERROR_CAN_NOT_COMPLETE); - } - else - { - /* FIXME: Should we empty the path even if conversion failed? */ - if(PATH_PathToRegion(pPath, pdcattr->jFillMode, &hrgnRval)) - PATH_EmptyPath(pPath); - } + if (pPath->state != PATH_Closed) + { + // FIXME: Check that setlasterror is being called correctly + EngSetLastError(ERROR_CAN_NOT_COMPLETE); + } + else + { + /* FIXME: Should we empty the path even if conversion failed? */ + if (PATH_PathToRegion(pPath, pdcattr->jFillMode, &hrgnRval)) + PATH_EmptyPath(pPath); + } - PATH_UnlockPath( pPath ); - DC_UnlockDc(pDc); - return hrgnRval; + PATH_UnlockPath(pPath); + DC_UnlockDc(pDc); + return hrgnRval; } BOOL @@ -2583,138 +2721,140 @@ NtGdiSetMiterLimit( IN DWORD dwNew, IN OUT OPTIONAL PDWORD pdwOut) { - DC *pDc; - gxf_long worker, worker1; - BOOL bResult = TRUE; + DC *pDc; + gxf_long worker, worker1; + BOOL bResult = TRUE; - if (!(pDc = DC_LockDc(hdc))) - { - EngSetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } + if (!(pDc = DC_LockDc(hdc))) + { + EngSetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } - worker.l = dwNew; - worker1.f = pDc->dclevel.laPath.eMiterLimit; - pDc->dclevel.laPath.eMiterLimit = worker.f; + worker.l = dwNew; + worker1.f = pDc->dclevel.laPath.eMiterLimit; + pDc->dclevel.laPath.eMiterLimit = worker.f; - if (pdwOut) - { - _SEH2_TRY - { - ProbeForWrite(pdwOut, sizeof(DWORD), 1); - *pdwOut = worker1.l; - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - SetLastNtError(_SEH2_GetExceptionCode()); - bResult = FALSE; - } - _SEH2_END; - } + if (pdwOut) + { + _SEH2_TRY + { + ProbeForWrite(pdwOut, sizeof(DWORD), 1); + *pdwOut = worker1.l; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + SetLastNtError(_SEH2_GetExceptionCode()); + bResult = FALSE; + } + _SEH2_END; + } - DC_UnlockDc(pDc); - return bResult; + DC_UnlockDc(pDc); + return bResult; } BOOL APIENTRY NtGdiStrokeAndFillPath(HDC hDC) { - DC *pDc; - PDC_ATTR pdcattr; - PPATH pPath; - BOOL bRet = FALSE; + DC *pDc; + PDC_ATTR pdcattr; + PPATH pPath; + BOOL bRet = FALSE; - DPRINT1("Enter %s\n", __FUNCTION__); + DPRINT1("Enter %s\n", __FUNCTION__); - if (!(pDc = DC_LockDc(hDC))) - { - EngSetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - pPath = PATH_LockPath( pDc->dclevel.hPath ); - if (!pPath) - { - DC_UnlockDc ( pDc ); - return FALSE; - } + if (!(pDc = DC_LockDc(hDC))) + { + EngSetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + pPath = PATH_LockPath(pDc->dclevel.hPath); + if (!pPath) + { + DC_UnlockDc(pDc); + return FALSE; + } - DC_vPrepareDCsForBlit(pDc, pDc->rosdc.CombinedClip->rclBounds, - NULL, pDc->rosdc.CombinedClip->rclBounds); + DC_vPrepareDCsForBlit(pDc, pDc->rosdc.CombinedClip->rclBounds, + NULL, pDc->rosdc.CombinedClip->rclBounds); - pdcattr = pDc->pdcattr; + pdcattr = pDc->pdcattr; - if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)) - DC_vUpdateFillBrush(pDc); + if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY)) + DC_vUpdateFillBrush(pDc); - if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY)) - DC_vUpdateLineBrush(pDc); + if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY)) + DC_vUpdateLineBrush(pDc); - bRet = PATH_FillPath(pDc, pPath); - if (bRet) bRet = PATH_StrokePath(pDc, pPath); - if (bRet) PATH_EmptyPath(pPath); + bRet = PATH_FillPath(pDc, pPath); + if (bRet) bRet = PATH_StrokePath(pDc, pPath); + if (bRet) PATH_EmptyPath(pPath); - PATH_UnlockPath( pPath ); - DC_vFinishBlit(pDc, NULL); - DC_UnlockDc(pDc); - return bRet; + PATH_UnlockPath(pPath); + DC_vFinishBlit(pDc, NULL); + DC_UnlockDc(pDc); + return bRet; } BOOL APIENTRY NtGdiStrokePath(HDC hDC) { - DC *pDc; - PDC_ATTR pdcattr; - PPATH pPath; - BOOL bRet = FALSE; + DC *pDc; + PDC_ATTR pdcattr; + PPATH pPath; + BOOL bRet = FALSE; - DPRINT("Enter %s\n", __FUNCTION__); + DPRINT("Enter %s\n", __FUNCTION__); - if (!(pDc = DC_LockDc(hDC))) - { - EngSetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - pPath = PATH_LockPath( pDc->dclevel.hPath ); - if (!pPath) - { - DC_UnlockDc ( pDc ); - return FALSE; - } + if (!(pDc = DC_LockDc(hDC))) + { + EngSetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } - DC_vPrepareDCsForBlit(pDc, pDc->rosdc.CombinedClip->rclBounds, - NULL, pDc->rosdc.CombinedClip->rclBounds); + pPath = PATH_LockPath(pDc->dclevel.hPath); + if (!pPath) + { + DC_UnlockDc(pDc); + return FALSE; + } - pdcattr = pDc->pdcattr; + DC_vPrepareDCsForBlit(pDc, pDc->rosdc.CombinedClip->rclBounds, + NULL, pDc->rosdc.CombinedClip->rclBounds); - if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY)) - DC_vUpdateLineBrush(pDc); + pdcattr = pDc->pdcattr; - bRet = PATH_StrokePath(pDc, pPath); + if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY)) + DC_vUpdateLineBrush(pDc); - DC_vFinishBlit(pDc, NULL); - PATH_EmptyPath(pPath); + bRet = PATH_StrokePath(pDc, pPath); - PATH_UnlockPath( pPath ); - DC_UnlockDc(pDc); - return bRet; + DC_vFinishBlit(pDc, NULL); + PATH_EmptyPath(pPath); + + PATH_UnlockPath(pPath); + DC_UnlockDc(pDc); + return bRet; } BOOL APIENTRY NtGdiWidenPath(HDC hDC) { - BOOL Ret; - PDC pdc = DC_LockDc ( hDC ); - if ( !pdc ) - { - EngSetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - Ret = PATH_WidenPath(pdc); - DC_UnlockDc ( pdc ); - return Ret; + BOOL Ret; + PDC pdc = DC_LockDc(hDC); + if (!pdc) + { + EngSetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + Ret = PATH_WidenPath(pdc); + DC_UnlockDc(pdc); + return Ret; } /* EOF */ diff --git a/win32ss/gdi/ntgdi/rect.h b/win32ss/gdi/ntgdi/rect.h index df601c92b3d..419547c06ab 100644 --- a/win32ss/gdi/ntgdi/rect.h +++ b/win32ss/gdi/ntgdi/rect.h @@ -1,7 +1,7 @@ #pragma once -VOID FORCEINLINE +VOID RECTL_vSetRect(RECTL *prcl, LONG left, LONG top, LONG right, LONG bottom) { prcl->left = left; @@ -10,8 +10,8 @@ RECTL_vSetRect(RECTL *prcl, LONG left, LONG top, LONG right, LONG bottom) prcl->bottom = bottom; } -VOID FORCEINLINE +VOID RECTL_vSetEmptyRect(RECTL *prcl) { prcl->left = 0; @@ -20,8 +20,8 @@ RECTL_vSetEmptyRect(RECTL *prcl) prcl->bottom = 0; } -VOID FORCEINLINE +VOID RECTL_vOffsetRect(RECTL *prcl, INT cx, INT cy) { prcl->left += cx; @@ -30,23 +30,23 @@ RECTL_vOffsetRect(RECTL *prcl, INT cx, INT cy) prcl->bottom += cy; } -BOOL FORCEINLINE +BOOL RECTL_bIsEmptyRect(const RECTL *prcl) { return (prcl->left >= prcl->right || prcl->top >= prcl->bottom); } -BOOL FORCEINLINE +BOOL RECTL_bPointInRect(const RECTL *prcl, INT x, INT y) { return (x >= prcl->left && x < prcl->right && y >= prcl->top && y < prcl->bottom); } -BOOL FORCEINLINE +BOOL RECTL_bIsWellOrdered(const RECTL *prcl) { return ((prcl->left <= prcl->right) && diff --git a/win32ss/gdi/ntgdi/text.h b/win32ss/gdi/ntgdi/text.h index 7abb55390ce..a528dd895d9 100644 --- a/win32ss/gdi/ntgdi/text.h +++ b/win32ss/gdi/ntgdi/text.h @@ -80,8 +80,8 @@ typedef struct _LFONT #define LFONT_ShareUnlockFont(plfnt) GDIOBJ_vDereferenceObject((POBJ)plfnt) #define LFONT_UnlockFont(plfnt) GDIOBJ_vUnlockObject((POBJ)plfnt) -PTEXTOBJ FORCEINLINE +PTEXTOBJ TEXTOBJ_LockText(HFONT hfont) { PLFONT plfnt = LFONT_ShareLockFont(hfont); @@ -93,8 +93,8 @@ TEXTOBJ_LockText(HFONT hfont) return plfnt; } -VOID FORCEINLINE +VOID TEXTOBJ_UnlockText(PLFONT plfnt) { ExReleasePushLockExclusive(&plfnt->lock); diff --git a/win32ss/include/ntuser.h b/win32ss/include/ntuser.h index 79a8c287b2f..e1ed1608429 100644 --- a/win32ss/include/ntuser.h +++ b/win32ss/include/ntuser.h @@ -5,6 +5,7 @@ typedef struct _PROCESSINFO *PPROCESSINFO; typedef struct _THREADINFO *PTHREADINFO; struct _DESKTOP; struct _WND; +struct tagPOPUPMENU; #define FIRST_USER_HANDLE 0x0020 /* first possible value for low word of user handle */ #define LAST_USER_HANDLE 0xffef /* last possible value for low word of user handle */ @@ -313,7 +314,7 @@ typedef struct tagITEM struct tagMENU* spSubMenu; /* Pop-up menu. */ HANDLE hbmpChecked; HANDLE hbmpUnchecked; - USHORT* lpstr; /* Item text pointer. */ + USHORT* Xlpstr; /* Item text pointer. */ ULONG cch; DWORD_PTR dwItemData; ULONG xItem; /* Item position. left */ @@ -326,6 +327,9 @@ typedef struct tagITEM HBITMAP hbmp; /* bitmap */ INT cxBmp; /* Width Maximum size of the bitmap items in MIIM_BITMAP state */ INT cyBmp; /* Height " */ + //// ReactOS + UNICODE_STRING lpstr; + struct tagITEM *Next; } ITEM, *PITEM; typedef struct tagMENULIST @@ -347,7 +351,7 @@ typedef struct tagMENU { PROCDESKHEAD head; ULONG fFlags; /* [Style flags | Menu flags] */ - INT iItem; /* nPos of selected item, if -1 not selected. */ + INT iItem; /* nPos of selected item, if -1 not selected. AKA focused item */ UINT cAlloced; /* Number of allocated items. Inc's of 8 */ UINT cItems; /* Number of items in the menu */ ULONG cxMenu; /* Width of the whole menu */ @@ -363,8 +367,54 @@ typedef struct tagMENU INT iTop; /* Current scroll position Top */ INT iMaxTop; /* Current scroll position Max Top */ DWORD dwArrowsOn:2; /* Arrows: 0 off, 1 on, 2 to the top, 3 to the bottom. */ + //// ReactOS + LIST_ENTRY ListEntry; + HWND hWnd; /* Window containing the menu */ + BOOL TimeToHide; } MENU, *PMENU; +typedef struct tagPOPUPMENU +{ + ULONG fIsMenuBar:1; + ULONG fHasMenuBar:1; + ULONG fIsSysMenu:1; + ULONG fIsTrackPopup:1; + ULONG fDroppedLeft:1; + ULONG fHierarchyDropped:1; + ULONG fRightButton:1; + ULONG fToggle:1; + ULONG fSynchronous:1; + ULONG fFirstClick:1; + ULONG fDropNextPopup:1; + ULONG fNoNotify:1; + ULONG fAboutToHide:1; + ULONG fShowTimer:1; + ULONG fHideTimer:1; + ULONG fDestroyed:1; + ULONG fDelayedFree:1; + ULONG fFlushDelayedFree:1; + ULONG fFreed:1; + ULONG fInCancel:1; + ULONG fTrackMouseEvent:1; + ULONG fSendUninit:1; + ULONG fRtoL:1; +// ULONG fDesktopMenu:1; + ULONG iDropDir:5; + ULONG fUseMonitorRect:1; + struct _WND *spwndNotify; + struct _WND *spwndPopupMenu; + struct _WND *spwndNextPopup; + struct _WND *spwndPrevPopup; + PMENU spmenu; + PMENU spmenuAlternate; + struct _WND *spwndActivePopup; + struct tagPOPUPMENU *ppopupmenuRoot; + struct tagPOPUPMENU *ppmDelayedFree; + UINT posSelectedItem; + UINT posDropped; +} POPUPMENU, *PPOPUPMENU; + + typedef struct _REGISTER_SYSCLASS { /* This is a reactos specific class used to initialize the @@ -657,6 +707,12 @@ typedef struct _SBWND SBCALC SBCalc; } SBWND, *PSBWND; +typedef struct _MENUWND +{ + WND wnd; + PPOPUPMENU ppopupmenu; +} MENUWND, *PMENUWND; + typedef struct _PFNCLIENT { WNDPROC pfnScrollBarWndProc; @@ -3277,11 +3333,6 @@ NtUserWin32PoolAllocationStats( DWORD Unknown4, DWORD Unknown5); -HWND -NTAPI -NtUserWindowFromPhysicalPoint( - POINT Point); - HWND NTAPI NtUserWindowFromPoint( @@ -3334,21 +3385,6 @@ typedef struct tagKMDDELPARAM #define TWOPARAM_ROUTINE_ROS_UPDATEUISTATE 0x1004 #define HWNDPARAM_ROUTINE_ROS_NOTIFYWINEVENT 0x1005 -DWORD -NTAPI -NtUserBuildMenuItemList( - HMENU hMenu, - PVOID Buffer, - ULONG nBufSize, - DWORD Reserved); - -UINT -NTAPI -NtUserGetMenuDefaultItem( - HMENU hMenu, - UINT fByPos, - UINT gmdiFlags); - BOOL NTAPI NtUserGetMonitorInfo( @@ -3371,25 +3407,21 @@ typedef struct tagROSMENUINFO DWORD dwContextHelpID; ULONG_PTR dwMenuData; /* ----------- Extra ----------- */ - HMENU Self; /* Handle of this menu */ - WORD Flags; /* Menu flags (MF_POPUP, MF_SYSMENU) */ - UINT FocusedItem; /* Currently focused item */ - UINT MenuItemCount; /* Number of items in the menu */ - HWND Wnd; /* Window containing the menu */ - WORD Width; /* Width of the whole menu */ - WORD Height; /* Height of the whole menu */ - HWND WndOwner; /* window receiving the messages for ownerdraw */ - BOOL TimeToHide; /* Request hiding when receiving a second click in the top-level menu item */ - SIZE maxBmpSize; /* Maximum size of the bitmap items in MIIM_BITMAP state */ -} ROSMENUINFO, *PROSMENUINFO; + ULONG fFlags; /* Menu flags (MF_POPUP, MF_SYSMENU) */ + UINT iItem; /* Currently focused item */ + UINT cItems; /* Number of items in the menu */ + WORD cxMenu; /* Width of the whole menu */ + WORD cyMenu; /* Height of the whole menu */ + ULONG cxTextAlign; + PWND spwndNotify; /* window receiving the messages for ownerdraw */ + INT iTop; + INT iMaxTop; + DWORD dwArrowsOn:2; -BOOL -NTAPI -NtUserMenuInfo( - HMENU hmenu, - PROSMENUINFO lpmi, - BOOL fsog -); + HMENU Self; /* Handle of this menu */ + HWND Wnd; /* Window containing the menu */ + BOOL TimeToHide; /* Request hiding when receiving a second click in the top-level menu item */ +} ROSMENUINFO, *PROSMENUINFO; typedef struct tagROSMENUITEMINFO { @@ -3410,18 +3442,9 @@ typedef struct tagROSMENUITEMINFO RECT Rect; /* Item area (relative to menu window) */ UINT dxTab; /* X position of text after Tab */ LPWSTR lpstr; /* Copy of the text pointer in MenuItem->Text */ + SIZE maxBmpSize; /* Maximum size of the bitmap items in MIIM_BITMAP state */ } ROSMENUITEMINFO, *PROSMENUITEMINFO; -BOOL -NTAPI -NtUserMenuItemInfo( - HMENU hMenu, - UINT uItem, - BOOL fByPosition, - PROSMENUITEMINFO lpmii, - BOOL fsog -); - HMONITOR NTAPI NtUserMonitorFromPoint( diff --git a/win32ss/user/ntuser/accelerator.c b/win32ss/user/ntuser/accelerator.c index 4c88bfab859..f43ee5e152a 100644 --- a/win32ss/user/ntuser/accelerator.c +++ b/win32ss/user/ntuser/accelerator.c @@ -50,8 +50,7 @@ co_IntTranslateAccelerator( UINT Mask = 0, nPos; HWND hWnd; HMENU hMenu, hSubMenu; - PMENU_OBJECT MenuObject, SubMenu; - PMENU_ITEM MenuItem; + PMENU MenuObject; ASSERT_REFS_CO(Window); @@ -101,16 +100,11 @@ co_IntTranslateAccelerator( hMenu = (Window->style & WS_CHILD) ? 0 : (HMENU)Window->IDMenu; hSubMenu = NULL; MenuObject = IntGetMenuObject(hMenu); + nPos = pAccel->cmd; if (MenuObject) { - nPos = IntGetMenuItemByFlag(MenuObject, - pAccel->cmd, - MF_BYCOMMAND, - &SubMenu, - &MenuItem, - NULL); - if (nPos != (UINT) - 1) - hSubMenu = SubMenu->head.h; + if ((MENU_FindItem (&MenuObject, &nPos, MF_BYPOSITION))) + hSubMenu = MenuObject->head.h; else hMenu = NULL; } @@ -120,16 +114,11 @@ co_IntTranslateAccelerator( hMenu = Window->SystemMenu; hSubMenu = hMenu; /* system menu is a popup menu */ MenuObject = IntGetMenuObject(hMenu); + nPos = pAccel->cmd; if (MenuObject) { - nPos = IntGetMenuItemByFlag(MenuObject, - pAccel->cmd, - MF_BYCOMMAND, - &SubMenu, - &MenuItem, - NULL); - if (nPos != (UINT) - 1) - hSubMenu = SubMenu->head.h; + if ((MENU_FindItem (&MenuObject, &nPos, MF_BYPOSITION))) + hSubMenu = MenuObject->head.h; else hMenu = NULL; } diff --git a/win32ss/user/ntuser/clipboard.c b/win32ss/user/ntuser/clipboard.c index 30ab59ce9b5..2965b3aa93f 100644 --- a/win32ss/user/ntuser/clipboard.c +++ b/win32ss/user/ntuser/clipboard.c @@ -17,7 +17,7 @@ DBG_DEFAULT_CHANNEL(UserClipbrd); #define IS_DATA_DELAYED(ce) ((ce)->hData == DATA_DELAYED) #define IS_DATA_SYNTHESIZED(ce) ((ce)->hData == DATA_SYNTH_USER || (ce)->hData == DATA_SYNTH_KRNL) -PWINSTATION_OBJECT static FASTCALL +static PWINSTATION_OBJECT FASTCALL IntGetWinStaForCbAccess(VOID) { HWINSTA hWinSta; @@ -37,7 +37,7 @@ IntGetWinStaForCbAccess(VOID) } /* If format exists, returns a non zero value (pointing to formated object) */ -PCLIP static FASTCALL +static PCLIP FASTCALL IntIsFormatAvailable(PWINSTATION_OBJECT pWinStaObj, UINT fmt) { unsigned i = 0; @@ -51,7 +51,7 @@ IntIsFormatAvailable(PWINSTATION_OBJECT pWinStaObj, UINT fmt) return NULL; } -VOID static FASTCALL +static VOID FASTCALL IntFreeElementData(PCLIP pElement) { if (!IS_DATA_DELAYED(pElement) && @@ -69,7 +69,7 @@ IntFreeElementData(PCLIP pElement) } /* Adds a new format and data to the clipboard */ -PCLIP static NTAPI +static PCLIP NTAPI IntAddFormatedData(PWINSTATION_OBJECT pWinStaObj, UINT fmt, HANDLE hData, BOOLEAN fGlobalHandle, BOOL bEnd) { PCLIP pElement = NULL; @@ -121,7 +121,7 @@ IntAddFormatedData(PWINSTATION_OBJECT pWinStaObj, UINT fmt, HANDLE hData, BOOLEA return pElement; } -BOOL static FASTCALL +static BOOL FASTCALL IntIsClipboardOpenByMe(PWINSTATION_OBJECT pWinSta) { /* Check if current thread has opened the clipboard */ @@ -134,7 +134,7 @@ IntIsClipboardOpenByMe(PWINSTATION_OBJECT pWinSta) return FALSE; } -VOID static NTAPI +static VOID NTAPI IntSynthesizeDib( PWINSTATION_OBJECT pWinStaObj, HBITMAP hbm) @@ -218,7 +218,7 @@ cleanup: UserReleaseDC(NULL, hdc, FALSE); } -VOID static WINAPI +static VOID WINAPI IntSynthesizeBitmap(PWINSTATION_OBJECT pWinStaObj, PCLIP pBmEl) { HDC hdc = NULL; @@ -279,7 +279,7 @@ cleanup: DIB_FreeConvertedBitmapInfo(pConvertedBmi, pBmi, -1); } -VOID static NTAPI +static VOID NTAPI IntAddSynthesizedFormats(PWINSTATION_OBJECT pWinStaObj) { PCLIP pTextEl, pUniTextEl, pOemTextEl, pLocaleEl, pBmEl, pDibEl; diff --git a/win32ss/user/ntuser/menu.c b/win32ss/user/ntuser/menu.c index b22f62926ee..f4c4e4c71c1 100644 --- a/win32ss/user/ntuser/menu.c +++ b/win32ss/user/ntuser/menu.c @@ -11,6 +11,18 @@ DBG_DEFAULT_CHANNEL(UserMenu); /* INTERNAL ******************************************************************/ +/* maximum allowed depth of any branch in the menu tree. + * This value is slightly larger than in windows (25) to + * stay on the safe side. */ +#define MAXMENUDEPTH 30 + +#define MNS_STYLE_MASK (MNS_NOCHECK|MNS_MODELESS|MNS_DRAGDROP|MNS_AUTODISMISS|MNS_NOTIFYBYPOS|MNS_CHECKORBMP) + +#define MENUITEMINFO_TYPE_MASK \ + (MFT_STRING | MFT_BITMAP | MFT_OWNERDRAW | MFT_SEPARATOR | \ + MFT_MENUBARBREAK | MFT_MENUBREAK | MFT_RADIOCHECK | \ + MFT_RIGHTORDER | MFT_RIGHTJUSTIFY /* same as MF_HELP */ ) + /* Maximum number of menu items a menu can contain */ #define MAX_MENU_ITEMS (0x4000) #define MAX_GOINTOSUBMENU (0x10) @@ -44,18 +56,18 @@ DBG_DEFAULT_CHANNEL(UserMenu); } \ } -#define FreeMenuText(MenuItem) \ +#define FreeMenuText(Menu,MenuItem) \ { \ if((MENU_ITEM_TYPE((MenuItem)->fType) == MF_STRING) && \ - (MenuItem)->Text.Length) { \ - ExFreePoolWithTag((MenuItem)->Text.Buffer, TAG_STRING); \ + (MenuItem)->lpstr.Length) { \ + DesktopHeapFree(((PMENU)Menu)->head.rpdesk, (MenuItem)->lpstr.Buffer); \ } \ } -PMENU_OBJECT FASTCALL UserGetMenuObject(HMENU hMenu) +PMENU FASTCALL UserGetMenuObject(HMENU hMenu) { - PMENU_OBJECT Menu; + PMENU Menu; if (!hMenu) { @@ -63,7 +75,7 @@ PMENU_OBJECT FASTCALL UserGetMenuObject(HMENU hMenu) return NULL; } - Menu = (PMENU_OBJECT)UserGetObject(gHandleTable, hMenu, TYPE_MENU); + Menu = (PMENU)UserGetObject(gHandleTable, hMenu, TYPE_MENU); if (!Menu) { EngSetLastError(ERROR_INVALID_MENU_HANDLE); @@ -76,15 +88,15 @@ PMENU_OBJECT FASTCALL UserGetMenuObject(HMENU hMenu) #if 0 void FASTCALL -DumpMenuItemList(PMENU_ITEM MenuItem) +DumpMenuItemList(PITEM MenuItem) { UINT cnt = 0; while(MenuItem) { - if(MenuItem->Text.Length) - DbgPrint(" %d. %wZ\n", ++cnt, &MenuItem->Text); + if(MenuItem->lpstr.Length) + DbgPrint(" %d. %wZ\n", ++cnt, &MenuItem->lpstr); else - DbgPrint(" %d. NO TEXT dwTypeData==%d\n", ++cnt, (DWORD)MenuItem->Text.Buffer); + DbgPrint(" %d. NO TEXT dwTypeData==%d\n", ++cnt, (DWORD)MenuItem->lpstr.Buffer); DbgPrint(" fType="); if(MFT_BITMAP & MenuItem->fType) DbgPrint("MFT_BITMAP "); @@ -127,10 +139,10 @@ DumpMenuItemList(PMENU_ITEM MenuItem) } #endif -PMENU_OBJECT FASTCALL +PMENU FASTCALL IntGetMenuObject(HMENU hMenu) { - PMENU_OBJECT Menu = UserGetMenuObject(hMenu); + PMENU Menu = UserGetMenuObject(hMenu); if (Menu) Menu->head.cLockObj++; @@ -138,32 +150,25 @@ IntGetMenuObject(HMENU hMenu) } BOOL FASTCALL -IntFreeMenuItem(PMENU_OBJECT Menu, PMENU_ITEM MenuItem, BOOL bRecurse) +IntFreeMenuItem(PMENU Menu, PITEM MenuItem, BOOL bRecurse) { - FreeMenuText(MenuItem); - if(bRecurse && MenuItem->hSubMenu) + FreeMenuText(Menu,MenuItem); + if(bRecurse && MenuItem->spSubMenu) { - PMENU_OBJECT SubMenu; - SubMenu = UserGetMenuObject(MenuItem->hSubMenu ); - if(SubMenu) - { - IntDestroyMenuObject(SubMenu, bRecurse, TRUE); - } + IntDestroyMenuObject(MenuItem->spSubMenu, bRecurse, TRUE); } /* Free memory */ - ExFreePoolWithTag(MenuItem, TAG_MENUITEM); + DesktopHeapFree(Menu->head.rpdesk, MenuItem); return TRUE; } BOOL FASTCALL -IntRemoveMenuItem(PMENU_OBJECT Menu, UINT uPosition, UINT uFlags, - BOOL bRecurse) +IntRemoveMenuItem(PMENU Menu, UINT uPosition, UINT uFlags, BOOL bRecurse) { - PMENU_ITEM PrevMenuItem, MenuItem; - if(IntGetMenuItemByFlag(Menu, uPosition, uFlags, &Menu, &MenuItem, - &PrevMenuItem) > -1) + PITEM PrevMenuItem, MenuItem = NULL; + if(IntGetMenuItemByFlag(Menu, uPosition, uFlags, &Menu, &MenuItem, &PrevMenuItem) > -1) { if(MenuItem) { @@ -171,9 +176,9 @@ IntRemoveMenuItem(PMENU_OBJECT Menu, UINT uPosition, UINT uFlags, PrevMenuItem->Next = MenuItem->Next; else { - Menu->MenuItemList = MenuItem->Next; + Menu->rgItems = MenuItem->Next; } - Menu->MenuInfo.MenuItemCount--; + Menu->cItems--; return IntFreeMenuItem(Menu, MenuItem, bRecurse); } } @@ -181,32 +186,38 @@ IntRemoveMenuItem(PMENU_OBJECT Menu, UINT uPosition, UINT uFlags, } UINT FASTCALL -IntDeleteMenuItems(PMENU_OBJECT Menu, BOOL bRecurse) +IntDeleteMenuItems(PMENU Menu, BOOL bRecurse) { UINT res = 0; - PMENU_ITEM NextItem; - PMENU_ITEM CurItem = Menu->MenuItemList; - while(CurItem) + PITEM NextItem; + PITEM CurItem = Menu->rgItems; + while(CurItem && Menu->cItems) { + Menu->cItems--; //// This is the last of this mess~! Removal requires new start up sequence. Do it like windows and wine! + //// wine MENU_CopySysPopup and ReactOS User32LoadSysMenuTemplateForKernel. + //// SC_CLOSE First and SC_CLOSED Last + //// Use menu item blocks not chain. + /// So do it like windows~! NextItem = CurItem->Next; IntFreeMenuItem(Menu, CurItem, bRecurse); + CurItem->Next = 0; // mark the item as end of the list!!! CurItem = NextItem; res++; } - Menu->MenuInfo.MenuItemCount = 0; - Menu->MenuItemList = NULL; + Menu->cItems = 0; + Menu->rgItems = NULL; return res; } BOOL FASTCALL -IntDestroyMenuObject(PMENU_OBJECT Menu, +IntDestroyMenuObject(PMENU Menu, BOOL bRecurse, BOOL RemoveFromProcess) { if(Menu) { PWND Window; - PWINSTATION_OBJECT WindowStation; - NTSTATUS Status; + //PWINSTATION_OBJECT WindowStation; + //NTSTATUS Status; /* Remove all menu items */ IntDeleteMenuItems(Menu, bRecurse); /* Do not destroy submenus */ @@ -216,70 +227,227 @@ IntDestroyMenuObject(PMENU_OBJECT Menu, RemoveEntryList(&Menu->ListEntry); } - Status = ObReferenceObjectByHandle(Menu->Process->Win32WindowStation, + /*Status = ObReferenceObjectByHandle(Menu->Process->Win32WindowStation, 0, ExWindowStationObjectType, KernelMode, (PVOID*)&WindowStation, NULL); - if(NT_SUCCESS(Status)) + if(NT_SUCCESS(Status))*/ + if (PsGetCurrentProcessSessionId() == Menu->head.rpdesk->rpwinstaParent->dwSessionId) { BOOL ret; - if (Menu->MenuInfo.Wnd) + if (Menu->hWnd) { - Window = UserGetWindowObject(Menu->MenuInfo.Wnd); + Window = UserGetWindowObject(Menu->hWnd); if (Window) { Window->IDMenu = 0; } } -// UserDereferenceObject(Menu); - ret = UserDeleteObject(Menu->MenuInfo.Self, TYPE_MENU); - ObDereferenceObject(WindowStation); + //UserDereferenceObject(Menu); + ret = UserDeleteObject(Menu->head.h, TYPE_MENU); + if (!ret) + { // Make sure it is really dead or just marked for deletion. + ret = UserObjectInDestroy(Menu->head.h); + if (ret && EngGetLastError() == ERROR_INVALID_HANDLE) ret = FALSE; + } // See test_subpopup_locked_by_menu tests.... + //ObDereferenceObject(WindowStation); return ret; } } return FALSE; } -PMENU_OBJECT FASTCALL +BOOL IntDestroyMenu( PMENU pMenu, BOOL RemoveFromProcess) +{ + /* DestroyMenu should not destroy system menu popup owner */ + if ((pMenu->fFlags & (MNF_POPUP | MNF_SYSSUBMENU)) == MNF_POPUP )//&& pMenu->hWnd) + { + //DestroyWindow( pMenu->hWnd ); + //pMenu->hWnd = 0; + } + + if (pMenu->rgItems) /* recursively destroy submenus */ + { + int i; + ITEM *item = pMenu->rgItems; + for (i = pMenu->cItems; i > 0; i--, item++) + { + if (item->spSubMenu) IntDestroyMenu(item->spSubMenu, RemoveFromProcess); + //FreeMenuText(pMenu,item); + } + DesktopHeapFree(pMenu->head.rpdesk, pMenu->rgItems ); + } + //IntDestroyMenuObject(pMenu, bRecurse, RemoveFromProcess); + return TRUE; +} + +/********************************************************************** + * MENU_depth + * + * detect if there are loops in the menu tree (or the depth is too large) + */ +int MENU_depth( PMENU pmenu, int depth) +{ + UINT i; + ITEM *item; + int subdepth; + + depth++; + if( depth > MAXMENUDEPTH) return depth; + item = pmenu->rgItems; + subdepth = depth; + for( i = 0; i < pmenu->cItems && subdepth <= MAXMENUDEPTH; i++, item++) + { + if( item->spSubMenu) + { + int bdepth = MENU_depth( item->spSubMenu, depth); + if( bdepth > subdepth) subdepth = bdepth; + } + if( subdepth > MAXMENUDEPTH) + TRACE("<- hmenu %p\n", item->spSubMenu); + } + return subdepth; +} + +/*********************************************************************** + * MENU_FindItem + * + * Find a menu item. Return a pointer on the item, and modifies *hmenu + * in case the item was in a sub-menu. + */ +ITEM *MENU_FindItem( PMENU *pmenu, UINT *nPos, UINT wFlags ) +{ + MENU *menu = *pmenu; + ITEM *fallback = NULL; + UINT fallback_pos = 0; + UINT i; + PITEM pItem; + + if (wFlags & MF_BYPOSITION) + { + if (*nPos >= menu->cItems) return NULL; + pItem = menu->rgItems; + //pItem = &menu->rgItems[*nPos]; + i = 0; + while(pItem) // Do this for now. + { + if (i < (INT)menu->cItems) + { + if ( *nPos == i ) return pItem; + } + pItem = pItem->Next; + i++; + } + } + else + { + PITEM item = menu->rgItems; + for (i = 0; item ,i < menu->cItems; i++, item = item->Next)//, item++) + { + if (item->spSubMenu) + { + PMENU psubmenu = item->spSubMenu; + PITEM subitem = MENU_FindItem( &psubmenu, nPos, wFlags ); + if (subitem) + { + *pmenu = psubmenu; + return subitem; + } + else if (item->wID == *nPos) + { + /* fallback to this item if nothing else found */ + fallback_pos = i; + fallback = item; + } + } + else if (item->wID == *nPos) + { + *nPos = i; + return item; + } + } + } + + if (fallback) + *nPos = fallback_pos; + + return fallback; +} + +BOOL IntRemoveMenu( PMENU pMenu, UINT nPos, UINT wFlags, BOOL bRecurse ) +{ + PITEM item, NewItems; + + TRACE("(menu=%p pos=%04x flags=%04x)\n",pMenu, nPos, wFlags); + if (!(item = MENU_FindItem( &pMenu, &nPos, wFlags ))) return FALSE; + + /* Remove item */ + + //FreeMenuText(pMenu,item); + + if (bRecurse && item->spSubMenu) + { + IntDestroyMenu(item->spSubMenu, TRUE); + } + ////// Use cAlloced with inc's of 8's.... + if (--pMenu->cItems == 0) + { + DesktopHeapFree(pMenu->head.rpdesk, pMenu->rgItems ); + pMenu->rgItems = NULL; + } + else + { + while(nPos < pMenu->cItems) + { + *item = *(item+1); + item++; + nPos++; + } + NewItems = DesktopHeapAlloc(pMenu->head.rpdesk, pMenu->cItems * sizeof(ITEM)); + RtlCopyMemory(NewItems, pMenu->rgItems, pMenu->cItems * sizeof(ITEM)); + DesktopHeapFree(pMenu->head.rpdesk, pMenu->rgItems); + pMenu->rgItems = NewItems; + } + return TRUE; +} + +PMENU FASTCALL IntCreateMenu(PHANDLE Handle, BOOL IsMenuBar) { - PMENU_OBJECT Menu; + PMENU Menu; PPROCESSINFO CurrentWin32Process; - Menu = (PMENU_OBJECT)UserCreateObject( gHandleTable, + Menu = (PMENU)UserCreateObject( gHandleTable, NULL, NULL, Handle, TYPE_MENU, - sizeof(MENU_OBJECT)); + sizeof(MENU)); if(!Menu) { *Handle = 0; return NULL; } - Menu->Process = PsGetCurrentProcess(); - Menu->RtoL = FALSE; /* Default */ - Menu->MenuInfo.cbSize = sizeof(MENUINFO); /* Not used */ - Menu->MenuInfo.fMask = 0; /* Not used */ - Menu->MenuInfo.dwStyle = 0; /* FIXME */ - Menu->MenuInfo.cyMax = 0; /* Default */ - Menu->MenuInfo.hbrBack = NULL; /* No brush */ - Menu->MenuInfo.dwContextHelpID = 0; /* Default */ - Menu->MenuInfo.dwMenuData = 0; /* Default */ - Menu->MenuInfo.Self = *Handle; - Menu->MenuInfo.FocusedItem = NO_SELECTED_ITEM; - Menu->MenuInfo.Flags = (IsMenuBar ? 0 : MNF_POPUP); - Menu->MenuInfo.Wnd = NULL; - Menu->MenuInfo.WndOwner = NULL; - Menu->MenuInfo.Height = 0; - Menu->MenuInfo.Width = 0; - Menu->MenuInfo.TimeToHide = FALSE; + Menu->cyMax = 0; /* Default */ + Menu->hbrBack = NULL; /* No brush */ + Menu->dwContextHelpId = 0; /* Default */ + Menu->dwMenuData = 0; /* Default */ + Menu->iItem = NO_SELECTED_ITEM; // Focused item + Menu->fFlags = (IsMenuBar ? 0 : MNF_POPUP); + Menu->spwndNotify = NULL; + Menu->cyMenu = 0; // Height + Menu->cxMenu = 0; // Width + Menu->cItems = 0; // Item count + Menu->iTop = 0; + Menu->iMaxTop = 0; + Menu->cxTextAlign = 0; + Menu->rgItems = NULL; - Menu->MenuInfo.MenuItemCount = 0; - Menu->MenuItemList = NULL; + Menu->hWnd = NULL; + Menu->TimeToHide = FALSE; /* Insert menu item into process menu handle list */ CurrentWin32Process = PsGetCurrentProcessWin32Process(); @@ -289,105 +457,104 @@ IntCreateMenu(PHANDLE Handle, BOOL IsMenuBar) } BOOL FASTCALL -IntCloneMenuItems(PMENU_OBJECT Destination, PMENU_OBJECT Source) +IntCloneMenuItems(PMENU Destination, PMENU Source) { - PMENU_ITEM MenuItem, NewMenuItem = NULL; - PMENU_ITEM Old = NULL; + PITEM MenuItem, NewMenuItem = NULL; + PITEM Old = NULL; - if(!Source->MenuInfo.MenuItemCount) + if(!Source->cItems) return FALSE; - MenuItem = Source->MenuItemList; + MenuItem = Source->rgItems; while(MenuItem) { Old = NewMenuItem; if(NewMenuItem) NewMenuItem->Next = MenuItem; - NewMenuItem = ExAllocatePoolWithTag(PagedPool, sizeof(MENU_ITEM), TAG_MENUITEM); + NewMenuItem = DesktopHeapAlloc(Destination->head.rpdesk, sizeof(ITEM)); if(!NewMenuItem) break; + RtlZeroMemory(NewMenuItem, sizeof(NewMenuItem)); NewMenuItem->fType = MenuItem->fType; NewMenuItem->fState = MenuItem->fState; NewMenuItem->wID = MenuItem->wID; - NewMenuItem->hSubMenu = MenuItem->hSubMenu; + NewMenuItem->spSubMenu = MenuItem->spSubMenu; NewMenuItem->hbmpChecked = MenuItem->hbmpChecked; NewMenuItem->hbmpUnchecked = MenuItem->hbmpUnchecked; NewMenuItem->dwItemData = MenuItem->dwItemData; if((MENU_ITEM_TYPE(NewMenuItem->fType) == MF_STRING)) { - if(MenuItem->Text.Length) + if(MenuItem->lpstr.Length) { - NewMenuItem->Text.Length = 0; - NewMenuItem->Text.MaximumLength = MenuItem->Text.MaximumLength; - NewMenuItem->Text.Buffer = (PWSTR)ExAllocatePoolWithTag(PagedPool, MenuItem->Text.MaximumLength, TAG_STRING); - if(!NewMenuItem->Text.Buffer) + NewMenuItem->lpstr.Length = 0; + NewMenuItem->lpstr.MaximumLength = MenuItem->lpstr.MaximumLength; + NewMenuItem->lpstr.Buffer = DesktopHeapAlloc(Destination->head.rpdesk, MenuItem->lpstr.MaximumLength); + if(!NewMenuItem->lpstr.Buffer) { - ExFreePoolWithTag(NewMenuItem, TAG_MENUITEM); + DesktopHeapFree(Destination->head.rpdesk, NewMenuItem); break; } - RtlCopyUnicodeString(&NewMenuItem->Text, &MenuItem->Text); + RtlCopyUnicodeString(&NewMenuItem->lpstr, &MenuItem->lpstr); } else { - NewMenuItem->Text.Buffer = MenuItem->Text.Buffer; + NewMenuItem->lpstr.Buffer = MenuItem->lpstr.Buffer; } } else { - NewMenuItem->Text.Buffer = MenuItem->Text.Buffer; + NewMenuItem->lpstr.Buffer = MenuItem->lpstr.Buffer; } - NewMenuItem->hbmpItem = MenuItem->hbmpItem; + NewMenuItem->hbmp = MenuItem->hbmp; NewMenuItem->Next = NULL; if(Old) Old->Next = NewMenuItem; else - Destination->MenuItemList = NewMenuItem; - Destination->MenuInfo.MenuItemCount++; + Destination->rgItems = NewMenuItem; + Destination->cItems++; MenuItem = MenuItem->Next; } return TRUE; } -PMENU_OBJECT FASTCALL -IntCloneMenu(PMENU_OBJECT Source) +PMENU FASTCALL +IntCloneMenu(PMENU Source) { PPROCESSINFO CurrentWin32Process; HANDLE hMenu; - PMENU_OBJECT Menu; + PMENU Menu; if(!Source) return NULL; - Menu = (PMENU_OBJECT)UserCreateObject( gHandleTable, + Menu = (PMENU)UserCreateObject( gHandleTable, NULL, NULL, &hMenu, TYPE_MENU, - sizeof(MENU_OBJECT)); + sizeof(MENU)); if(!Menu) return NULL; - Menu->Process = PsGetCurrentProcess(); - Menu->RtoL = Source->RtoL; - Menu->MenuInfo.cbSize = sizeof(MENUINFO); /* Not used */ - Menu->MenuInfo.fMask = Source->MenuInfo.fMask; - Menu->MenuInfo.dwStyle = Source->MenuInfo.dwStyle; - Menu->MenuInfo.cyMax = Source->MenuInfo.cyMax; - Menu->MenuInfo.hbrBack = Source->MenuInfo.hbrBack; - Menu->MenuInfo.dwContextHelpID = Source->MenuInfo.dwContextHelpID; - Menu->MenuInfo.dwMenuData = Source->MenuInfo.dwMenuData; - Menu->MenuInfo.Self = hMenu; - Menu->MenuInfo.FocusedItem = NO_SELECTED_ITEM; - Menu->MenuInfo.Wnd = NULL; - Menu->MenuInfo.WndOwner = NULL; - Menu->MenuInfo.Height = 0; - Menu->MenuInfo.Width = 0; - Menu->MenuInfo.TimeToHide = FALSE; + Menu->fFlags = Source->fFlags; + Menu->cyMax = Source->cyMax; + Menu->hbrBack = Source->hbrBack; + Menu->dwContextHelpId = Source->dwContextHelpId; + Menu->dwMenuData = Source->dwMenuData; + Menu->iItem = NO_SELECTED_ITEM; + Menu->spwndNotify = NULL; + Menu->cyMenu = 0; + Menu->cxMenu = 0; + Menu->cItems = 0; + Menu->iTop = 0; + Menu->iMaxTop = 0; + Menu->cxTextAlign = 0; + Menu->rgItems = NULL; - Menu->MenuInfo.MenuItemCount = 0; - Menu->MenuItemList = NULL; + Menu->hWnd = NULL; + Menu->TimeToHide = FALSE; /* Insert menu item into process menu handle list */ CurrentWin32Process = PsGetCurrentProcessWin32Process(); @@ -399,101 +566,117 @@ IntCloneMenu(PMENU_OBJECT Source) } BOOL FASTCALL -IntSetMenuFlagRtoL(PMENU_OBJECT Menu) +IntSetMenuFlagRtoL(PMENU Menu) { - Menu->RtoL = TRUE; + Menu->fFlags |= MNF_RTOL; return TRUE; } BOOL FASTCALL -IntSetMenuContextHelpId(PMENU_OBJECT Menu, DWORD dwContextHelpId) +IntSetMenuContextHelpId(PMENU Menu, DWORD dwContextHelpId) { - Menu->MenuInfo.dwContextHelpID = dwContextHelpId; + Menu->dwContextHelpId = dwContextHelpId; return TRUE; } BOOL FASTCALL -IntGetMenuInfo(PMENU_OBJECT Menu, PROSMENUINFO lpmi) +IntGetMenuInfo(PMENU Menu, PROSMENUINFO lpmi) { if(lpmi->fMask & MIM_BACKGROUND) - lpmi->hbrBack = Menu->MenuInfo.hbrBack; + lpmi->hbrBack = Menu->hbrBack; if(lpmi->fMask & MIM_HELPID) - lpmi->dwContextHelpID = Menu->MenuInfo.dwContextHelpID; + lpmi->dwContextHelpID = Menu->dwContextHelpId; if(lpmi->fMask & MIM_MAXHEIGHT) - lpmi->cyMax = Menu->MenuInfo.cyMax; + lpmi->cyMax = Menu->cyMax; if(lpmi->fMask & MIM_MENUDATA) - lpmi->dwMenuData = Menu->MenuInfo.dwMenuData; + lpmi->dwMenuData = Menu->dwMenuData; if(lpmi->fMask & MIM_STYLE) - lpmi->dwStyle = Menu->MenuInfo.dwStyle; + lpmi->dwStyle = Menu->fFlags & MNS_STYLE_MASK; + if (sizeof(MENUINFO) < lpmi->cbSize) { - RtlCopyMemory((char *) lpmi + sizeof(MENUINFO), - (char *) &Menu->MenuInfo + sizeof(MENUINFO), - lpmi->cbSize - sizeof(MENUINFO)); - } - if (sizeof(ROSMENUINFO) == lpmi->cbSize) - { - lpmi->maxBmpSize.cx = Menu->MenuInfo.maxBmpSize.cx; - lpmi->maxBmpSize.cy = Menu->MenuInfo.maxBmpSize.cy; + lpmi->cItems = Menu->cItems; + + lpmi->iItem = Menu->iItem; + lpmi->cxMenu = Menu->cxMenu; + lpmi->cyMenu = Menu->cyMenu; + lpmi->spwndNotify = Menu->spwndNotify; + lpmi->cxTextAlign = Menu->cxTextAlign; + lpmi->iTop = Menu->iMaxTop; + lpmi->iMaxTop = Menu->iMaxTop; + lpmi->dwArrowsOn = Menu->dwArrowsOn; + + lpmi->fFlags = Menu->fFlags; + lpmi->Self = Menu->head.h; + lpmi->TimeToHide = Menu->TimeToHide; + lpmi->Wnd = Menu->hWnd; } return TRUE; } BOOL FASTCALL -IntSetMenuInfo(PMENU_OBJECT Menu, PROSMENUINFO lpmi) +IntSetMenuInfo(PMENU Menu, PROSMENUINFO lpmi) { if(lpmi->fMask & MIM_BACKGROUND) - Menu->MenuInfo.hbrBack = lpmi->hbrBack; + Menu->hbrBack = lpmi->hbrBack; if(lpmi->fMask & MIM_HELPID) - Menu->MenuInfo.dwContextHelpID = lpmi->dwContextHelpID; + Menu->dwContextHelpId = lpmi->dwContextHelpID; if(lpmi->fMask & MIM_MAXHEIGHT) - Menu->MenuInfo.cyMax = lpmi->cyMax; + Menu->cyMax = lpmi->cyMax; if(lpmi->fMask & MIM_MENUDATA) - Menu->MenuInfo.dwMenuData = lpmi->dwMenuData; + Menu->dwMenuData = lpmi->dwMenuData; if(lpmi->fMask & MIM_STYLE) - Menu->MenuInfo.dwStyle = lpmi->dwStyle; + Menu->fFlags ^= (Menu->fFlags ^ lpmi->dwStyle) & MNS_STYLE_MASK; if(lpmi->fMask & MIM_APPLYTOSUBMENUS) { int i; - PMENU_ITEM item = Menu->MenuItemList; - for ( i = Menu->MenuInfo.MenuItemCount; i; i--, item = item->Next) + PITEM item = Menu->rgItems; + for ( i = Menu->cItems; i; i--, item = item->Next) { - if ( item->hSubMenu ) + if ( item->spSubMenu ) { - PMENU_OBJECT SubMenu; - if (!(SubMenu = UserGetMenuObject(item->hSubMenu))) continue; - IntSetMenuInfo( SubMenu, lpmi); + IntSetMenuInfo( item->spSubMenu, lpmi); } } + /* PITEM item = Menu->rgItems; + for ( i = Menu->cItems; i; i--, item++) + { + if ( item->spSubMenu ) + { + IntSetMenuInfo( item->spSubMenu, lpmi); + } + }*/ } if (sizeof(MENUINFO) < lpmi->cbSize) { - Menu->MenuInfo.FocusedItem = lpmi->FocusedItem; - Menu->MenuInfo.Height = lpmi->Height; - Menu->MenuInfo.Width = lpmi->Width; - Menu->MenuInfo.Wnd = lpmi->Wnd; - Menu->MenuInfo.WndOwner = lpmi->WndOwner; - Menu->MenuInfo.TimeToHide = lpmi->TimeToHide; - } - if (sizeof(ROSMENUINFO) == lpmi->cbSize) - { - Menu->MenuInfo.maxBmpSize.cx = lpmi->maxBmpSize.cx; - Menu->MenuInfo.maxBmpSize.cy = lpmi->maxBmpSize.cy; + Menu->iItem = lpmi->iItem; + Menu->cyMenu = lpmi->cyMenu; + Menu->cxMenu = lpmi->cxMenu; + Menu->spwndNotify = lpmi->spwndNotify; + Menu->cxTextAlign = lpmi->cxTextAlign; + Menu->iTop = lpmi->iTop; + Menu->iMaxTop = lpmi->iMaxTop; + Menu->dwArrowsOn = lpmi->dwArrowsOn; + + Menu->TimeToHide = lpmi->TimeToHide; + Menu->hWnd = lpmi->Wnd; } return TRUE; } - +// +// Old and yeah~..... Why start with a -1 for position search? +// int FASTCALL -IntGetMenuItemByFlag(PMENU_OBJECT Menu, +IntGetMenuItemByFlag(PMENU Menu, UINT uSearchBy, UINT fFlag, - PMENU_OBJECT *SubMenu, - PMENU_ITEM *MenuItem, - PMENU_ITEM *PrevMenuItem) + PMENU *SubMenu, + PITEM *MenuItem, + PITEM *PrevMenuItem) { - PMENU_ITEM PrevItem = NULL; - PMENU_ITEM CurItem = Menu->MenuItemList; + PITEM PrevItem = NULL; + PITEM CurItem = Menu->rgItems; int p; int ret; @@ -542,17 +725,12 @@ IntGetMenuItemByFlag(PMENU_OBJECT Menu, } else { - if(CurItem->hSubMenu) + if(CurItem->spSubMenu) { - PMENU_OBJECT NewMenu = UserGetMenuObject(CurItem->hSubMenu); - if(NewMenu) + ret = IntGetMenuItemByFlag(CurItem->spSubMenu, uSearchBy, fFlag, SubMenu, MenuItem, PrevMenuItem); + if(ret != -1) { - ret = IntGetMenuItemByFlag(NewMenu, uSearchBy, fFlag, - SubMenu, MenuItem, PrevMenuItem); - if(ret != -1) - { - return ret; - } + return ret; } } } @@ -566,13 +744,13 @@ IntGetMenuItemByFlag(PMENU_OBJECT Menu, int FASTCALL -IntInsertMenuItemToList(PMENU_OBJECT Menu, PMENU_ITEM MenuItem, int pos) +IntInsertMenuItemToList(PMENU Menu, PITEM MenuItem, int pos) { - PMENU_ITEM CurItem; - PMENU_ITEM LastItem = NULL; + PITEM CurItem; + PITEM LastItem = NULL; UINT npos = 0; - CurItem = Menu->MenuItemList; + CurItem = Menu->rgItems; while(CurItem && (pos != 0)) { LastItem = CurItem; @@ -589,17 +767,17 @@ IntInsertMenuItemToList(PMENU_OBJECT Menu, PMENU_ITEM MenuItem, int pos) else { /* Insert at the beginning */ - Menu->MenuItemList = MenuItem; + Menu->rgItems = MenuItem; } MenuItem->Next = CurItem; - Menu->MenuInfo.MenuItemCount++; + Menu->cItems++; return npos; } BOOL FASTCALL -IntGetMenuItemInfo(PMENU_OBJECT Menu, /* UNUSED PARAM!! */ - PMENU_ITEM MenuItem, PROSMENUITEMINFO lpmii) +IntGetMenuItemInfo(PMENU Menu, /* UNUSED PARAM!! */ + PITEM MenuItem, PROSMENUITEMINFO lpmii) { NTSTATUS Status; @@ -609,7 +787,7 @@ IntGetMenuItemInfo(PMENU_OBJECT Menu, /* UNUSED PARAM!! */ } if(lpmii->fMask & MIIM_BITMAP) { - lpmii->hbmpItem = MenuItem->hbmpItem; + lpmii->hbmpItem = MenuItem->hbmp; } if(lpmii->fMask & MIIM_CHECKMARKS) { @@ -630,7 +808,7 @@ IntGetMenuItemInfo(PMENU_OBJECT Menu, /* UNUSED PARAM!! */ } if(lpmii->fMask & MIIM_SUBMENU) { - lpmii->hSubMenu = MenuItem->hSubMenu; + lpmii->hSubMenu = MenuItem->spSubMenu ? MenuItem->spSubMenu->head.h : NULL; } if ((lpmii->fMask & MIIM_STRING) || @@ -638,13 +816,13 @@ IntGetMenuItemInfo(PMENU_OBJECT Menu, /* UNUSED PARAM!! */ { if (lpmii->dwTypeData == NULL) { - lpmii->cch = MenuItem->Text.Length / sizeof(WCHAR); + lpmii->cch = MenuItem->lpstr.Length / sizeof(WCHAR); } else - { - Status = MmCopyToCaller(lpmii->dwTypeData, MenuItem->Text.Buffer, + { //// lpmii->lpstr can be read in user mode!!!! + Status = MmCopyToCaller(lpmii->dwTypeData, MenuItem->lpstr.Buffer, min(lpmii->cch * sizeof(WCHAR), - MenuItem->Text.MaximumLength)); + MenuItem->lpstr.MaximumLength)); if (! NT_SUCCESS(Status)) { SetLastNtError(Status); @@ -655,18 +833,23 @@ IntGetMenuItemInfo(PMENU_OBJECT Menu, /* UNUSED PARAM!! */ if (sizeof(ROSMENUITEMINFO) == lpmii->cbSize) { - lpmii->Rect = MenuItem->Rect; + lpmii->Rect.left = MenuItem->xItem; + lpmii->Rect.top = MenuItem->yItem; + lpmii->Rect.right = MenuItem->cxItem; // Do this for now...... + lpmii->Rect.bottom = MenuItem->cyItem; lpmii->dxTab = MenuItem->dxTab; - lpmii->lpstr = MenuItem->Text.Buffer; // Use DesktopHeap! + lpmii->lpstr = MenuItem->lpstr.Buffer; + lpmii->maxBmpSize.cx = MenuItem->cxBmp; + lpmii->maxBmpSize.cy = MenuItem->cyBmp; } return TRUE; } BOOL FASTCALL -IntSetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, PROSMENUITEMINFO lpmii) +IntSetMenuItemInfo(PMENU MenuObject, PITEM MenuItem, PROSMENUITEMINFO lpmii, PUNICODE_STRING lpstr) { - PMENU_OBJECT SubMenuObject; + PMENU SubMenuObject; UINT fTypeMask = (MFT_BITMAP | MFT_MENUBARBREAK | MFT_MENUBREAK | MFT_OWNERDRAW | MFT_RADIOCHECK | MFT_RIGHTJUSTIFY | MFT_SEPARATOR); if(!MenuItem || !MenuObject || !lpmii) @@ -680,13 +863,16 @@ IntSetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, PROSMENUITEMINF } if (lpmii->fMask & MIIM_TYPE) { + #if 0 //// Done in User32. if (lpmii->fMask & ( MIIM_STRING | MIIM_FTYPE | MIIM_BITMAP)) { ERR("IntSetMenuItemInfo: Invalid combination of fMask bits used\n"); + KeRosDumpStackFrames(NULL, 20); /* This does not happen on Win9x/ME */ SetLastNtError( ERROR_INVALID_PARAMETER); return FALSE; } + #endif /* * Delete the menu item type when changing type from * MF_STRING. @@ -694,33 +880,36 @@ IntSetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, PROSMENUITEMINF if (MenuItem->fType != lpmii->fType && MENU_ITEM_TYPE(MenuItem->fType) == MFT_STRING) { - FreeMenuText(MenuItem); - RtlInitUnicodeString(&MenuItem->Text, NULL); + FreeMenuText(MenuObject,MenuItem); + RtlInitUnicodeString(&MenuItem->lpstr, NULL); } if(lpmii->fType & MFT_BITMAP) { if(lpmii->hbmpItem) - MenuItem->hbmpItem = lpmii->hbmpItem; + MenuItem->hbmp = lpmii->hbmpItem; else { /* Win 9x/Me stuff */ - MenuItem->hbmpItem = (HBITMAP)((ULONG_PTR)(LOWORD(lpmii->dwTypeData))); + MenuItem->hbmp = (HBITMAP)((ULONG_PTR)(LOWORD(lpmii->dwTypeData))); } } MenuItem->fType |= lpmii->fType; } if (lpmii->fMask & MIIM_FTYPE ) { + #if 0 //// ? if(( lpmii->fType & MFT_BITMAP)) { ERR("IntSetMenuItemInfo: Can not use FTYPE and MFT_BITMAP.\n"); SetLastNtError( ERROR_INVALID_PARAMETER); return FALSE; } - MenuItem->fType |= lpmii->fType; /* Need to save all the flags, this fixed MFT_RIGHTJUSTIFY */ + #endif + MenuItem->fType &= ~MENUITEMINFO_TYPE_MASK; + MenuItem->fType |= lpmii->fType & MENUITEMINFO_TYPE_MASK; } if(lpmii->fMask & MIIM_BITMAP) { - MenuItem->hbmpItem = lpmii->hbmpItem; + MenuItem->hbmp = lpmii->hbmpItem; } if(lpmii->fMask & MIIM_CHECKMARKS) { @@ -747,79 +936,158 @@ IntSetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, PROSMENUITEMINF if(lpmii->fMask & MIIM_SUBMENU) { - MenuItem->hSubMenu = lpmii->hSubMenu; /* Make sure the submenu is marked as a popup menu */ - if (MenuItem->hSubMenu) + if (lpmii->hSubMenu) { - SubMenuObject = UserGetMenuObject(MenuItem->hSubMenu); + SubMenuObject = UserGetMenuObject(lpmii->hSubMenu); if (SubMenuObject != NULL) { - SubMenuObject->MenuInfo.Flags |= MNF_POPUP; + SubMenuObject->fFlags |= MNF_POPUP; + // Now fix the test_subpopup_locked_by_menu tests.... + if (MenuItem->spSubMenu) UserDereferenceObject(MenuItem->spSubMenu); + MenuItem->spSubMenu = SubMenuObject; + UserReferenceObject(SubMenuObject); } + else + { + EngSetLastError( ERROR_INVALID_PARAMETER); + return FALSE; + } + } + else + { // If submenu just dereference it. + if (MenuItem->spSubMenu) UserDereferenceObject(MenuItem->spSubMenu); + MenuItem->spSubMenu = NULL; } } if ((lpmii->fMask & MIIM_STRING) || ((lpmii->fMask & MIIM_TYPE) && (MENU_ITEM_TYPE(lpmii->fType) == MF_STRING))) { - FreeMenuText(MenuItem); + FreeMenuText(MenuObject,MenuItem); if(lpmii->dwTypeData && lpmii->cch) { UNICODE_STRING Source; - Source.Length = - Source.MaximumLength = lpmii->cch * sizeof(WCHAR); + Source.Length = Source.MaximumLength = lpmii->cch * sizeof(WCHAR); Source.Buffer = lpmii->dwTypeData; - MenuItem->Text.Buffer = (PWSTR)ExAllocatePoolWithTag( - PagedPool, Source.Length + sizeof(WCHAR), TAG_STRING); - if(MenuItem->Text.Buffer != NULL) + MenuItem->lpstr.Buffer = DesktopHeapAlloc( MenuObject->head.rpdesk, Source.Length + sizeof(WCHAR)); + if(MenuItem->lpstr.Buffer != NULL) { - MenuItem->Text.Length = 0; - MenuItem->Text.MaximumLength = Source.Length + sizeof(WCHAR); - RtlCopyUnicodeString(&MenuItem->Text, &Source); - MenuItem->Text.Buffer[MenuItem->Text.Length / sizeof(WCHAR)] = 0; + MenuItem->lpstr.Length = 0; + MenuItem->lpstr.MaximumLength = Source.Length + sizeof(WCHAR); + RtlCopyUnicodeString(&MenuItem->lpstr, &Source); + MenuItem->lpstr.Buffer[MenuItem->lpstr.Length / sizeof(WCHAR)] = 0; + + MenuItem->cch = MenuItem->lpstr.Length / sizeof(WCHAR); + MenuItem->Xlpstr = (USHORT*)MenuItem->lpstr.Buffer; } else { - RtlInitUnicodeString(&MenuItem->Text, NULL); + RtlInitUnicodeString(&MenuItem->lpstr, NULL); + MenuItem->Xlpstr = NULL; } } else { - if (0 == (MenuObject->MenuInfo.Flags & MNF_SYSDESKMN)) + if (0 == (MenuObject->fFlags & MNF_SYSDESKMN)) { MenuItem->fType |= MF_SEPARATOR; } - RtlInitUnicodeString(&MenuItem->Text, NULL); + RtlInitUnicodeString(&MenuItem->lpstr, NULL); } } + //if( !MenuItem->lpstr.Buffer && !(MenuItem->fType & MFT_OWNERDRAW) && !MenuItem->hbmp) + // MenuItem->fType |= MFT_SEPARATOR; break system menu..... + + /* Force size recalculation! */ + MenuObject->cyMenu = 0; + if (sizeof(ROSMENUITEMINFO) == lpmii->cbSize) { - MenuItem->Rect = lpmii->Rect; + MenuItem->xItem = lpmii->Rect.left; + MenuItem->yItem = lpmii->Rect.top; + MenuItem->cxItem = lpmii->Rect.right; // Do this for now...... + MenuItem->cyItem = lpmii->Rect.bottom; MenuItem->dxTab = lpmii->dxTab; - lpmii->lpstr = MenuItem->Text.Buffer; /* Use DesktopHeap! Send back new allocated string or zero */ + lpmii->lpstr = MenuItem->lpstr.Buffer; /* Send back new allocated string or zero */ + MenuItem->cxBmp = lpmii->maxBmpSize.cx; + MenuItem->cyBmp = lpmii->maxBmpSize.cy; } return TRUE; } + +/********************************************************************** + * MENU_InsertItem + * + * Insert (allocate) a new item into a menu. + */ +ITEM *MENU_InsertItem( PMENU menu, UINT pos, UINT flags ) +{ + ITEM *newItems; + + /* Find where to insert new item */ + + if (flags & MF_BYPOSITION) { + if (pos > menu->cItems) + pos = menu->cItems; + } else { + if (!MENU_FindItem( &menu, &pos, flags )) + pos = menu->cItems; + } + + /* Make sure that MDI system buttons stay on the right side. + * Note: XP treats only bitmap handles 1 - 6 as "magic" ones + * regardless of their id. + */ + while ( pos > 0 && + (INT_PTR)menu->rgItems[pos - 1].hbmp >= (INT_PTR)HBMMENU_SYSTEM && + (INT_PTR)menu->rgItems[pos - 1].hbmp <= (INT_PTR)HBMMENU_MBAR_CLOSE_D) + pos--; + + TRACE("inserting at %u flags %x\n", pos, flags); + + /* Create new items array */ + + newItems = DesktopHeapAlloc(menu->head.rpdesk, sizeof(ITEM) * (menu->cItems+1) ); + if (!newItems) + { + WARN("allocation failed\n" ); + return NULL; + } + if (menu->cItems > 0) + { + /* Copy the old array into the new one */ + if (pos > 0) RtlCopyMemory( newItems, menu->rgItems, pos * sizeof(ITEM) ); + if (pos < menu->cItems) RtlCopyMemory( &newItems[pos+1], &menu->rgItems[pos], (menu->cItems-pos)*sizeof(ITEM) ); + DesktopHeapFree(menu->head.rpdesk, menu->rgItems ); + } + menu->rgItems = newItems; + menu->cItems++; + RtlZeroMemory( &newItems[pos], sizeof(*newItems) ); + menu->cyMenu = 0; /* force size recalculate */ + return &newItems[pos]; +} + BOOL FASTCALL IntInsertMenuItem( - _In_ PMENU_OBJECT MenuObject, + _In_ PMENU MenuObject, UINT uItem, BOOL fByPosition, PROSMENUITEMINFO ItemInfo) { int pos; - PMENU_ITEM MenuItem; - PMENU_OBJECT SubMenu = NULL; + PITEM MenuItem; + PMENU SubMenu = NULL; NT_ASSERT(MenuObject != NULL); - - if (MAX_MENU_ITEMS <= MenuObject->MenuInfo.MenuItemCount) + //ERR("InsertMenuItem\n"); + if (MAX_MENU_ITEMS <= MenuObject->cItems) { EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; @@ -830,9 +1098,9 @@ IntInsertMenuItem( SubMenu = MenuObject; /* calculate position */ pos = (int)uItem; - if(uItem > MenuObject->MenuInfo.MenuItemCount) + if(uItem > MenuObject->cItems) { - pos = MenuObject->MenuInfo.MenuItemCount; + pos = MenuObject->cItems; } } else @@ -843,7 +1111,7 @@ IntInsertMenuItem( { /* Default to last position of menu */ SubMenu = MenuObject; - pos = MenuObject->MenuInfo.MenuItemCount; + pos = MenuObject->cItems; } @@ -852,31 +1120,24 @@ IntInsertMenuItem( pos = -1; } - MenuItem = ExAllocatePoolWithTag(PagedPool, sizeof(MENU_ITEM), TAG_MENUITEM); + MenuItem = DesktopHeapAlloc(MenuObject->head.rpdesk, sizeof(ITEM)); if (NULL == MenuItem) { EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); return FALSE; } - MenuItem->fType = MFT_STRING; - MenuItem->fState = MFS_ENABLED | MFS_UNCHECKED; - MenuItem->wID = 0; - MenuItem->hSubMenu = (HMENU)0; - MenuItem->hbmpChecked = (HBITMAP)0; - MenuItem->hbmpUnchecked = (HBITMAP)0; - MenuItem->dwItemData = 0; - RtlInitUnicodeString(&MenuItem->Text, NULL); - MenuItem->hbmpItem = (HBITMAP)0; + RtlZeroMemory(MenuItem, sizeof(MenuItem)); - if(!IntSetMenuItemInfo(SubMenu, MenuItem, ItemInfo)) + if(!IntSetMenuItemInfo(SubMenu, MenuItem, ItemInfo, NULL)) { - ExFreePoolWithTag(MenuItem, TAG_MENUITEM); + DesktopHeapFree(MenuObject->head.rpdesk, MenuItem); return FALSE; } /* Force size recalculation! */ - MenuObject->MenuInfo.Height = 0; + MenuObject->cyMenu = 0; + MenuItem->hbmpChecked = MenuItem->hbmpUnchecked = 0; pos = IntInsertMenuItemToList(SubMenu, MenuItem, pos); @@ -886,58 +1147,53 @@ IntInsertMenuItem( } UINT FASTCALL -IntEnableMenuItem(PMENU_OBJECT MenuObject, UINT uIDEnableItem, UINT uEnable) +IntEnableMenuItem(PMENU MenuObject, UINT uIDEnableItem, UINT uEnable) { - PMENU_ITEM MenuItem; - UINT res = IntGetMenuItemByFlag(MenuObject, uIDEnableItem, uEnable, NULL, &MenuItem, NULL); - if(!MenuItem || (res == (UINT)-1)) - { - return (UINT)-1; - } + PITEM MenuItem; + UINT res; + + if (!(MenuItem = MENU_FindItem( &MenuObject, &uIDEnableItem, uEnable ))) return (UINT)-1; res = MenuItem->fState & (MF_GRAYED | MF_DISABLED); - if(uEnable & MF_DISABLED) - { - MenuItem->fState |= MF_DISABLED; - MenuItem->fState |= uEnable & MF_GRAYED; - } - else - { - if(uEnable & MF_GRAYED) - { - MenuItem->fState |= (MF_GRAYED | MF_DISABLED); - } - else - { - MenuItem->fState &= ~(MF_DISABLED | MF_GRAYED); - } - } + MenuItem->fState ^= (res ^ uEnable) & (MF_GRAYED | MF_DISABLED); + /* If the close item in the system menu change update the close button */ + if((MenuItem->wID == SC_CLOSE) && (res != uEnable)) + { + if (MenuObject->fFlags & MNF_SYSSUBMENU && MenuObject->spwndNotify != 0) + { + RECTL rc = MenuObject->spwndNotify->rcWindow; + + /* Refresh the frame to reflect the change */ + IntMapWindowPoints(0, MenuObject->spwndNotify, (POINT *)&rc, 2); + rc.bottom = 0; + co_UserRedrawWindow(MenuObject->spwndNotify, &rc, 0, RDW_FRAME | RDW_INVALIDATE | RDW_NOCHILDREN); + } + } return res; } - - +#if 0 // Moved to User32. DWORD FASTCALL -IntBuildMenuItemList(PMENU_OBJECT MenuObject, PVOID Buffer, ULONG nMax) +IntBuildMenuItemList(PMENU MenuObject, PVOID Buffer, ULONG nMax) { DWORD res = 0; ROSMENUITEMINFO mii; PVOID Buf; - PMENU_ITEM CurItem = MenuObject->MenuItemList; + PITEM CurItem = MenuObject->rgItems; PWCHAR StrOut; NTSTATUS Status; WCHAR NulByte; if (0 != nMax) { - if (nMax < MenuObject->MenuInfo.MenuItemCount * sizeof(ROSMENUITEMINFO)) + if (nMax < MenuObject->cItems * sizeof(ROSMENUITEMINFO)) { return 0; } - StrOut = (PWCHAR)((char *) Buffer + MenuObject->MenuInfo.MenuItemCount + StrOut = (PWCHAR)((char *) Buffer + MenuObject->cItems * sizeof(ROSMENUITEMINFO)); - nMax -= MenuObject->MenuInfo.MenuItemCount * sizeof(ROSMENUITEMINFO); + nMax -= MenuObject->cItems * sizeof(ROSMENUITEMINFO); Buf = Buffer; mii.cbSize = sizeof(ROSMENUITEMINFO); mii.fMask = 0; @@ -945,9 +1201,9 @@ IntBuildMenuItemList(PMENU_OBJECT MenuObject, PVOID Buffer, ULONG nMax) while (NULL != CurItem) { - mii.cch = CurItem->Text.Length / sizeof(WCHAR); + mii.cch = CurItem->lpstr.Length / sizeof(WCHAR); mii.dwItemData = CurItem->dwItemData; - if (0 != CurItem->Text.Length) + if (0 != CurItem->lpstr.Length) { mii.dwTypeData = StrOut; } @@ -959,12 +1215,17 @@ IntBuildMenuItemList(PMENU_OBJECT MenuObject, PVOID Buffer, ULONG nMax) mii.fType = CurItem->fType; mii.wID = CurItem->wID; mii.hbmpChecked = CurItem->hbmpChecked; - mii.hbmpItem = CurItem->hbmpItem; + mii.hbmpItem = CurItem->hbmp; mii.hbmpUnchecked = CurItem->hbmpUnchecked; - mii.hSubMenu = CurItem->hSubMenu; - mii.Rect = CurItem->Rect; + mii.hSubMenu = CurItem->spSubMenu ? CurItem->spSubMenu->head.h : NULL; + mii.Rect.left = CurItem->xItem; + mii.Rect.top = CurItem->yItem; + mii.Rect.right = CurItem->cxItem; // Do this for now...... + mii.Rect.bottom = CurItem->cyItem; mii.dxTab = CurItem->dxTab; - mii.lpstr = CurItem->Text.Buffer; // Use DesktopHeap! + mii.lpstr = CurItem->lpstr.Buffer; // Can be read from user side! + //mii.maxBmpSize.cx = CurItem->cxBmp; + //mii.maxBmpSize.cy = CurItem->cyBmp; Status = MmCopyToCaller(Buf, &mii, sizeof(ROSMENUITEMINFO)); if (! NT_SUCCESS(Status)) @@ -974,18 +1235,18 @@ IntBuildMenuItemList(PMENU_OBJECT MenuObject, PVOID Buffer, ULONG nMax) } Buf = (PVOID)((ULONG_PTR)Buf + sizeof(ROSMENUITEMINFO)); - if (0 != CurItem->Text.Length - && (nMax >= CurItem->Text.Length + sizeof(WCHAR))) + if (0 != CurItem->lpstr.Length + && (nMax >= CurItem->lpstr.Length + sizeof(WCHAR))) { /* Copy string */ - Status = MmCopyToCaller(StrOut, CurItem->Text.Buffer, - CurItem->Text.Length); + Status = MmCopyToCaller(StrOut, CurItem->lpstr.Buffer, + CurItem->lpstr.Length); if (! NT_SUCCESS(Status)) { SetLastNtError(Status); return 0; } - StrOut += CurItem->Text.Length / sizeof(WCHAR); + StrOut += CurItem->lpstr.Length / sizeof(WCHAR); Status = MmCopyToCaller(StrOut, &NulByte, sizeof(WCHAR)); if (! NT_SUCCESS(Status)) { @@ -993,9 +1254,9 @@ IntBuildMenuItemList(PMENU_OBJECT MenuObject, PVOID Buffer, ULONG nMax) return 0; } StrOut++; - nMax -= CurItem->Text.Length + sizeof(WCHAR); + nMax -= CurItem->lpstr.Length + sizeof(WCHAR); } - else if (0 != CurItem->Text.Length) + else if (0 != CurItem->lpstr.Length) { break; } @@ -1008,82 +1269,69 @@ IntBuildMenuItemList(PMENU_OBJECT MenuObject, PVOID Buffer, ULONG nMax) { while (NULL != CurItem) { - res += sizeof(ROSMENUITEMINFO) + CurItem->Text.Length + sizeof(WCHAR); + res += sizeof(ROSMENUITEMINFO) + CurItem->lpstr.Length + sizeof(WCHAR); CurItem = CurItem->Next; } } + return res; +} +#endif +DWORD FASTCALL +IntCheckMenuItem(PMENU MenuObject, UINT uIDCheckItem, UINT uCheck) +{ + PITEM MenuItem; + DWORD res; + + if (!(MenuItem = MENU_FindItem( &MenuObject, &uIDCheckItem, uCheck ))) return -1; + + res = (DWORD)(MenuItem->fState & MF_CHECKED); + + MenuItem->fState ^= (res ^ uCheck) & MF_CHECKED; return res; } - -DWORD FASTCALL -IntCheckMenuItem(PMENU_OBJECT MenuObject, UINT uIDCheckItem, UINT uCheck) -{ - PMENU_ITEM MenuItem; - int res = -1; - - if((IntGetMenuItemByFlag(MenuObject, uIDCheckItem, uCheck, NULL, &MenuItem, NULL) < 0) || !MenuItem) - { - return -1; - } - - res = (DWORD)(MenuItem->fState & MF_CHECKED); - if(uCheck & MF_CHECKED) - { - MenuItem->fState |= MF_CHECKED; - } - else - { - MenuItem->fState &= ~MF_CHECKED; - } - - return (DWORD)res; -} - BOOL FASTCALL IntHiliteMenuItem(PWND WindowObject, - PMENU_OBJECT MenuObject, + PMENU MenuObject, UINT uItemHilite, UINT uHilite) { - PMENU_ITEM MenuItem; - int Pos; + PITEM MenuItem; - Pos = IntGetMenuItemByFlag(MenuObject, uItemHilite, uHilite, NULL, &MenuItem, NULL); + if (!(MenuItem = MENU_FindItem( &MenuObject, &uItemHilite, uHilite ))) return FALSE; - if (!MenuItem || (uHilite & MF_BYPOSITION && Pos == -1)) + if (MenuItem) { - return FALSE; + if (uHilite & MF_HILITE) + { + MenuItem->fState |= MF_HILITE; + } + else + { + MenuItem->fState &= ~MF_HILITE; + } } - - if (uHilite & MF_HILITE) - { - MenuItem->fState |= MF_HILITE; - } - else - { - MenuItem->fState &= ~MF_HILITE; - } - /* FIXME: Update the window's menu */ return TRUE; } BOOL FASTCALL -UserSetMenuDefaultItem(PMENU_OBJECT MenuObject, UINT uItem, UINT fByPos) +UserSetMenuDefaultItem(PMENU MenuObject, UINT uItem, UINT fByPos) { BOOL ret = FALSE; - PMENU_ITEM MenuItem = MenuObject->MenuItemList; + PITEM MenuItem = MenuObject->rgItems; + while(MenuItem) + { + MenuItem->fState &= ~MFS_DEFAULT; + MenuItem = MenuItem->Next; + } + + /* no default item */ if(uItem == (UINT)-1) { - while(MenuItem) - { - MenuItem->fState &= ~MFS_DEFAULT; - MenuItem = MenuItem->Next; - } return TRUE; } @@ -1126,14 +1374,13 @@ UserSetMenuDefaultItem(PMENU_OBJECT MenuObject, UINT uItem, UINT fByPos) UINT FASTCALL -IntGetMenuDefaultItem(PMENU_OBJECT MenuObject, UINT fByPos, UINT gmdiFlags, +IntGetMenuDefaultItem(PMENU MenuObject, UINT fByPos, UINT gmdiFlags, DWORD *gismc) { UINT x = 0; UINT res = -1; UINT sres; - PMENU_OBJECT SubMenuObject; - PMENU_ITEM MenuItem = MenuObject->MenuItemList; + PITEM MenuItem = MenuObject->rgItems; while(MenuItem) { @@ -1149,15 +1396,14 @@ IntGetMenuDefaultItem(PMENU_OBJECT MenuObject, UINT fByPos, UINT gmdiFlags, res = MenuItem->wID; if((*gismc < MAX_GOINTOSUBMENU) && (gmdiFlags & GMDI_GOINTOPOPUPS) && - MenuItem->hSubMenu) + MenuItem->spSubMenu) { - SubMenuObject = UserGetMenuObject(MenuItem->hSubMenu); - if(!SubMenuObject || (SubMenuObject == MenuObject)) + if(MenuItem->spSubMenu == MenuObject) break; (*gismc)++; - sres = IntGetMenuDefaultItem(SubMenuObject, fByPos, gmdiFlags, gismc); + sres = IntGetMenuDefaultItem(MenuItem->spSubMenu, fByPos, gmdiFlags, gismc); (*gismc)--; if(sres > (UINT)-1) @@ -1175,7 +1421,7 @@ IntGetMenuDefaultItem(PMENU_OBJECT MenuObject, UINT fByPos, UINT gmdiFlags, } VOID FASTCALL -co_IntInitTracking(PWND Window, PMENU_OBJECT Menu, BOOL Popup, +co_IntInitTracking(PWND Window, PMENU Menu, BOOL Popup, UINT Flags) { /* FIXME: Hide caret */ @@ -1186,11 +1432,11 @@ co_IntInitTracking(PWND Window, PMENU_OBJECT Menu, BOOL Popup, /* FIXME: Send WM_SETCURSOR message */ if(!(Flags & TPM_NONOTIFY)) - co_IntSendMessage(Window->head.h, WM_INITMENU, (WPARAM)Menu->MenuInfo.Self, 0); + co_IntSendMessage(Window->head.h, WM_INITMENU, (WPARAM)Menu->head.h, 0); } VOID FASTCALL -co_IntExitTracking(PWND Window, PMENU_OBJECT Menu, BOOL Popup, +co_IntExitTracking(PWND Window, PMENU Menu, BOOL Popup, UINT Flags) { if(!(Flags & TPM_NONOTIFY)) @@ -1200,14 +1446,14 @@ co_IntExitTracking(PWND Window, PMENU_OBJECT Menu, BOOL Popup, } INT FASTCALL -IntTrackMenu(PMENU_OBJECT Menu, PWND Window, INT x, INT y, +IntTrackMenu(PMENU Menu, PWND Window, INT x, INT y, RECTL lprect) { return 0; } BOOL FASTCALL -co_IntTrackPopupMenu(PMENU_OBJECT Menu, PWND Window, +co_IntTrackPopupMenu(PMENU Menu, PWND Window, UINT Flags, POINT *Pos, UINT MenuPos, RECTL *ExcludeRect) { co_IntInitTracking(Window, Menu, TRUE, Flags); @@ -1225,7 +1471,7 @@ IntCleanupMenus(struct _EPROCESS *Process, PPROCESSINFO Win32Process) { PEPROCESS CurrentProcess; PLIST_ENTRY LastHead = NULL; - PMENU_OBJECT MenuObject; + PMENU MenuObject; CurrentProcess = PsGetCurrentProcess(); if (CurrentProcess != Process) @@ -1237,8 +1483,8 @@ IntCleanupMenus(struct _EPROCESS *Process, PPROCESSINFO Win32Process) Win32Process->MenuListHead.Flink != LastHead) { LastHead = Win32Process->MenuListHead.Flink; - MenuObject = CONTAINING_RECORD(Win32Process->MenuListHead.Flink, MENU_OBJECT, ListEntry); - + MenuObject = CONTAINING_RECORD(Win32Process->MenuListHead.Flink, MENU, ListEntry); + ERR("Menus are stuck on the process list!\n"); IntDestroyMenuObject(MenuObject, FALSE, TRUE); } @@ -1382,7 +1628,7 @@ intGetTitleBarInfo(PWND pWindowObject, PTITLEBARINFO bti) DWORD FASTCALL UserInsertMenuItem( - PMENU_OBJECT Menu, + PMENU Menu, UINT uItem, BOOL fByPosition, LPCMENUITEMINFOW UnsafeItemInfo) @@ -1422,117 +1668,87 @@ UserInsertMenuItem( UINT FASTCALL IntGetMenuState( HMENU hMenu, UINT uId, UINT uFlags) { - PMENU_OBJECT MenuObject, SubMenu; - PMENU_ITEM mi; + PMENU MenuObject; + PITEM pItem; if (!(MenuObject = UserGetMenuObject(hMenu))) { return (UINT)-1; } - if (IntGetMenuItemByFlag(MenuObject, uId, uFlags, &SubMenu, &mi, NULL)) + if (!(pItem = MENU_FindItem( &MenuObject, &uId, uFlags ))) return -1; + + if (pItem->spSubMenu) { - if (mi->hSubMenu) - { - if (SubMenu) - { - UINT nSubItems = SubMenu->MenuInfo.MenuItemCount; - return (nSubItems << 8) | ((mi->fState | mi->fType) & 0xff); - } - else - return (UINT)-1; - } - return (mi->fType | mi->fState); + return (pItem->spSubMenu->cItems << 8) | ((pItem->fState|pItem->fType) & 0xff); } - return (UINT)-1; + else + return (pItem->fType | pItem->fState); } HMENU FASTCALL IntGetSubMenu( HMENU hMenu, int nPos) { - PMENU_OBJECT MenuObject, SubMenu; + PMENU MenuObject; + PITEM pItem; if (!(MenuObject = UserGetMenuObject(hMenu))) { return NULL; } - if (IntGetMenuItemByFlag(MenuObject, nPos, MF_BYPOSITION, &SubMenu, NULL, NULL)) + + if (!(pItem = MENU_FindItem( &MenuObject, (UINT*)&nPos, MF_BYPOSITION ))) return NULL; + + if (pItem->spSubMenu) { - return SubMenu ? UserHMGetHandle(SubMenu) : NULL; + HMENU hsubmenu = UserHMGetHandle(pItem->spSubMenu); + return hsubmenu; } return NULL; } UINT FASTCALL IntFindSubMenu(HMENU *hMenu, HMENU hSubTarget ) { - PMENU_OBJECT MenuObject; - PMENU_ITEM mi; - UINT i; + PMENU menu; + HMENU hSubMenu; + UINT i; + PITEM item; - if ( (*hMenu) == (HMENU)0xffff || !(MenuObject = UserGetMenuObject(*hMenu)) ) - return NO_SELECTED_ITEM; + if (((*hMenu)==(HMENU)0xffff) ||(!(menu = UserGetMenuObject(*hMenu)))) + return NO_SELECTED_ITEM; - for (i = 0; i < MenuObject->MenuInfo.MenuItemCount; i++) - { - if (!IntGetMenuItemByFlag(MenuObject, i, MF_BYPOSITION, NULL, &mi, NULL)) - { - return NO_SELECTED_ITEM; - } - - if (!(mi->hSubMenu)) continue; - - if (mi->hSubMenu == hSubTarget) - { - return i; - } - else - { - HMENU hsubmenu = mi->hSubMenu; - UINT pos = IntFindSubMenu(&hsubmenu, hSubTarget ); - if (pos != NO_SELECTED_ITEM) - { - *hMenu = hsubmenu; - return pos; - } - } - } - return NO_SELECTED_ITEM; + item = menu->rgItems; + for (i = 0; i < menu->cItems; i++, item = item->Next)//item++) + { + if (!item->spSubMenu) + continue; + else + { + hSubMenu = UserHMGetHandle(item->spSubMenu); + if (hSubMenu == hSubTarget) + { + return i; + } + else + { + HMENU hsubmenu = hSubMenu; + UINT pos = IntFindSubMenu( &hsubmenu, hSubTarget ); + if (pos != NO_SELECTED_ITEM) + { + *hMenu = hsubmenu; + return pos; + } + } + } + } + return NO_SELECTED_ITEM; } -/* FUNCTIONS *****************************************************************/ - -/* - * @implemented - */ -DWORD APIENTRY -NtUserCheckMenuItem( - HMENU hMenu, - UINT uIDCheckItem, - UINT uCheck) -{ - PMENU_OBJECT Menu; - DECLARE_RETURN(DWORD); - - TRACE("Enter NtUserCheckMenuItem\n"); - UserEnterExclusive(); - - if(!(Menu = UserGetMenuObject(hMenu))) - { - RETURN( (DWORD)-1); - } - - RETURN( IntCheckMenuItem(Menu, uIDCheckItem, uCheck)); - -CLEANUP: - TRACE("Leave NtUserCheckMenuItem, ret=%lu\n",_ret_); - UserLeave(); - END_CLEANUP; -} HMENU FASTCALL UserCreateMenu(BOOL PopupMenu) { PWINSTATION_OBJECT WinStaObject; HANDLE Handle; - PMENU_OBJECT Menu; + PMENU Menu; NTSTATUS Status; PEPROCESS CurrentProcess = PsGetCurrentProcess(); @@ -1555,6 +1771,10 @@ HMENU FASTCALL UserCreateMenu(BOOL PopupMenu) return (HMENU)0; } Menu = IntCreateMenu(&Handle, !PopupMenu); + if (Menu->head.rpdesk->rpwinstaParent != WinStaObject) + { + ERR("Desktop Window Station does not match Process one!\n"); + } ObDereferenceObject(WinStaObject); } else @@ -1566,6 +1786,221 @@ HMENU FASTCALL UserCreateMenu(BOOL PopupMenu) return (HMENU)Handle; } +BOOL FASTCALL +UserMenuItemInfo( + PMENU Menu, + UINT Item, + BOOL ByPosition, + PROSMENUITEMINFO UnsafeItemInfo, + BOOL SetOrGet) +{ + PITEM MenuItem; + ROSMENUITEMINFO ItemInfo; + NTSTATUS Status; + UINT Size; + BOOL Ret; + + Status = MmCopyFromCaller(&Size, &UnsafeItemInfo->cbSize, sizeof(UINT)); + if (! NT_SUCCESS(Status)) + { + SetLastNtError(Status); + return( FALSE); + } + if (sizeof(MENUITEMINFOW) != Size + && FIELD_OFFSET(MENUITEMINFOW, hbmpItem) != Size + && sizeof(ROSMENUITEMINFO) != Size) + { + EngSetLastError(ERROR_INVALID_PARAMETER); + return( FALSE); + } + Status = MmCopyFromCaller(&ItemInfo, UnsafeItemInfo, Size); + if (! NT_SUCCESS(Status)) + { + SetLastNtError(Status); + return( FALSE); + } + /* If this is a pre-0x0500 _WIN32_WINNT MENUITEMINFOW, you can't + set/get hbmpItem */ + if (FIELD_OFFSET(MENUITEMINFOW, hbmpItem) == Size + && 0 != (ItemInfo.fMask & MIIM_BITMAP)) + { + EngSetLastError(ERROR_INVALID_PARAMETER); + return( FALSE); + } + + if (!(MenuItem = MENU_FindItem( &Menu, &Item, (ByPosition ? MF_BYPOSITION : MF_BYCOMMAND) ))) + { + EngSetLastError(ERROR_MENU_ITEM_NOT_FOUND); + return( FALSE); + } + + if (SetOrGet) + { + Ret = IntSetMenuItemInfo(Menu, MenuItem, &ItemInfo, NULL); + } + else + { + Ret = IntGetMenuItemInfo(Menu, MenuItem, &ItemInfo); + if (Ret) + { + Status = MmCopyToCaller(UnsafeItemInfo, &ItemInfo, Size); + if (! NT_SUCCESS(Status)) + { + SetLastNtError(Status); + return( FALSE); + } + } + } + + return( Ret); +} + +BOOL FASTCALL +UserMenuInfo( + PMENU Menu, + PROSMENUINFO UnsafeMenuInfo, + BOOL SetOrGet) +{ + BOOL Res; + DWORD Size; + NTSTATUS Status; + ROSMENUINFO MenuInfo; + + Status = MmCopyFromCaller(&Size, &UnsafeMenuInfo->cbSize, sizeof(DWORD)); + if (! NT_SUCCESS(Status)) + { + SetLastNtError(Status); + return( FALSE); + } + if(Size < sizeof(MENUINFO) || sizeof(ROSMENUINFO) < Size) + { + EngSetLastError(ERROR_INVALID_PARAMETER); + return( FALSE); + } + Status = MmCopyFromCaller(&MenuInfo, UnsafeMenuInfo, Size); + if (! NT_SUCCESS(Status)) + { + SetLastNtError(Status); + return( FALSE); + } + + if(SetOrGet) + { + /* Set MenuInfo */ + Res = IntSetMenuInfo(Menu, &MenuInfo); + } + else + { + /* Get MenuInfo */ + Res = IntGetMenuInfo(Menu, &MenuInfo); + if (Res) + { + Status = MmCopyToCaller(UnsafeMenuInfo, &MenuInfo, Size); + if (! NT_SUCCESS(Status)) + { + SetLastNtError(Status); + return( FALSE); + } + } + } + + return( Res); +} + +VOID FASTCALL +MENU_AdjustMenuItemRect(PMENU menu, PRECTL rect) +{ + if (menu->dwArrowsOn) + { + UINT arrow_bitmap_height; + //BITMAP bmp; + //GetObjectW(get_up_arrow_bitmap(), sizeof(bmp), &bmp); + arrow_bitmap_height = gpsi->oembmi[65].cy; ///// Menu up arrow! OBM_UPARROW DFCS_MENUARROWUP + //arrow_bitmap_height = bmp.bmHeight; + rect->top += arrow_bitmap_height - menu->iTop; + rect->bottom += arrow_bitmap_height - menu->iTop; + } +} + +BOOL FASTCALL +IntGetMenuItemRect( + PWND pWnd, + PMENU Menu, + UINT uItem, + PRECTL Rect) +{ + LONG XMove, YMove; + PITEM MenuItem; + //int p = 0; + + if (!pWnd) + { + HWND hWnd = Menu->hWnd; + if (!(pWnd = UserGetWindowObject(hWnd))) return FALSE; + } + + if ((MenuItem = MENU_FindItem (&Menu, &uItem, MF_BYPOSITION))) + { + Rect->left = MenuItem->xItem; + Rect->top = MenuItem->yItem; + Rect->right = MenuItem->cxItem; // Do this for now...... + Rect->bottom = MenuItem->cyItem; + } + else + { + ERR("Failed Item Lookup! %d\n", uItem); + return FALSE; + } + + if (Menu->fFlags & MNF_POPUP) + { + XMove = pWnd->rcClient.left; + YMove = pWnd->rcClient.top; + } + else + { + XMove = pWnd->rcWindow.left; + YMove = pWnd->rcWindow.top; + } + + Rect->left += XMove; + Rect->top += YMove; + Rect->right += XMove; + Rect->bottom += YMove; + + return TRUE; +} + +/* FUNCTIONS *****************************************************************/ + +/* + * @implemented + */ +DWORD APIENTRY +NtUserCheckMenuItem( + HMENU hMenu, + UINT uIDCheckItem, + UINT uCheck) +{ + PMENU Menu; + DECLARE_RETURN(DWORD); + + TRACE("Enter NtUserCheckMenuItem\n"); + UserEnterExclusive(); + + if(!(Menu = UserGetMenuObject(hMenu))) + { + RETURN( (DWORD)-1); + } + + RETURN( IntCheckMenuItem(Menu, uIDCheckItem, uCheck)); + +CLEANUP: + TRACE("Leave NtUserCheckMenuItem, ret=%lu\n",_ret_); + UserLeave(); + END_CLEANUP; +} + /* * @implemented */ @@ -1575,7 +2010,7 @@ NtUserDeleteMenu( UINT uPosition, UINT uFlags) { - PMENU_OBJECT Menu; + PMENU Menu; DECLARE_RETURN(BOOL); TRACE("Enter NtUserDeleteMenu\n"); @@ -1666,19 +2101,20 @@ CLEANUP: */ BOOL FASTCALL UserDestroyMenu(HMENU hMenu) { - PMENU_OBJECT Menu; + PMENU Menu; + PTHREADINFO pti = PsGetCurrentThreadWin32Thread(); if(!(Menu = UserGetMenuObject(hMenu))) { return FALSE; } - if(Menu->Process != PsGetCurrentProcess()) + //if(Menu->Process != PsGetCurrentProcess()) + if (Menu->head.rpdesk != pti->rpdesk) { EngSetLastError(ERROR_ACCESS_DENIED); return FALSE; } - return IntDestroyMenuObject(Menu, FALSE, TRUE); } @@ -1689,7 +2125,7 @@ BOOL APIENTRY NtUserDestroyMenu( HMENU hMenu) { - PMENU_OBJECT Menu; + PMENU Menu; DECLARE_RETURN(BOOL); TRACE("Enter NtUserDestroyMenu\n"); @@ -1699,13 +2135,11 @@ NtUserDestroyMenu( { RETURN( FALSE); } - - if(Menu->Process != PsGetCurrentProcess()) + if (Menu->head.rpdesk != gptiCurrent->rpdesk) { EngSetLastError(ERROR_ACCESS_DENIED); RETURN( FALSE); } - RETURN( IntDestroyMenuObject(Menu, TRUE, TRUE)); CLEANUP: @@ -1723,7 +2157,7 @@ NtUserEnableMenuItem( UINT uIDEnableItem, UINT uEnable) { - PMENU_OBJECT Menu; + PMENU Menu; DECLARE_RETURN(UINT); TRACE("Enter NtUserEnableMenuItem\n"); @@ -1742,50 +2176,6 @@ CLEANUP: END_CLEANUP; } -BOOL FASTCALL -IntGetMenuItemRect( - PWND pWnd, - PMENU_OBJECT Menu, - UINT uItem, - PRECTL Rect) -{ - LONG XMove, YMove; - PMENU_ITEM MenuItem; - int p = 0; - - if (!pWnd) - { - HWND hWnd = Menu->MenuInfo.Wnd; - if (!(pWnd = UserGetWindowObject(hWnd))) return FALSE; - } - - if ((p = IntGetMenuItemByFlag(Menu, uItem, MF_BYPOSITION, NULL, &MenuItem, NULL)) > -1) - *Rect = MenuItem->Rect; - else - { - ERR("Failed Item Lookup! %d\n", p); - return FALSE; - } - - if (Menu->MenuInfo.Flags & MNF_POPUP) - { - XMove = pWnd->rcClient.left; - YMove = pWnd->rcClient.top; - } - else - { - XMove = pWnd->rcWindow.left; - YMove = pWnd->rcWindow.top; - } - - Rect->left += XMove; - Rect->top += YMove; - Rect->right += XMove; - Rect->bottom += YMove; - - return TRUE; -} - /* * @implemented */ @@ -1801,7 +2191,7 @@ NtUserGetMenuBarInfo( MENUBARINFO kmbi; BOOL Ret; NTSTATUS Status = STATUS_SUCCESS; - PMENU_OBJECT Menu = NULL; + PMENU Menu = NULL; DECLARE_RETURN(BOOL); TRACE("Enter NtUserGetMenuBarInfo\n"); @@ -1833,7 +2223,7 @@ NtUserGetMenuBarInfo( case OBJID_SYSMENU: if (!(pWnd->style & WS_SYSMENU)) RETURN(FALSE); Menu = IntGetSystemMenu(pWnd, FALSE, FALSE); - hMenu = Menu->MenuInfo.Self; + hMenu = Menu->head.h; break; default: RETURN(FALSE); @@ -1862,16 +2252,16 @@ NtUserGetMenuBarInfo( if (!Menu) RETURN(FALSE); - if (idItem < 0 || idItem > Menu->MenuInfo.MenuItemCount) + if (idItem < 0 || idItem > Menu->cItems) RETURN(FALSE); RECTL_vSetEmptyRect(&kmbi.rcBar); if (idItem == 0) { - Ret = IntGetMenuItemRect(pWnd, Menu, -1, &kmbi.rcBar); - kmbi.rcBar.right = kmbi.rcBar.left + Menu->MenuInfo.Width; - kmbi.rcBar.bottom = kmbi.rcBar.top + Menu->MenuInfo.Height; + Ret = IntGetMenuItemRect(pWnd, Menu, 0, &kmbi.rcBar); + kmbi.rcBar.right = kmbi.rcBar.left + Menu->cxMenu; + kmbi.rcBar.bottom = kmbi.rcBar.top + Menu->cyMenu; ERR("idItem 0 %d\n",Ret); } else @@ -1882,16 +2272,20 @@ NtUserGetMenuBarInfo( kmbi.hMenu = hMenu; kmbi.hwndMenu = NULL; + kmbi.fBarFocused = FALSE; + kmbi.fFocused = FALSE; //kmbi.fBarFocused = top_popup_hmenu == hMenu; if (idItem) { - PMENU_OBJECT SubMenuObject; - kmbi.fFocused = Menu->MenuInfo.FocusedItem == idItem-1; - - if ( kmbi.fFocused && Menu->MenuItemList->hSubMenu ) + PITEM MenuItem; + UINT nPos = idItem-1; + kmbi.fFocused = Menu->iItem == idItem-1; + //if (kmbi->fFocused && (Menu->rgItems[idItem - 1].spSubMenu)) + MenuItem = MENU_FindItem (&Menu, &nPos, MF_BYPOSITION); + if ( MenuItem && kmbi.fFocused && MenuItem->spSubMenu ) { - SubMenuObject = UserGetMenuObject(Menu->MenuItemList->hSubMenu); - if (SubMenuObject) kmbi.hwndMenu = SubMenuObject->MenuInfo.Wnd; + //kmbi.hwndMenu = Menu->rgItems[idItem - 1].spSubMenu->hWnd; + kmbi.hwndMenu = MenuItem->spSubMenu->hWnd; } } /* else @@ -1931,8 +2325,8 @@ NtUserGetMenuIndex( HMENU hMenu, HMENU hSubMenu) { - PMENU_OBJECT Menu, SubMenu; - PMENU_ITEM MenuItem; + PMENU Menu, SubMenu; + PITEM MenuItem; DECLARE_RETURN(UINT); TRACE("Enter NtUserGetMenuIndex\n"); @@ -1942,10 +2336,10 @@ NtUserGetMenuIndex( !(SubMenu = UserGetMenuObject(hSubMenu)) ) RETURN(0xFFFFFFFF); - MenuItem = Menu->MenuItemList; + MenuItem = Menu->rgItems; while(MenuItem) { - if (MenuItem->hSubMenu == hSubMenu) + if (MenuItem->spSubMenu == SubMenu) RETURN(MenuItem->wID); MenuItem = MenuItem->Next; } @@ -1971,8 +2365,8 @@ NtUserGetMenuItemRect( PWND ReferenceWnd; LONG XMove, YMove; RECTL Rect; - PMENU_OBJECT Menu; - PMENU_ITEM MenuItem; + PMENU Menu; + PITEM MenuItem; NTSTATUS Status = STATUS_SUCCESS; DECLARE_RETURN(BOOL); @@ -1984,21 +2378,26 @@ NtUserGetMenuItemRect( RETURN(FALSE); } - if (IntGetMenuItemByFlag(Menu, uItem, MF_BYPOSITION, NULL, &MenuItem, NULL) > -1) - Rect = MenuItem->Rect; + if ((MenuItem = MENU_FindItem (&Menu, &uItem, MF_BYPOSITION))) + { + Rect.left = MenuItem->xItem; + Rect.top = MenuItem->yItem; + Rect.right = MenuItem->cxItem; // Do this for now...... + Rect.bottom = MenuItem->cyItem; + } else RETURN(FALSE); if(!hWnd) { - hWnd = Menu->MenuInfo.Wnd; + hWnd = Menu->hWnd; } if (lprcItem == NULL) RETURN( FALSE); if (!(ReferenceWnd = UserGetWindowObject(hWnd))) RETURN( FALSE); - if (Menu->MenuInfo.Flags & MNF_POPUP) + if (Menu->fFlags & MNF_POPUP) { XMove = ReferenceWnd->rcClient.left; YMove = ReferenceWnd->rcClient.top; @@ -2047,7 +2446,7 @@ NtUserHiliteMenuItem( UINT uItemHilite, UINT uHilite) { - PMENU_OBJECT Menu; + PMENU Menu; PWND Window; DECLARE_RETURN(BOOLEAN); @@ -2074,58 +2473,6 @@ CLEANUP: END_CLEANUP; } -static -BOOL FASTCALL -UserMenuInfo( - PMENU_OBJECT Menu, - PROSMENUINFO UnsafeMenuInfo, - BOOL SetOrGet) -{ - BOOL Res; - DWORD Size; - NTSTATUS Status; - ROSMENUINFO MenuInfo; - - Status = MmCopyFromCaller(&Size, &UnsafeMenuInfo->cbSize, sizeof(DWORD)); - if (! NT_SUCCESS(Status)) - { - SetLastNtError(Status); - return( FALSE); - } - if(Size < sizeof(MENUINFO) || sizeof(ROSMENUINFO) < Size) - { - EngSetLastError(ERROR_INVALID_PARAMETER); - return( FALSE); - } - Status = MmCopyFromCaller(&MenuInfo, UnsafeMenuInfo, Size); - if (! NT_SUCCESS(Status)) - { - SetLastNtError(Status); - return( FALSE); - } - - if(SetOrGet) - { - /* Set MenuInfo */ - Res = IntSetMenuInfo(Menu, &MenuInfo); - } - else - { - /* Get MenuInfo */ - Res = IntGetMenuInfo(Menu, &MenuInfo); - if (Res) - { - Status = MmCopyToCaller(UnsafeMenuInfo, &MenuInfo, Size); - if (! NT_SUCCESS(Status)) - { - SetLastNtError(Status); - return( FALSE); - } - } - } - - return( Res); -} /* * @implemented @@ -2137,9 +2484,9 @@ NtUserMenuItemFromPoint( DWORD X, DWORD Y) { - PMENU_OBJECT Menu; + PMENU Menu; PWND Window = NULL; - PMENU_ITEM mi; + PITEM mi; int i; DECLARE_RETURN(int); @@ -2151,7 +2498,7 @@ NtUserMenuItemFromPoint( RETURN( -1); } - if (!(Window = UserGetWindowObject(Menu->MenuInfo.Wnd))) + if (!(Window = UserGetWindowObject(Menu->hWnd))) { RETURN( -1); } @@ -2159,10 +2506,16 @@ NtUserMenuItemFromPoint( X -= Window->rcWindow.left; Y -= Window->rcWindow.top; - mi = Menu->MenuItemList; - for (i = 0; NULL != mi; i++) + mi = Menu->rgItems; + for (i = 0; NULL != mi; i++)//, mi++) { - if (RECTL_bPointInRect(&(mi->Rect), X, Y)) + RECTL Rect; + Rect.left = mi->xItem; + Rect.top = mi->yItem; + Rect.right = mi->cxItem; // Do this for now...... + Rect.bottom = mi->cyItem; + //MENU_AdjustMenuItemRect(Menu, &Rect); Need gpsi OBMI via callback! + if (RECTL_bPointInRect(&Rect, X, Y)) { break; } @@ -2177,80 +2530,6 @@ CLEANUP: END_CLEANUP; } -static -BOOL FASTCALL -UserMenuItemInfo( - PMENU_OBJECT Menu, - UINT Item, - BOOL ByPosition, - PROSMENUITEMINFO UnsafeItemInfo, - BOOL SetOrGet) -{ - PMENU_ITEM MenuItem; - ROSMENUITEMINFO ItemInfo; - NTSTATUS Status; - UINT Size; - BOOL Ret; - - Status = MmCopyFromCaller(&Size, &UnsafeItemInfo->cbSize, sizeof(UINT)); - if (! NT_SUCCESS(Status)) - { - SetLastNtError(Status); - return( FALSE); - } - if (sizeof(MENUITEMINFOW) != Size - && FIELD_OFFSET(MENUITEMINFOW, hbmpItem) != Size - && sizeof(ROSMENUITEMINFO) != Size) - { - EngSetLastError(ERROR_INVALID_PARAMETER); - return( FALSE); - } - Status = MmCopyFromCaller(&ItemInfo, UnsafeItemInfo, Size); - if (! NT_SUCCESS(Status)) - { - SetLastNtError(Status); - return( FALSE); - } - /* If this is a pre-0x0500 _WIN32_WINNT MENUITEMINFOW, you can't - set/get hbmpItem */ - if (FIELD_OFFSET(MENUITEMINFOW, hbmpItem) == Size - && 0 != (ItemInfo.fMask & MIIM_BITMAP)) - { - EngSetLastError(ERROR_INVALID_PARAMETER); - return( FALSE); - } - - if (IntGetMenuItemByFlag(Menu, Item, - (ByPosition ? MF_BYPOSITION : MF_BYCOMMAND), - NULL, &MenuItem, NULL) < 0) - { - EngSetLastError(ERROR_INVALID_PARAMETER); -// This will crash menu (line 80) correct_behavior test! -// "NT4 and below can't handle a bigger MENUITEMINFO struct" -// EngSetLastError(ERROR_MENU_ITEM_NOT_FOUND); - return( FALSE); - } - - if (SetOrGet) - { - Ret = IntSetMenuItemInfo(Menu, MenuItem, &ItemInfo); - } - else - { - Ret = IntGetMenuItemInfo(Menu, MenuItem, &ItemInfo); - if (Ret) - { - Status = MmCopyToCaller(UnsafeItemInfo, &ItemInfo, Size); - if (! NT_SUCCESS(Status)) - { - SetLastNtError(Status); - return( FALSE); - } - } - } - - return( Ret); -} /* * @implemented @@ -2261,7 +2540,7 @@ NtUserRemoveMenu( UINT uPosition, UINT uFlags) { - PMENU_OBJECT Menu; + PMENU Menu; DECLARE_RETURN(BOOL); TRACE("Enter NtUserRemoveMenu\n"); @@ -2289,7 +2568,7 @@ NtUserSetMenuContextHelpId( HMENU hMenu, DWORD dwContextHelpId) { - PMENU_OBJECT Menu; + PMENU Menu; DECLARE_RETURN(BOOL); TRACE("Enter NtUserSetMenuContextHelpId\n"); @@ -2317,7 +2596,7 @@ NtUserSetMenuDefaultItem( UINT uItem, UINT fByPos) { - PMENU_OBJECT Menu; + PMENU Menu; DECLARE_RETURN(BOOL); TRACE("Enter NtUserSetMenuDefaultItem\n"); @@ -2343,7 +2622,7 @@ BOOL APIENTRY NtUserSetMenuFlagRtoL( HMENU hMenu) { - PMENU_OBJECT Menu; + PMENU Menu; DECLARE_RETURN(BOOL); TRACE("Enter NtUserSetMenuFlagRtoL\n"); @@ -2370,7 +2649,7 @@ NtUserThunkedMenuInfo( HMENU hMenu, LPCMENUINFO lpcmi) { - PMENU_OBJECT Menu; + PMENU Menu; DECLARE_RETURN(BOOL); TRACE("Enter NtUserThunkedMenuInfo\n"); @@ -2401,7 +2680,7 @@ NtUserThunkedMenuItemInfo( LPMENUITEMINFOW lpmii, PUNICODE_STRING lpszCaption) { - PMENU_OBJECT Menu; + PMENU Menu; NTSTATUS Status; UNICODE_STRING lstrCaption; DECLARE_RETURN(BOOL); @@ -2420,7 +2699,7 @@ NtUserThunkedMenuItemInfo( lstrCaption.Buffer = NULL; /* Check if we got a Caption */ - if (lpszCaption) + if (lpszCaption && lpszCaption->Buffer) { /* Copy the string to kernel mode */ Status = ProbeAndCaptureUnicodeString( &lstrCaption, @@ -2432,6 +2711,7 @@ NtUserThunkedMenuItemInfo( SetLastNtError(Status); RETURN(FALSE); } + ///// Now use it! } if (bInsert) RETURN( UserInsertMenuItem(Menu, uItem, fByPosition, lpmii)); @@ -2444,135 +2724,4 @@ CLEANUP: END_CLEANUP; } -////// ReactOS NtUserBad -/* - * @implemented - */ -DWORD -APIENTRY -NtUserBuildMenuItemList( - HMENU hMenu, - VOID* Buffer, - ULONG nBufSize, - DWORD Reserved) -{ - DWORD res = -1; - PMENU_OBJECT Menu; - DECLARE_RETURN(DWORD); - - TRACE("Enter NtUserBuildMenuItemList\n"); - UserEnterExclusive(); - - if(!(Menu = UserGetMenuObject(hMenu))) - { - RETURN( (DWORD)-1); - } - - if(Buffer) - { - res = IntBuildMenuItemList(Menu, Buffer, nBufSize); - } - else - { - res = Menu->MenuInfo.MenuItemCount; - } - - RETURN( res); - -CLEANUP: - TRACE("Leave NtUserBuildMenuItemList, ret=%lu\n",_ret_); - UserLeave(); - END_CLEANUP; -} - -/* - * @implemented - */ -UINT APIENTRY -NtUserGetMenuDefaultItem( - HMENU hMenu, - UINT fByPos, - UINT gmdiFlags) -{ - PMENU_OBJECT Menu; - DWORD gismc = 0; - DECLARE_RETURN(UINT); - - TRACE("Enter NtUserGetMenuDefaultItem\n"); - UserEnterExclusive(); - - if(!(Menu = UserGetMenuObject(hMenu))) - { - RETURN(-1); - } - - RETURN( IntGetMenuDefaultItem(Menu, fByPos, gmdiFlags, &gismc)); - -CLEANUP: - TRACE("Leave NtUserGetMenuDefaultItem, ret=%u\n",_ret_); - UserLeave(); - END_CLEANUP; -} - -/* - * @implemented - */ -BOOL -APIENTRY -NtUserMenuInfo( - HMENU hMenu, - PROSMENUINFO UnsafeMenuInfo, - BOOL SetOrGet) -{ - PMENU_OBJECT Menu; - DECLARE_RETURN(BOOL); - - TRACE("Enter NtUserMenuInfo\n"); - UserEnterShared(); - - if (!(Menu = UserGetMenuObject(hMenu))) - { - RETURN(FALSE); - } - - RETURN(UserMenuInfo(Menu, UnsafeMenuInfo, SetOrGet)); - -CLEANUP: - TRACE("Leave NtUserMenuInfo, ret=%i\n",_ret_); - UserLeave(); - END_CLEANUP; -} - -/* - * @implemented - */ -BOOL -APIENTRY -NtUserMenuItemInfo( - HMENU hMenu, - UINT Item, - BOOL ByPosition, - PROSMENUITEMINFO UnsafeItemInfo, - BOOL SetOrGet) -{ - PMENU_OBJECT Menu; - DECLARE_RETURN(BOOL); - - TRACE("Enter NtUserMenuItemInfo\n"); - UserEnterExclusive(); - - if (!(Menu = UserGetMenuObject(hMenu))) - { - RETURN(FALSE); - } - - RETURN( UserMenuItemInfo(Menu, Item, ByPosition, UnsafeItemInfo, SetOrGet)); - -CLEANUP: - TRACE("Leave NtUserMenuItemInfo, ret=%i\n",_ret_); - UserLeave(); - END_CLEANUP; - -} - /* EOF */ diff --git a/win32ss/user/ntuser/menu.h b/win32ss/user/ntuser/menu.h index 1ca12747dbb..9ff6b0cbee0 100644 --- a/win32ss/user/ntuser/menu.h +++ b/win32ss/user/ntuser/menu.h @@ -10,32 +10,6 @@ #define MF_END (0x0080) #endif -typedef struct _MENU_ITEM -{ - struct _MENU_ITEM *Next; - UINT fType; - UINT fState; - UINT wID; - HMENU hSubMenu; - HBITMAP hbmpChecked; - HBITMAP hbmpUnchecked; - ULONG_PTR dwItemData; - UNICODE_STRING Text; - HBITMAP hbmpItem; - RECTL Rect; - UINT dxTab; -} MENU_ITEM, *PMENU_ITEM; - -typedef struct _MENU_OBJECT -{ - PROCDESKHEAD head; - PEPROCESS Process; - LIST_ENTRY ListEntry; - PMENU_ITEM MenuItemList; - ROSMENUINFO MenuInfo; - BOOL RtoL; -} MENU_OBJECT, *PMENU_OBJECT; - typedef struct _SETMENUITEMRECT { UINT uItem; @@ -43,33 +17,34 @@ typedef struct _SETMENUITEMRECT RECTL rcRect; } SETMENUITEMRECT, *PSETMENUITEMRECT; -PMENU_OBJECT FASTCALL +PMENU FASTCALL IntGetMenuObject(HMENU hMenu); #define IntReleaseMenuObject(MenuObj) \ UserDereferenceObject(MenuObj) BOOL FASTCALL -IntDestroyMenuObject(PMENU_OBJECT MenuObject, BOOL bRecurse, BOOL RemoveFromProcess); +IntDestroyMenuObject(PMENU MenuObject, BOOL bRecurse, BOOL RemoveFromProcess); -PMENU_OBJECT FASTCALL -IntCloneMenu(PMENU_OBJECT Source); +PMENU FASTCALL +IntCloneMenu(PMENU Source); int FASTCALL -IntGetMenuItemByFlag(PMENU_OBJECT MenuObject, UINT uSearchBy, UINT fFlag, - PMENU_OBJECT *SubMenu, PMENU_ITEM *MenuItem, - PMENU_ITEM *PrevMenuItem); +IntGetMenuItemByFlag(PMENU MenuObject, UINT uSearchBy, UINT fFlag, + PMENU *SubMenu, PITEM *MenuItem, + PITEM *PrevMenuItem); BOOL FASTCALL IntCleanupMenus(struct _EPROCESS *Process, PPROCESSINFO Win32Process); BOOL FASTCALL -IntInsertMenuItem(_In_ PMENU_OBJECT MenuObject, UINT uItem, BOOL fByPosition, +IntInsertMenuItem(_In_ PMENU MenuObject, UINT uItem, BOOL fByPosition, PROSMENUITEMINFO ItemInfo); -PMENU_OBJECT FASTCALL +PMENU FASTCALL IntGetSystemMenu(PWND Window, BOOL bRevert, BOOL RetMenu); UINT FASTCALL IntFindSubMenu(HMENU *hMenu, HMENU hSubTarget ); UINT FASTCALL IntGetMenuState( HMENU hMenu, UINT uId, UINT uFlags); - +BOOL FASTCALL IntRemoveMenuItem(PMENU Menu, UINT uPosition, UINT uFlags, BOOL bRecurse); +PITEM MENU_FindItem( PMENU *pmenu, UINT *nPos, UINT wFlags ); diff --git a/win32ss/user/ntuser/ntstubs.c b/win32ss/user/ntuser/ntstubs.c index 2176cde0755..bc9705e6398 100644 --- a/win32ss/user/ntuser/ntstubs.c +++ b/win32ss/user/ntuser/ntstubs.c @@ -1089,17 +1089,6 @@ NtUserUpdateLayeredWindow( return 0; } -/* - * @unimplemented - */ -HWND APIENTRY -NtUserWindowFromPhysicalPoint(POINT Point) -{ - STUB - - return NULL; -} - /* * NtUserResolveDesktopForWOW * diff --git a/win32ss/user/ntuser/object.c b/win32ss/user/ntuser/object.c index a7de628ff87..c807be0852e 100644 --- a/win32ss/user/ntuser/object.c +++ b/win32ss/user/ntuser/object.c @@ -597,7 +597,7 @@ PVOID FASTCALL ValidateHandle(HANDLE handle, HANDLE_TYPE type) } /* - * NtUserValidateHandleSecure + * NtUserValidateHandleSecure W2k3 has one argument. * * Status * @implemented @@ -609,62 +609,46 @@ NtUserValidateHandleSecure( HANDLE handle, BOOL Restricted) { - if(!Restricted) + UINT uType; + PPROCESSINFO ppi; + PUSER_HANDLE_ENTRY entry; + + DECLARE_RETURN(BOOL); + UserEnterExclusive(); + + if (!(entry = handle_to_entry(gHandleTable, handle ))) + { + EngSetLastError(ERROR_INVALID_HANDLE); + RETURN( FALSE); + } + uType = entry->type; + switch (uType) { - UINT uType; - { - PUSER_HANDLE_ENTRY entry; - if (!(entry = handle_to_entry(gHandleTable, handle ))) - { - EngSetLastError(ERROR_INVALID_HANDLE); - return FALSE; - } - uType = entry->type; - } - switch (uType) - { case TYPE_WINDOW: - { - if (UserGetWindowObject((HWND) handle)) return TRUE; - return FALSE; - } + case TYPE_INPUTCONTEXT: + ppi = ((PTHREADINFO)entry->pi)->ppi; + break; case TYPE_MENU: - { - if (UserGetMenuObject((HMENU) handle)) return TRUE; - return FALSE; - } case TYPE_ACCELTABLE: - { - if (UserGetAccelObject((HACCEL) handle)) return TRUE; - return FALSE; - } case TYPE_CURSOR: - { - if (UserGetCurIconObject((HCURSOR) handle)) return TRUE; - return FALSE; - } case TYPE_HOOK: - { - if (IntGetHookObject((HHOOK) handle)) return TRUE; - return FALSE; - } - case TYPE_MONITOR: - { - if (UserGetMonitorObject((HMONITOR) handle)) return TRUE; - return FALSE; - } case TYPE_CALLPROC: - { - WNDPROC_INFO Proc; - return UserGetCallProcInfo( handle, &Proc ); - } + case TYPE_SETWINDOWPOS: + ppi = entry->pi; + break; default: - EngSetLastError(ERROR_INVALID_HANDLE); - } + ppi = NULL; + break; } - else - { /* Is handle entry restricted? */ - STUB - } - return FALSE; + + if (!ppi) RETURN( FALSE); + + // Same process job returns TRUE. + if (gptiCurrent->ppi->pW32Job == ppi->pW32Job) RETURN( TRUE); + + RETURN( FALSE); + +CLEANUP: + UserLeave(); + END_CLEANUP; } diff --git a/win32ss/user/ntuser/simplecall.c b/win32ss/user/ntuser/simplecall.c index 59a92a5e62a..5661052c3e6 100644 --- a/win32ss/user/ntuser/simplecall.c +++ b/win32ss/user/ntuser/simplecall.c @@ -401,17 +401,17 @@ NtUserCallTwoParam( case TWOPARAM_ROUTINE_SETMENUBARHEIGHT: { DWORD_PTR Ret; - PMENU_OBJECT MenuObject = IntGetMenuObject((HMENU)Param1); + PMENU MenuObject = IntGetMenuObject((HMENU)Param1); if(!MenuObject) RETURN( 0); if(Param2 > 0) { - Ret = (MenuObject->MenuInfo.Height == (int)Param2); - MenuObject->MenuInfo.Height = (int)Param2; + Ret = (MenuObject->cyMenu == (int)Param2); + MenuObject->cyMenu = (int)Param2; } else - Ret = (DWORD_PTR)MenuObject->MenuInfo.Height; + Ret = (DWORD_PTR)MenuObject->cyMenu; IntReleaseMenuObject(MenuObject); RETURN( Ret); } @@ -564,9 +564,9 @@ NtUserCallHwndLock( break; case HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOWMOUSE: - TRACE("co_IntSetForegroundWindow 1 0x%p\n",hWnd); + TRACE("co_IntSetForegroundWindow M 1 0x%p\n",hWnd); Ret = co_IntSetForegroundWindowMouse(Window); - TRACE("co_IntSetForegroundWindow 2 0x%p\n",hWnd); + TRACE("co_IntSetForegroundWindow M 2 0x%p\n",hWnd); break; case HWNDLOCK_ROUTINE_UPDATEWINDOW: diff --git a/win32ss/user/ntuser/userfuncs.h b/win32ss/user/ntuser/userfuncs.h index 4cfff9f8678..96935084a42 100644 --- a/win32ss/user/ntuser/userfuncs.h +++ b/win32ss/user/ntuser/userfuncs.h @@ -1,6 +1,6 @@ #pragma once -PMENU_OBJECT FASTCALL UserGetMenuObject(HMENU hMenu); +PMENU FASTCALL UserGetMenuObject(HMENU hMenu); #define ASSERT_REFS_CO(_obj_) \ { \ @@ -109,7 +109,7 @@ PWND FASTCALL UserGetAncestor(PWND Wnd, UINT Type); /*************** MENU.C ***************/ HMENU FASTCALL UserCreateMenu(BOOL PopupMenu); -BOOL FASTCALL UserSetMenuDefaultItem(PMENU_OBJECT Menu, UINT uItem, UINT fByPos); +BOOL FASTCALL UserSetMenuDefaultItem(PMENU Menu, UINT uItem, UINT fByPos); BOOL FASTCALL UserDestroyMenu(HMENU hMenu); /*************** SCROLLBAR.C ***************/ diff --git a/win32ss/user/ntuser/window.c b/win32ss/user/ntuser/window.c index 102b4962aee..6e95a3e6b8d 100644 --- a/win32ss/user/ntuser/window.c +++ b/win32ss/user/ntuser/window.c @@ -459,7 +459,7 @@ UserFreeWindowInfo(PTHREADINFO ti, PWND Wnd) } // DesktopHeapFree(Wnd->head.rpdesk, Wnd); -// WindowObject->Wnd = NULL; +// WindowObject->hWnd = NULL; } /*********************************************************************** @@ -479,7 +479,7 @@ static LRESULT co_UserFreeWindow(PWND Window, HWND *Children; HWND *ChildHandle; PWND Child; - PMENU_OBJECT Menu; + PMENU Menu; BOOLEAN BelongsToThreadData; ASSERT(Window); @@ -792,7 +792,7 @@ IntSetMenu( HMENU Menu, BOOL *Changed) { - PMENU_OBJECT OldMenu, NewMenu = NULL; + PMENU OldMenu, NewMenu = NULL; if ((Wnd->style & (WS_CHILD | WS_POPUP)) == WS_CHILD) { @@ -810,7 +810,7 @@ IntSetMenu( if (Wnd->IDMenu) { OldMenu = IntGetMenuObject((HMENU) Wnd->IDMenu); - ASSERT(NULL == OldMenu || OldMenu->MenuInfo.Wnd == Wnd->head.h); + ASSERT(NULL == OldMenu || OldMenu->hWnd == Wnd->head.h); } else { @@ -829,7 +829,7 @@ IntSetMenu( EngSetLastError(ERROR_INVALID_MENU_HANDLE); return FALSE; } - if (NULL != NewMenu->MenuInfo.Wnd) + if (NULL != NewMenu->hWnd) { /* Can't use the same menu for two windows */ if (NULL != OldMenu) @@ -845,12 +845,12 @@ IntSetMenu( Wnd->IDMenu = (UINT) Menu; if (NULL != NewMenu) { - NewMenu->MenuInfo.Wnd = Wnd->head.h; + NewMenu->hWnd = Wnd->head.h; IntReleaseMenuObject(NewMenu); } if (NULL != OldMenu) { - OldMenu->MenuInfo.Wnd = NULL; + OldMenu->hWnd = NULL; IntReleaseMenuObject(OldMenu); } @@ -895,13 +895,13 @@ co_DestroyThreadWindows(struct _ETHREAD *Thread) } } -PMENU_OBJECT FASTCALL +PMENU FASTCALL IntGetSystemMenu(PWND Window, BOOL bRevert, BOOL RetMenu) { - PMENU_OBJECT Menu, NewMenu = NULL, SysMenu = NULL, ret = NULL; + PMENU Menu, NewMenu = NULL, SysMenu = NULL, ret = NULL; PTHREADINFO W32Thread; HMENU hNewMenu, hSysMenu; - ROSMENUITEMINFO ItemInfo; + ROSMENUITEMINFO ItemInfo = {0}; if(bRevert) { @@ -929,10 +929,10 @@ IntGetSystemMenu(PWND Window, BOOL bRevert, BOOL RetMenu) NewMenu = IntCloneMenu(Menu); if(NewMenu) - { - Window->SystemMenu = NewMenu->MenuInfo.Self; - NewMenu->MenuInfo.Flags |= MNF_SYSDESKMN; - NewMenu->MenuInfo.Wnd = Window->head.h; + { // Use spmenuSys + Window->SystemMenu = NewMenu->head.h; + NewMenu->fFlags |= MNF_SYSDESKMN; + NewMenu->hWnd = Window->head.h; ret = NewMenu; //IntReleaseMenuObject(NewMenu); } @@ -950,8 +950,8 @@ IntGetSystemMenu(PWND Window, BOOL bRevert, BOOL RetMenu) UserDestroyMenu(hSysMenu); return NULL; } - SysMenu->MenuInfo.Flags |= MNF_SYSDESKMN; - SysMenu->MenuInfo.Wnd = Window->head.h; + SysMenu->fFlags |= MNF_SYSDESKMN; + SysMenu->hWnd = Window->head.h; hNewMenu = co_IntLoadSysMenuTemplate(); if(!hNewMenu) { @@ -970,21 +970,24 @@ IntGetSystemMenu(PWND Window, BOOL bRevert, BOOL RetMenu) NewMenu = IntCloneMenu(Menu); if(NewMenu) { - NewMenu->MenuInfo.Flags |= MNF_SYSDESKMN | MNF_POPUP; - NewMenu->MenuInfo.dwStyle = MNS_CHECKORBMP; + NewMenu->fFlags |= MNF_SYSDESKMN | MNF_POPUP; + // Do not set MNS_CHECKORBMP it breaks menus, also original code destroyed the style anyway. IntReleaseMenuObject(NewMenu); UserSetMenuDefaultItem(NewMenu, SC_CLOSE, FALSE); + if (Window->pcls->style & CS_NOCLOSE) + IntRemoveMenuItem(NewMenu, SC_CLOSE, MF_BYCOMMAND, TRUE); + ItemInfo.cbSize = sizeof(MENUITEMINFOW); ItemInfo.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_STATE | MIIM_SUBMENU; ItemInfo.fType = 0; ItemInfo.fState = MFS_ENABLED; ItemInfo.dwTypeData = NULL; ItemInfo.cch = 0; - ItemInfo.hSubMenu = NewMenu->MenuInfo.Self; + ItemInfo.hSubMenu = NewMenu->head.h; IntInsertMenuItem(SysMenu, (UINT) -1, TRUE, &ItemInfo); - Window->SystemMenu = SysMenu->MenuInfo.Self; + Window->SystemMenu = SysMenu->head.h; ret = SysMenu; } @@ -1419,15 +1422,15 @@ co_UserSetParent(HWND hWndChild, HWND hWndNewParent) } BOOL FASTCALL -IntSetSystemMenu(PWND Window, PMENU_OBJECT Menu) +IntSetSystemMenu(PWND Window, PMENU Menu) { - PMENU_OBJECT OldMenu; + PMENU OldMenu; if(Window->SystemMenu) { OldMenu = IntGetMenuObject(Window->SystemMenu); if(OldMenu) { - OldMenu->MenuInfo.Flags &= ~ MNF_SYSDESKMN; + OldMenu->fFlags &= ~ MNF_SYSDESKMN; IntReleaseMenuObject(OldMenu); } } @@ -1435,10 +1438,10 @@ IntSetSystemMenu(PWND Window, PMENU_OBJECT Menu) if(Menu) { /* FIXME: Check window style, propably return FALSE? */ - Window->SystemMenu = Menu->MenuInfo.Self; - Menu->MenuInfo.Flags |= MNF_SYSDESKMN; + Window->SystemMenu = Menu->head.h; + Menu->fFlags |= MNF_SYSDESKMN; } - else + else // Use spmenuSys too! Window->SystemMenu = (HMENU)0; return TRUE; @@ -1752,7 +1755,7 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs, PWND pWnd = NULL; HWND hWnd; PTHREADINFO pti = NULL; - PMENU_OBJECT SystemMenu; + PMENU SystemMenu; BOOL MenuChanged; BOOL bUnicodeWindow; @@ -1985,8 +1988,8 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs, { SystemMenu = IntGetSystemMenu(pWnd, TRUE, TRUE); if(SystemMenu) - { - pWnd->SystemMenu = SystemMenu->MenuInfo.Self; + { // spmenuSys + pWnd->SystemMenu = SystemMenu->head.h; IntReleaseMenuObject(SystemMenu); } } @@ -3678,7 +3681,7 @@ HMENU APIENTRY NtUserGetSystemMenu(HWND hWnd, BOOL bRevert) { PWND Window; - PMENU_OBJECT Menu; + PMENU Menu; DECLARE_RETURN(HMENU); TRACE("Enter NtUserGetSystemMenu\n"); @@ -3694,7 +3697,7 @@ NtUserGetSystemMenu(HWND hWnd, BOOL bRevert) RETURN(NULL); } - RETURN(Menu->MenuInfo.Self); + RETURN(Menu->head.h); CLEANUP: TRACE("Leave NtUserGetSystemMenu, ret=%p\n", _ret_); @@ -3714,7 +3717,7 @@ NtUserSetSystemMenu(HWND hWnd, HMENU hMenu) { BOOL Result = FALSE; PWND Window; - PMENU_OBJECT Menu; + PMENU Menu; DECLARE_RETURN(BOOL); TRACE("Enter NtUserSetSystemMenu\n"); diff --git a/win32ss/user/user32/CMakeLists.txt b/win32ss/user/user32/CMakeLists.txt index 8ea0ea1f840..7178a825639 100644 --- a/win32ss/user/user32/CMakeLists.txt +++ b/win32ss/user/user32/CMakeLists.txt @@ -58,6 +58,7 @@ list(APPEND SOURCE windows/text.c windows/window.c windows/winpos.c + ${CMAKE_CURRENT_BINARY_DIR}/user32_stubs.c include/user32.h) if(USE_NEW_CURSORICON) diff --git a/win32ss/user/user32/controls/listbox.c b/win32ss/user/user32/controls/listbox.c index 18e0fe99660..7da8bef089f 100644 --- a/win32ss/user/user32/controls/listbox.c +++ b/win32ss/user/user32/controls/listbox.c @@ -74,7 +74,7 @@ typedef struct INT item_height; /* Default item height */ INT page_size; /* Items per listbox page */ INT column_width; /* Column width for multi-column listboxes */ - INT horz_extent; /* Horizontal extent (0 if no hscroll) */ + INT horz_extent; /* Horizontal extent */ INT horz_pos; /* Horizontal position */ INT nb_tabs; /* Number of tabs in array */ INT *tabs; /* Array of tabs */ @@ -259,17 +259,14 @@ static void LISTBOX_UpdateScroll( LB_DESCR *descr ) if (descr->style & WS_VSCROLL) SetScrollInfo( descr->self, SB_VERT, &info, TRUE ); - if (descr->horz_extent) + if (descr->style & WS_HSCROLL) { - info.nMin = 0; - info.nMax = descr->horz_extent - 1; info.nPos = descr->horz_pos; info.nPage = descr->width; - info.fMask = SIF_RANGE | SIF_POS | SIF_PAGE; + info.fMask = SIF_POS | SIF_PAGE; if (descr->style & LBS_DISABLENOSCROLL) info.fMask |= SIF_DISABLENOSCROLL; - if (descr->style & WS_HSCROLL) - SetScrollInfo( descr->self, SB_HORZ, &info, TRUE ); + SetScrollInfo( descr->self, SB_HORZ, &info, TRUE ); } } } @@ -1236,16 +1233,21 @@ static void LISTBOX_SetHorizontalPos( LB_DESCR *descr, INT pos ) */ static LRESULT LISTBOX_SetHorizontalExtent( LB_DESCR *descr, INT extent ) { - if (!descr->horz_extent || (descr->style & LBS_MULTICOLUMN)) + if (descr->style & LBS_MULTICOLUMN) return LB_OKAY; - if (extent <= 0) extent = 1; if (extent == descr->horz_extent) return LB_OKAY; TRACE("[%p]: new horz extent = %d\n", descr->self, extent ); descr->horz_extent = extent; + if (descr->style & WS_HSCROLL) { + SCROLLINFO info; + info.cbSize = sizeof(info); + info.nMin = 0; + info.nMax = descr->horz_extent ? descr->horz_extent - 1 : 0; + info.fMask = SIF_RANGE; + SetScrollInfo( descr->self, SB_HORZ, &info, TRUE ); + } if (descr->horz_pos > extent - descr->width) LISTBOX_SetHorizontalPos( descr, extent - descr->width ); - else - LISTBOX_UpdateScroll( descr ); return LB_OKAY; } @@ -2492,7 +2494,7 @@ static BOOL LISTBOX_Create( HWND hwnd, LPHEADCOMBO lphc ) descr->item_height = 1; descr->page_size = 1; descr->column_width = 150; - descr->horz_extent = (descr->style & WS_HSCROLL) ? 1 : 0; + descr->horz_extent = 0; descr->horz_pos = 0; descr->nb_tabs = 0; descr->tabs = NULL; diff --git a/win32ss/user/user32/misc/stubs.c b/win32ss/user/user32/misc/stubs.c index aa445c91b12..f3e4926b32d 100644 --- a/win32ss/user/user32/misc/stubs.c +++ b/win32ss/user/user32/misc/stubs.c @@ -475,15 +475,6 @@ BOOL WINAPI DdeGetQualityOfService(HWND hWnd, DWORD Reserved, PSECURITY_QUALITY_ return FALSE; } -/* - * @unimplemented - */ -BOOL WINAPI SetProcessDPIAware(VOID) -{ - UNIMPLEMENTED; - return TRUE; -} - /* * @unimplemented */ diff --git a/win32ss/user/user32/user32.spec b/win32ss/user/user32/user32.spec index 80f266cc604..c021d69d394 100644 --- a/win32ss/user/user32/user32.spec +++ b/win32ss/user/user32/user32.spec @@ -427,16 +427,17 @@ @ stdcall IsHungAppWindow(long) @ stdcall IsIconic(long) @ stdcall IsMenu(long) +@ stdcall -stub IsProcess16Bit() @ stdcall IsRectEmpty(ptr) -@ stdcall IsServerSideWindow(long) @ stdcall IsSETEnabled() +@ stdcall IsServerSideWindow(long) @ stdcall IsWinEventHookInstalled(long) @ stdcall IsWindow(long) @ stdcall IsWindowEnabled(long) @ stdcall IsWindowInDestroy(long) @ stdcall IsWindowUnicode(long) @ stdcall IsWindowVisible(long) -# @ stub IsWow64Message +@ stdcall -stub IsWow64Message() @ stdcall IsZoomed(long) @ stdcall KillSystemTimer(long long) @ stdcall KillTimer(long long) NtUserKillTimer @@ -731,7 +732,6 @@ @ stdcall WinHelpW(long wstr long long) @ stdcall WindowFromDC(long) @ stdcall WindowFromPoint(double) -@ stdcall WindowFromPhysicalPoint(double) NtUserWindowFromPhysicalPoint @ stdcall keybd_event(long long long long) @ stdcall mouse_event(long long long long long) @ varargs wsprintfA(str str) @@ -739,9 +739,6 @@ @ stdcall wvsprintfA(ptr str ptr) @ stdcall wvsprintfW(ptr wstr ptr) -; Functions exported by Win Vista -@ stdcall SetProcessDPIAware() - ; Unknown and undocumented functions ; @ stdcall CalcChildScroll(long long) ; @ stdcall CharNextExW(long wstr long) diff --git a/win32ss/user/user32/windows/clipboard.c b/win32ss/user/user32/windows/clipboard.c index fe321a8f5ee..6e024270320 100644 --- a/win32ss/user/user32/windows/clipboard.c +++ b/win32ss/user/user32/windows/clipboard.c @@ -152,7 +152,7 @@ RegisterClipboardFormatW(LPCWSTR lpszFormat) return ret; } -PVOID static WINAPI +static PVOID WINAPI IntSynthesizeMultiByte(PVOID pwStr, DWORD cbStr, BOOL bOem) { HANDLE hGlobal; @@ -173,7 +173,7 @@ IntSynthesizeMultiByte(PVOID pwStr, DWORD cbStr, BOOL bOem) return pGlobal; } -PVOID static WINAPI +static PVOID WINAPI IntSynthesizeWideChar(PVOID pwStr, DWORD cbStr, BOOL bOem) { HANDLE hGlobal; diff --git a/win32ss/user/user32/windows/menu.c b/win32ss/user/user32/windows/menu.c index d3eeae860bc..7470a3c8f9f 100644 --- a/win32ss/user/user32/windows/menu.c +++ b/win32ss/user/user32/windows/menu.c @@ -14,6 +14,7 @@ #include LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active); +BOOL WINAPI GdiValidateHandle(HGDIOBJ hobj); WINE_DEFAULT_DEBUG_CHANNEL(menu); @@ -44,15 +45,30 @@ WINE_DEFAULT_DEBUG_CHANNEL(menu); #define MENU_ITEM_TYPE(flags) ((flags) & MENU_TYPE_MASK) +#define MNS_STYLE_MASK (MNS_NOCHECK|MNS_MODELESS|MNS_DRAGDROP|MNS_AUTODISMISS|MNS_NOTIFYBYPOS|MNS_CHECKORBMP) + +#define MENUITEMINFO_TYPE_MASK \ + (MFT_STRING | MFT_BITMAP | MFT_OWNERDRAW | MFT_SEPARATOR | \ + MFT_MENUBARBREAK | MFT_MENUBREAK | MFT_RADIOCHECK | \ + MFT_RIGHTORDER | MFT_RIGHTJUSTIFY /* same as MF_HELP */ ) + +#define TYPE_MASK (MENUITEMINFO_TYPE_MASK | MF_POPUP | MF_SYSMENU) + +#define STATE_MASK (~TYPE_MASK) + +#define MENUITEMINFO_STATE_MASK (STATE_MASK & ~(MF_BYPOSITION | MF_MOUSESELECT)) + +#define MII_STATE_MASK (MFS_GRAYED|MFS_CHECKED|MFS_HILITE|MFS_DEFAULT) + /* macro to test that flags do not indicate bitmap, ownerdraw or separator */ #define IS_STRING_ITEM(flags) (MF_STRING == MENU_ITEM_TYPE(flags)) #define IS_MAGIC_BITMAP(id) ((id) && ((INT_PTR)(id) < 12) && ((INT_PTR)(id) >= -1)) #define IS_SYSTEM_MENU(MenuInfo) \ - (0 == ((MenuInfo)->Flags & MNF_POPUP) && 0 != ((MenuInfo)->Flags & MNF_SYSDESKMN)) + (0 == ((MenuInfo)->fFlags & MNF_POPUP) && 0 != ((MenuInfo)->fFlags & MNF_SYSDESKMN)) #define IS_SYSTEM_POPUP(MenuInfo) \ - (0 != ((MenuInfo)->Flags & MNF_POPUP) && 0 != ((MenuInfo)->Flags & MNF_SYSDESKMN)) + (0 != ((MenuInfo)->fFlags & MNF_POPUP) && 0 != ((MenuInfo)->fFlags & MNF_SYSDESKMN)) #define IS_BITMAP_ITEM(flags) (MF_BITMAP == MENU_ITEM_TYPE(flags)) @@ -108,6 +124,250 @@ static HBITMAP BmpSysMenu = NULL; static SIZE MenuCharSize; + +/*********************************************************************** + * MENU_GetMenu + * + * Validate the given menu handle and returns the menu structure pointer. + */ +FORCEINLINE PMENU MENU_GetMenu(HMENU hMenu) +{ + return ValidateHandle(hMenu, TYPE_MENU); +} + +/*********************************************************************** + * MENU_FindItem + * + * Find a menu item. Return a pointer on the item, and modifies *hmenu + * in case the item was in a sub-menu. + */ +ITEM *MENU_FindItem( HMENU *hmenu, UINT *nPos, UINT wFlags ) +{ + MENU *menu; + ITEM *fallback = NULL; + UINT fallback_pos = 0; + UINT i; + PITEM pItem; + + if ((*hmenu == (HMENU)0xffff) || (!(menu = MENU_GetMenu(*hmenu)))) return NULL; + if (wFlags & MF_BYPOSITION) + { + if (*nPos >= menu->cItems) return NULL; + pItem = menu->rgItems ? DesktopPtrToUser(menu->rgItems) : NULL; + //pItem = &menu->rgItems[*nPos]; + i = 0; + while(pItem) // Do this for now. + { + if (i < (INT)menu->cItems) + { + if ( *nPos == i ) return pItem; + } + pItem = pItem->Next ? DesktopPtrToUser(pItem->Next) : NULL; + i++; + } + } + else + { + PITEM item = menu->rgItems ? DesktopPtrToUser(menu->rgItems) : NULL; + for (i = 0; item ,i < menu->cItems; i++, item = item->Next ? DesktopPtrToUser(item->Next) : NULL)//, item++) + { + if (item->spSubMenu) + { + PMENU pSubMenu = DesktopPtrToUser(item->spSubMenu); + HMENU hsubmenu = UserHMGetHandle(pSubMenu); + ITEM *subitem = MENU_FindItem( &hsubmenu, nPos, wFlags ); + if (subitem) + { + *hmenu = hsubmenu; + return subitem; + } + else if (item->wID == *nPos) + { + /* fallback to this item if nothing else found */ + fallback_pos = i; + fallback = item; + } + } + else if (item->wID == *nPos) + { + *nPos = i; + return item; + } + } + } + + if (fallback) + *nPos = fallback_pos; + + return fallback; +} + +#define MAX_GOINTOSUBMENU (0x10) +UINT FASTCALL +IntGetMenuDefaultItem(PMENU Menu, BOOL fByPos, UINT gmdiFlags, DWORD *gismc) +{ + UINT x = 0; + UINT res = -1; + UINT sres; + PITEM Item = Menu->rgItems ? DesktopPtrToUser(Menu->rgItems) : NULL; + + while(Item) + { + if (Item->fState & MFS_DEFAULT) + { + if (!(gmdiFlags & GMDI_USEDISABLED) && + (Item->fState & MFS_DISABLED) ) + break; + + res = fByPos ? x : Item->wID; + + if ((*gismc < MAX_GOINTOSUBMENU) && + (gmdiFlags & GMDI_GOINTOPOPUPS) && + Item->spSubMenu) + { + if (DesktopPtrToUser(Item->spSubMenu) == Menu) + break; + + (*gismc)++; + sres = IntGetMenuDefaultItem( DesktopPtrToUser(Item->spSubMenu), fByPos, gmdiFlags, gismc); + (*gismc)--; + + if(sres > (UINT)-1) + res = sres; + } + break; + } + Item = Item->Next ? DesktopPtrToUser(Item->Next) : NULL; + x++; + } + return res; +} + +static BOOL GetMenuItemInfo_common ( HMENU hmenu, + UINT item, + BOOL bypos, + LPMENUITEMINFOW lpmii, + BOOL unicode) +{ + ITEM *pItem = MENU_FindItem (&hmenu, &item, bypos ? MF_BYPOSITION : 0); + + //debug_print_menuitem("GetMenuItemInfo_common: ", pItem, ""); + + if (!pItem) + { + SetLastError( ERROR_MENU_ITEM_NOT_FOUND); + //SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if( lpmii->fMask & MIIM_TYPE) + { + if( lpmii->fMask & ( MIIM_STRING | MIIM_FTYPE | MIIM_BITMAP)) + { + ERR("invalid combination of fMask bits used\n"); + /* this does not happen on Win9x/ME */ + SetLastError( ERROR_INVALID_PARAMETER); + return FALSE; + } + lpmii->fType = pItem->fType & MENUITEMINFO_TYPE_MASK; + if( pItem->hbmp) lpmii->fType |= MFT_BITMAP; + lpmii->hbmpItem = pItem->hbmp; /* not on Win9x/ME */ + if( lpmii->fType & MFT_BITMAP) + { + lpmii->dwTypeData = (LPWSTR) pItem->hbmp; + lpmii->cch = 0; + } + else if( lpmii->fType & (MFT_OWNERDRAW | MFT_SEPARATOR)) + { + /* this does not happen on Win9x/ME */ + lpmii->dwTypeData = 0; + lpmii->cch = 0; + } + } + + /* copy the text string */ + if ((lpmii->fMask & (MIIM_TYPE|MIIM_STRING))) + { + if( !pItem->Xlpstr ) + { // Very strange this fixes a wine test with a crash. + if(lpmii->dwTypeData && lpmii->cch && !(GdiValidateHandle((HGDIOBJ)lpmii->dwTypeData)) ) + { + lpmii->cch = 0; + if( unicode) + *((WCHAR *)lpmii->dwTypeData) = 0; + else + *((CHAR *)lpmii->dwTypeData) = 0; + } + } + else + { + int len; + LPWSTR text = DesktopPtrToUser(pItem->Xlpstr); + if (unicode) + { + len = strlenW(text); + if(lpmii->dwTypeData && lpmii->cch) + lstrcpynW(lpmii->dwTypeData, text, lpmii->cch); + } + else + { + len = WideCharToMultiByte( CP_ACP, 0, text, -1, NULL, 0, NULL, NULL ) - 1; + if(lpmii->dwTypeData && lpmii->cch) + if (!WideCharToMultiByte( CP_ACP, 0, text, -1, + (LPSTR)lpmii->dwTypeData, lpmii->cch, NULL, NULL )) + ((LPSTR)lpmii->dwTypeData)[lpmii->cch - 1] = 0; + } + /* if we've copied a substring we return its length */ + if(lpmii->dwTypeData && lpmii->cch) + if (lpmii->cch <= len + 1) + lpmii->cch--; + else + lpmii->cch = len; + else + { + /* return length of string */ + /* not on Win9x/ME if fType & MFT_BITMAP */ + lpmii->cch = len; + } + } + } + + if (lpmii->fMask & MIIM_FTYPE) + lpmii->fType = pItem->fType & MENUITEMINFO_TYPE_MASK; + + if (lpmii->fMask & MIIM_BITMAP) + lpmii->hbmpItem = pItem->hbmp; + + if (lpmii->fMask & MIIM_STATE) + lpmii->fState = pItem->fState & MII_STATE_MASK; //MENUITEMINFO_STATE_MASK; + + if (lpmii->fMask & MIIM_ID) + lpmii->wID = pItem->wID; + + if (lpmii->fMask & MIIM_SUBMENU && pItem->spSubMenu ) + { + PMENU pSubMenu = DesktopPtrToUser(pItem->spSubMenu); + HMENU hSubMenu = UserHMGetHandle(pSubMenu); + lpmii->hSubMenu = hSubMenu; + } + else + { + /* hSubMenu is always cleared + * (not on Win9x/ME ) */ + lpmii->hSubMenu = 0; + } + + if (lpmii->fMask & MIIM_CHECKMARKS) + { + lpmii->hbmpChecked = pItem->hbmpChecked; + lpmii->hbmpUnchecked = pItem->hbmpUnchecked; + } + if (lpmii->fMask & MIIM_DATA) + lpmii->dwItemData = pItem->dwItemData; + + return TRUE; +} + /*********************************************************************** * MenuGetRosMenuInfo * @@ -116,10 +376,31 @@ static SIZE MenuCharSize; static BOOL FASTCALL MenuGetRosMenuInfo(PROSMENUINFO MenuInfo, HMENU Menu) { - MenuInfo->cbSize = sizeof(ROSMENUINFO); - MenuInfo->fMask = MIM_BACKGROUND | MIM_HELPID | MIM_MAXHEIGHT | MIM_MENUDATA | MIM_STYLE; + PMENU pMenu; + if (!(pMenu = ValidateHandle(Menu, TYPE_MENU))) return FALSE; - return NtUserMenuInfo(Menu, MenuInfo, FALSE); + MenuInfo->hbrBack = pMenu->hbrBack; + MenuInfo->dwContextHelpID = pMenu->dwContextHelpId; + MenuInfo->cyMax = pMenu->cyMax; + MenuInfo->dwMenuData = pMenu->dwMenuData; + MenuInfo->dwStyle = pMenu->fFlags & MNS_STYLE_MASK; + + MenuInfo->cItems = pMenu->cItems; + + MenuInfo->iItem = pMenu->iItem; + MenuInfo->cxMenu = pMenu->cxMenu; + MenuInfo->cyMenu = pMenu->cyMenu; + MenuInfo->spwndNotify = pMenu->spwndNotify; + MenuInfo->cxTextAlign = pMenu->cxTextAlign; + MenuInfo->iTop = pMenu->iMaxTop; + MenuInfo->iMaxTop = pMenu->iMaxTop; + MenuInfo->dwArrowsOn = pMenu->dwArrowsOn; + + MenuInfo->fFlags = pMenu->fFlags; + MenuInfo->Self = pMenu->head.h; + MenuInfo->TimeToHide = pMenu->TimeToHide; + MenuInfo->Wnd = pMenu->hWnd; + return TRUE; } /*********************************************************************** @@ -133,7 +414,7 @@ MenuSetRosMenuInfo(PROSMENUINFO MenuInfo) MenuInfo->cbSize = sizeof(ROSMENUINFO); MenuInfo->fMask = MIM_BACKGROUND | MIM_HELPID | MIM_MAXHEIGHT | MIM_MENUDATA | MIM_STYLE; - return NtUserMenuInfo(MenuInfo->Self, MenuInfo, TRUE); + return NtUserThunkedMenuInfo(MenuInfo->Self, (LPCMENUINFO)MenuInfo); } /*********************************************************************** @@ -156,41 +437,68 @@ MenuInitRosMenuItemInfo(PROSMENUITEMINFO ItemInfo) static BOOL FASTCALL MenuGetRosMenuItemInfo(HMENU Menu, UINT Index, PROSMENUITEMINFO ItemInfo) { + PITEM pItem; UINT Save_Mask = ItemInfo->fMask; /* Save the org mask bits. */ if (ItemInfo->dwTypeData != NULL) - { + { HeapFree(GetProcessHeap(), 0, ItemInfo->dwTypeData); - } + } - - ItemInfo->fMask = MIIM_BITMAP | MIIM_CHECKMARKS | MIIM_DATA | MIIM_FTYPE - | MIIM_ID | MIIM_STATE | MIIM_STRING | MIIM_SUBMENU | MIIM_TYPE; ItemInfo->dwTypeData = NULL; - if (! NtUserMenuItemInfo(Menu, Index, TRUE, ItemInfo, FALSE)) - { + if (!(pItem = MENU_FindItem(&Menu, &Index, MF_BYPOSITION))) + { ItemInfo->fType = 0; return FALSE; - } + } + + ItemInfo->fType = pItem->fType; + ItemInfo->hbmpItem = pItem->hbmp; + ItemInfo->hbmpChecked = pItem->hbmpChecked; + ItemInfo->hbmpUnchecked = pItem->hbmpUnchecked; + ItemInfo->dwItemData = pItem->dwItemData; + ItemInfo->wID = pItem->wID; + ItemInfo->fState = pItem->fState; + + if (pItem->spSubMenu) + { + PMENU pSubMenu = DesktopPtrToUser(pItem->spSubMenu); + HMENU hSubMenu = UserHMGetHandle(pSubMenu); + ItemInfo->hSubMenu = hSubMenu; + } + else + ItemInfo->hSubMenu = NULL; if (MENU_ITEM_TYPE(ItemInfo->fType) == MF_STRING) - { - ItemInfo->cch++; - ItemInfo->dwTypeData = HeapAlloc(GetProcessHeap(), 0, - ItemInfo->cch * sizeof(WCHAR)); - if (NULL == ItemInfo->dwTypeData) + { + LPWSTR lpstr = pItem->lpstr.Buffer ? DesktopPtrToUser(pItem->lpstr.Buffer) : NULL; + if (lpstr) + { + ItemInfo->cch = pItem->lpstr.Length / sizeof(WCHAR); + ItemInfo->cch++; + ItemInfo->dwTypeData = HeapAlloc(GetProcessHeap(), 0, ItemInfo->cch * sizeof(WCHAR)); + if (ItemInfo->dwTypeData == NULL) { - return FALSE; + return FALSE; } + RtlCopyMemory(ItemInfo->dwTypeData, lpstr, min(ItemInfo->cch * sizeof(WCHAR), pItem->lpstr.MaximumLength)); + } + else + { + ItemInfo->cch = 0; + } + } + + ItemInfo->Rect.left = pItem->xItem; + ItemInfo->Rect.top = pItem->yItem; + ItemInfo->Rect.right = pItem->cxItem; // Do this for now...... + ItemInfo->Rect.bottom = pItem->cyItem; + ItemInfo->dxTab = pItem->dxTab; + ItemInfo->lpstr = pItem->lpstr.Buffer; + ItemInfo->maxBmpSize.cx = pItem->cxBmp; + ItemInfo->maxBmpSize.cy = pItem->cyBmp; - if (! NtUserMenuItemInfo(Menu, Index, TRUE, ItemInfo, FALSE)) - { - ItemInfo->fType = 0; - return FALSE; - } - ItemInfo->dwTypeData[ItemInfo->cch - 1] = UNICODE_NULL; - } ItemInfo->fMask = Save_Mask; return TRUE; } @@ -210,8 +518,7 @@ MenuSetRosMenuItemInfo(HMENU Menu, UINT Index, PROSMENUITEMINFO ItemInfo) { ItemInfo->cch = strlenW(ItemInfo->dwTypeData); } - Ret = NtUserMenuItemInfo(Menu, Index, TRUE, ItemInfo, TRUE); - + Ret = NtUserThunkedMenuItemInfo(Menu, Index, TRUE, FALSE, (LPMENUITEMINFOW)ItemInfo, NULL); return Ret; } @@ -224,10 +531,105 @@ static VOID FASTCALL MenuCleanupRosMenuItemInfo(PROSMENUITEMINFO ItemInfo) { if (ItemInfo->dwTypeData != NULL) - { + { HeapFree(GetProcessHeap(), 0, ItemInfo->dwTypeData); ItemInfo->dwTypeData = NULL; - } + } +} + +DWORD FASTCALL +IntBuildMenuItemList(PMENU MenuObject, PVOID Buffer, ULONG nMax) +{ + DWORD res = 0; + ROSMENUITEMINFO mii; + PVOID Buf; + PITEM CurItem = MenuObject->rgItems ? DesktopPtrToUser(MenuObject->rgItems) : NULL; + PWCHAR StrOut; + WCHAR NulByte; + + if (0 != nMax) + { + if (nMax < MenuObject->cItems * sizeof(ROSMENUITEMINFO)) + { + return 0; + } + StrOut = (PWCHAR)((char *) Buffer + MenuObject->cItems * sizeof(ROSMENUITEMINFO)); + nMax -= MenuObject->cItems * sizeof(ROSMENUITEMINFO); + Buf = Buffer; + mii.cbSize = sizeof(ROSMENUITEMINFO); + mii.fMask = 0; + NulByte = L'\0'; + + while (NULL != CurItem) + { + mii.cch = CurItem->lpstr.Length / sizeof(WCHAR); + mii.dwItemData = CurItem->dwItemData; + if (0 != CurItem->lpstr.Length) + { + mii.dwTypeData = StrOut; + } + else + { + mii.dwTypeData = NULL; + } + mii.fState = CurItem->fState; + mii.fType = CurItem->fType; + mii.wID = CurItem->wID; + mii.hbmpChecked = CurItem->hbmpChecked; + mii.hbmpItem = CurItem->hbmp; + mii.hbmpUnchecked = CurItem->hbmpUnchecked; + if (CurItem->spSubMenu) + { + PMENU pSubMenu = DesktopPtrToUser(CurItem->spSubMenu); + HMENU hSubMenu = UserHMGetHandle(pSubMenu); + mii.hSubMenu = hSubMenu; + } + else + mii.hSubMenu = NULL; + mii.Rect.left = CurItem->xItem; + mii.Rect.top = CurItem->yItem; + mii.Rect.right = CurItem->cxItem; // Do this for now...... + mii.Rect.bottom = CurItem->cyItem; + mii.dxTab = CurItem->dxTab; + mii.lpstr = CurItem->lpstr.Buffer; // Can be read from user side! + //mii.maxBmpSize.cx = CurItem->cxBmp; + //mii.maxBmpSize.cy = CurItem->cyBmp; + + RtlCopyMemory(Buf, &mii, sizeof(ROSMENUITEMINFO)); + Buf = (PVOID)((ULONG_PTR)Buf + sizeof(ROSMENUITEMINFO)); + + if (0 != CurItem->lpstr.Length && (nMax >= CurItem->lpstr.Length + sizeof(WCHAR))) + { + LPWSTR lpstr = CurItem->lpstr.Buffer ? DesktopPtrToUser(CurItem->lpstr.Buffer) : NULL; + if (lpstr) + { + /* Copy string */ + RtlCopyMemory(StrOut, lpstr, CurItem->lpstr.Length); + + StrOut += CurItem->lpstr.Length / sizeof(WCHAR); + RtlCopyMemory(StrOut, &NulByte, sizeof(WCHAR)); + StrOut++; + nMax -= CurItem->lpstr.Length + sizeof(WCHAR); + } + } + else if (0 != CurItem->lpstr.Length) + { + break; + } + + CurItem = CurItem->Next ? DesktopPtrToUser(CurItem->Next) : NULL; + res++; + } + } + else + { + while (NULL != CurItem) + { + res += sizeof(ROSMENUITEMINFO) + CurItem->lpstr.Length + sizeof(WCHAR); + CurItem = CurItem->Next ? DesktopPtrToUser(CurItem->Next) : NULL; + } + } + return res; } /*********************************************************************** @@ -239,19 +641,22 @@ static INT FASTCALL MenuGetAllRosMenuItemInfo(HMENU Menu, PROSMENUITEMINFO *ItemInfo) { DWORD BufSize; + PMENU pMenu; - BufSize = NtUserBuildMenuItemList(Menu, (VOID *) 1, 0, 0); + if (!(pMenu = ValidateHandle(Menu, TYPE_MENU))) return -1; + + BufSize = IntBuildMenuItemList(pMenu, (PVOID)1, 0); if (BufSize == (DWORD) -1 || BufSize == 0) - { + { return -1; - } + } *ItemInfo = HeapAlloc(GetProcessHeap(), 0, BufSize); if (NULL == *ItemInfo) - { + { return -1; - } + } - return NtUserBuildMenuItemList(Menu, *ItemInfo, BufSize, 0); + return IntBuildMenuItemList(pMenu, (PVOID)*ItemInfo, BufSize); } /*********************************************************************** @@ -319,14 +724,14 @@ static UINT MenuGetStartOfNextColumn( PROSMENUITEMINFO MenuItems; UINT i; - i = MenuInfo->FocusedItem; + i = MenuInfo->iItem; if ( i == NO_SELECTED_ITEM ) return i; if (MenuGetAllRosMenuItemInfo(MenuInfo->Self, &MenuItems) <= 0) return NO_SELECTED_ITEM; - for (i++ ; i < MenuInfo->MenuItemCount; i++) + for (i++ ; i < MenuInfo->cItems; i++) if (0 != (MenuItems[i].fType & (MF_MENUBREAK | MF_MENUBARBREAK))) return i; @@ -346,14 +751,14 @@ static UINT FASTCALL MenuGetStartOfPrevColumn( PROSMENUITEMINFO MenuItems; UINT i; - if (!MenuInfo->FocusedItem || MenuInfo->FocusedItem == NO_SELECTED_ITEM) + if (!MenuInfo->iItem || MenuInfo->iItem == NO_SELECTED_ITEM) return NO_SELECTED_ITEM; if (MenuGetAllRosMenuItemInfo(MenuInfo->Self, &MenuItems) <= 0) return NO_SELECTED_ITEM; /* Find the start of the column */ - for (i = MenuInfo->FocusedItem; + for (i = MenuInfo->iItem; 0 != i && 0 == (MenuItems[i].fType & (MF_MENUBREAK | MF_MENUBARBREAK)); --i) { @@ -376,47 +781,6 @@ static UINT FASTCALL MenuGetStartOfPrevColumn( return i; } -/*********************************************************************** - * MenuFindSubMenu - * - * Find a Sub menu. Return the position of the submenu, and modifies - * *hmenu in case it is found in another sub-menu. - * If the submenu cannot be found, NO_SELECTED_ITEM is returned. - */ -static UINT FASTCALL MenuFindSubMenu(HMENU *hmenu, HMENU hSubTarget ) -{ - ROSMENUINFO menu; - UINT i; - ROSMENUITEMINFO item; - if (((*hmenu)==(HMENU)0xffff) || - (!MenuGetRosMenuInfo(&menu, *hmenu))) - return NO_SELECTED_ITEM; - - MenuInitRosMenuItemInfo(&item); - for (i = 0; i < menu.MenuItemCount; i++) { - if (! MenuGetRosMenuItemInfo(menu.Self, i, &item)) - { - MenuCleanupRosMenuItemInfo(&item); - return NO_SELECTED_ITEM; - } - if (!(item.hSubMenu)) continue; - if (item.hSubMenu == hSubTarget) { - MenuCleanupRosMenuItemInfo(&item); - return i; - } - else { - HMENU hsubmenu = item.hSubMenu; - UINT pos = MenuFindSubMenu(&hsubmenu, hSubTarget ); - if (pos != NO_SELECTED_ITEM) { - *hmenu = hsubmenu; - return pos; - } - } - } - MenuCleanupRosMenuItemInfo(&item); - return NO_SELECTED_ITEM; -} - /*********************************************************************** * MenuLoadBitmaps * @@ -432,6 +796,126 @@ MenuLoadBitmaps(VOID) BmpSysMenu = LoadBitmapW(0, MAKEINTRESOURCEW(OBM_CLOSE)); } } +/////////// Make gpsi OBMI via callback ////////////// +/*********************************************************************** + * get_arrow_bitmap + */ +HBITMAP get_arrow_bitmap(void) +{ + static HBITMAP arrow_bitmap; + + if (!arrow_bitmap) arrow_bitmap = LoadBitmapW(0, MAKEINTRESOURCEW(OBM_MNARROW)); + return arrow_bitmap; +} + +/*********************************************************************** + * get_down_arrow_bitmap DFCS_MENUARROWDOWN + */ +HBITMAP get_down_arrow_bitmap(void) +{ + static HBITMAP arrow_bitmap; + + if (!arrow_bitmap) arrow_bitmap = LoadBitmapW(0, MAKEINTRESOURCEW(OBM_DNARROW)); + return arrow_bitmap; +} + +/*********************************************************************** + * get_down_arrow_inactive_bitmap DFCS_MENUARROWDOWN | DFCS_INACTIVE + */ +HBITMAP get_down_arrow_inactive_bitmap(void) +{ + static HBITMAP arrow_bitmap; + + if (!arrow_bitmap) arrow_bitmap = LoadBitmapW(0, MAKEINTRESOURCEW(OBM_DNARROWI)); + return arrow_bitmap; +} + +/*********************************************************************** + * get_up_arrow_bitmap DFCS_MENUARROWUP + */ +HBITMAP get_up_arrow_bitmap(void) +{ + static HBITMAP arrow_bitmap; + + if (!arrow_bitmap) arrow_bitmap = LoadBitmapW(0, MAKEINTRESOURCEW(OBM_UPARROW)); + return arrow_bitmap; +} + +/*********************************************************************** + * get_up_arrow_inactive_bitmap DFCS_MENUARROWUP | DFCS_INACTIVE + */ +static HBITMAP get_up_arrow_inactive_bitmap(void) +{ + static HBITMAP arrow_bitmap; + + if (!arrow_bitmap) arrow_bitmap = LoadBitmapW(0, MAKEINTRESOURCEW(OBM_UPARROWI)); + return arrow_bitmap; +} +//////////////// +/*********************************************************************** + * MenuFindSubMenu + * + * Find a Sub menu. Return the position of the submenu, and modifies + * *hmenu in case it is found in another sub-menu. + * If the submenu cannot be found, NO_SELECTED_ITEM is returned. + */ +static UINT FASTCALL MenuFindSubMenu(HMENU *hmenu, HMENU hSubTarget ) +{ + PMENU menu, pSubMenu; + HMENU hSubMenu; + UINT i; + PITEM item; + + if (((*hmenu)==(HMENU)0xffff) ||(!(menu = MENU_GetMenu(*hmenu)))) + return NO_SELECTED_ITEM; + + item = menu->rgItems ? DesktopPtrToUser(menu->rgItems) : NULL; + for (i = 0; i < menu->cItems; i++, item = item->Next ? DesktopPtrToUser(item->Next) : NULL)//item++) + { + if (!item->spSubMenu) + continue; + else + { + pSubMenu = DesktopPtrToUser(item->spSubMenu); + hSubMenu = UserHMGetHandle(pSubMenu); + if (hSubMenu == hSubTarget) + { + return i; + } + else + { + HMENU hsubmenu = hSubMenu; + UINT pos = MenuFindSubMenu( &hsubmenu, hSubTarget ); + if (pos != NO_SELECTED_ITEM) + { + *hmenu = hsubmenu; + return pos; + } + } + } + } + return NO_SELECTED_ITEM; +} + +/*********************************************************************** + * MENU_AdjustMenuItemRect + * + * Adjust menu item rectangle according to scrolling state. + */ +static void +MENU_AdjustMenuItemRect(PROSMENUINFO menu, LPRECT rect) +{ + if (menu->dwArrowsOn) + { + UINT arrow_bitmap_height; + BITMAP bmp; + + GetObjectW(get_up_arrow_bitmap(), sizeof(bmp), &bmp); + arrow_bitmap_height = bmp.bmHeight; + rect->top += arrow_bitmap_height - menu->iTop; + rect->bottom += arrow_bitmap_height - menu->iTop; + } +} /*********************************************************************** * MenuDrawPopupGlyph @@ -535,7 +1019,7 @@ static UINT FASTCALL MenuFindItemByKey(HWND WndOwner, PROSMENUINFO MenuInfo, if ( !ForceMenuChar ) { ItemInfo = Items; - for (i = 0; i < MenuInfo->MenuItemCount; i++, ItemInfo++) + for (i = 0; i < MenuInfo->cItems; i++, ItemInfo++) { if ((ItemInfo->lpstr) && NULL != ItemInfo->dwTypeData) { @@ -550,8 +1034,8 @@ static UINT FASTCALL MenuFindItemByKey(HWND WndOwner, PROSMENUINFO MenuInfo, } } - Flags |= MenuInfo->Flags & MNF_POPUP ? MF_POPUP : 0; - Flags |= MenuInfo->Flags & MNF_SYSDESKMN ? MF_SYSMENU : 0; + Flags |= MenuInfo->fFlags & MNF_POPUP ? MF_POPUP : 0; + Flags |= MenuInfo->fFlags & MNF_SYSDESKMN ? MF_SYSMENU : 0; MenuChar = SendMessageW(WndOwner, WM_MENUCHAR, MAKEWPARAM(Key, Flags), (LPARAM) MenuInfo->Self); @@ -631,7 +1115,7 @@ static void FASTCALL MenuGetBitmapItemSize(PROSMENUITEMINFO lpitem, SIZE *size, * Draw a bitmap item. */ static void FASTCALL MenuDrawBitmapItem(HDC hdc, PROSMENUITEMINFO lpitem, const RECT *rect, - HMENU hmenu, HWND WndOwner, UINT odaction, BOOL MenuBar) + PROSMENUINFO MenuInfo, HWND WndOwner, UINT odaction, BOOL MenuBar) { BITMAP bm; DWORD rop; @@ -699,7 +1183,9 @@ static void FASTCALL MenuDrawBitmapItem(HDC hdc, PROSMENUITEMINFO lpitem, const drawItem.itemState |= (lpitem->fState & MF_DISABLED)?ODS_DISABLED:0; drawItem.itemState |= (lpitem->fState & MF_GRAYED)?ODS_GRAYED|ODS_DISABLED:0; drawItem.itemState |= (lpitem->fState & MF_HILITE)?ODS_SELECTED:0; - drawItem.hwndItem = (HWND)hmenu; + //drawItem.itemState |= (!(MenuInfo->fFlags & MNF_UNDERLINE))?ODS_NOACCEL:0; + //drawItem.itemState |= (MenuInfo->fFlags & MNF_INACTIVE)?ODS_INACTIVE:0; + drawItem.hwndItem = (HWND)MenuInfo->Self; drawItem.hDC = hdc; drawItem.rcItem = *rect; drawItem.itemData = lpitem->dwItemData; @@ -750,14 +1236,19 @@ static void FASTCALL MenuDrawBitmapItem(HDC hdc, PROSMENUITEMINFO lpitem, const * Calculate the size of the menu item and store it in lpitem->rect. */ static void FASTCALL MenuCalcItemSize( HDC hdc, PROSMENUITEMINFO lpitem, PROSMENUINFO MenuInfo, HWND hwndOwner, - INT orgX, INT orgY, BOOL menuBar) + INT orgX, INT orgY, BOOL menuBar, BOOL textandbmp) { WCHAR *p; UINT check_bitmap_width = GetSystemMetrics( SM_CXMENUCHECK ); + UINT arrow_bitmap_width; + BITMAP bm; INT itemheight = 0; TRACE("dc=%x owner=%x (%d,%d)\n", hdc, hwndOwner, orgX, orgY); + GetObjectW( get_arrow_bitmap(), sizeof(bm), &bm ); + arrow_bitmap_width = bm.bmWidth; + MenuCharSize.cx = GdiGetCharDimensions( hdc, NULL, &MenuCharSize.cy ); SetRect( &lpitem->Rect, orgX, orgY, orgX, orgY ); @@ -776,24 +1267,26 @@ static void FASTCALL MenuCalcItemSize( HDC hdc, PROSMENUITEMINFO lpitem, PROSMEN * width of a menufont character to the width of an owner-drawn menu. */ lpitem->Rect.right += mis.itemWidth + 2 * MenuCharSize.cx; - if (menuBar) { /* under at least win95 you seem to be given a standard height for the menu and the height value is ignored */ lpitem->Rect.bottom += GetSystemMetrics(SM_CYMENUSIZE); } else lpitem->Rect.bottom += mis.itemHeight; - + // Or this, + //Item->cxBmp = mis.itemWidth; + //Item->cyBmp = mis.itemHeight; TRACE("id=%04lx size=%dx%d\n", - lpitem->wID, mis.itemWidth, mis.itemHeight); + lpitem->wID, lpitem->Rect.right-lpitem->Rect.left, + lpitem->Rect.bottom-lpitem->Rect.top); return; } if (lpitem->fType & MF_SEPARATOR) { - lpitem->Rect.bottom += SEPARATOR_HEIGHT; + lpitem->Rect.bottom += GetSystemMetrics( SM_CYMENUSIZE)/2;//SEPARATOR_HEIGHT; if( !menuBar) - lpitem->Rect.right += check_bitmap_width + MenuCharSize.cx; + lpitem->Rect.right += arrow_bitmap_width/*check_bitmap_width*/ + MenuCharSize.cx; return; } @@ -807,21 +1300,17 @@ static void FASTCALL MenuCalcItemSize( HDC hdc, PROSMENUITEMINFO lpitem, PROSMEN MenuGetBitmapItemSize(lpitem, &size, hwndOwner ); /* Keep the size of the bitmap in callback mode to be able * to draw it correctly */ - lpitem->Rect.right = lpitem->Rect.left + size.cx; - if (MenuInfo->maxBmpSize.cx < abs(size.cx) + MENU_ITEM_HBMP_SPACE || - MenuInfo->maxBmpSize.cy < abs(size.cy)) - { - MenuInfo->maxBmpSize.cx = abs(size.cx) + MENU_ITEM_HBMP_SPACE; - MenuInfo->maxBmpSize.cy = abs(size.cy); - } + lpitem->maxBmpSize = size; + MenuInfo->cxTextAlign = max(MenuInfo->cxTextAlign, size.cx); MenuSetRosMenuInfo(MenuInfo); + lpitem->Rect.right += size.cx + 2; itemheight = size.cy + 2; if( !(MenuInfo->dwStyle & MNS_NOCHECK)) lpitem->Rect.right += 2 * check_bitmap_width; lpitem->Rect.right += 4 + MenuCharSize.cx; lpitem->dxTab = lpitem->Rect.right; - lpitem->Rect.right += check_bitmap_width; + lpitem->Rect.right += arrow_bitmap_width;//check_bitmap_width; } else /* hbmpItem & MenuBar */ { MenuGetBitmapItemSize(lpitem, &size, hwndOwner ); lpitem->Rect.right += size.cx; @@ -894,6 +1383,17 @@ static void FASTCALL MenuCalcItemSize( HDC hdc, PROSMENUITEMINFO lpitem, PROSMEN TRACE("(%ld,%ld)-(%ld,%ld)\n", lpitem->Rect.left, lpitem->Rect.top, lpitem->Rect.right, lpitem->Rect.bottom); } +/*********************************************************************** + * MENU_GetMaxPopupHeight + */ +static UINT +MENU_GetMaxPopupHeight(PROSMENUINFO lppop) +{ + if (lppop->cyMax) + return lppop->cyMax; + return GetSystemMetrics(SM_CYSCREEN) - GetSystemMetrics(SM_CYBORDER); +} + /*********************************************************************** * MenuPopupMenuCalcSize * @@ -904,10 +1404,11 @@ static void FASTCALL MenuPopupMenuCalcSize(PROSMENUINFO MenuInfo, HWND WndOwner) ROSMENUITEMINFO lpitem; HDC hdc; int start, i; - int orgX, orgY, maxX, maxTab, maxTabWidth; + int orgX, orgY, maxX, maxTab, maxTabWidth, maxHeight; + BOOL textandbmp = FALSE; - MenuInfo->Width = MenuInfo->Height = 0; - if (MenuInfo->MenuItemCount == 0) + MenuInfo->cxMenu = MenuInfo->cyMenu = 0; + if (MenuInfo->cItems == 0) { MenuSetRosMenuInfo(MenuInfo); return; @@ -919,11 +1420,10 @@ static void FASTCALL MenuPopupMenuCalcSize(PROSMENUINFO MenuInfo, HWND WndOwner) start = 0; maxX = 2 + 1; - MenuInfo->maxBmpSize.cx = 0; - MenuInfo->maxBmpSize.cy = 0; + MenuInfo->cxTextAlign = 0; MenuInitRosMenuItemInfo(&lpitem); - while (start < MenuInfo->MenuItemCount) + while (start < MenuInfo->cItems) { orgX = maxX; orgY = 2; @@ -931,7 +1431,7 @@ static void FASTCALL MenuPopupMenuCalcSize(PROSMENUINFO MenuInfo, HWND WndOwner) maxTab = maxTabWidth = 0; /* Parse items until column break or end of menu */ - for (i = start; i < MenuInfo->MenuItemCount; i++) + for (i = start; i < MenuInfo->cItems; i++) { if (! MenuGetRosMenuItemInfo(MenuInfo->Self, i, &lpitem)) { @@ -942,7 +1442,9 @@ static void FASTCALL MenuPopupMenuCalcSize(PROSMENUINFO MenuInfo, HWND WndOwner) if (i != start && (lpitem.fType & (MF_MENUBREAK | MF_MENUBARBREAK))) break; - MenuCalcItemSize(hdc, &lpitem, MenuInfo, WndOwner, orgX, orgY, FALSE); + if( lpitem.lpstr && lpitem.hbmpItem) textandbmp = TRUE; + + MenuCalcItemSize(hdc, &lpitem, MenuInfo, WndOwner, orgX, orgY, FALSE, textandbmp); if (! MenuSetRosMenuItemInfo(MenuInfo->Self, i, &lpitem)) { MenuCleanupRosMenuItemInfo(&lpitem); @@ -957,7 +1459,7 @@ static void FASTCALL MenuPopupMenuCalcSize(PROSMENUINFO MenuInfo, HWND WndOwner) maxX = max(maxX, lpitem.Rect.right); orgY = lpitem.Rect.bottom; if ((lpitem.lpstr) && lpitem.dxTab ) - { + { maxTab = max( maxTab, lpitem.dxTab ); maxTabWidth = max(maxTabWidth, lpitem.Rect.right - lpitem.dxTab); } @@ -978,14 +1480,33 @@ static void FASTCALL MenuPopupMenuCalcSize(PROSMENUINFO MenuInfo, HWND WndOwner) } start++; } - MenuInfo->Height = max(MenuInfo->Height, orgY); + MenuInfo->cyMenu = max(MenuInfo->cyMenu, orgY); } - MenuInfo->Width = maxX; + MenuInfo->cxMenu = maxX; + /* if none of the items have both text and bitmap then + * the text and bitmaps are all aligned on the left. If there is at + * least one item with both text and bitmap then bitmaps are + * on the left and texts left aligned with the right hand side + * of the bitmaps */ + if( !textandbmp) MenuInfo->cxTextAlign = 0; /* space for 3d border */ - MenuInfo->Height += 2; - MenuInfo->Width += 2; + MenuInfo->cyMenu += MENU_BOTTOM_MARGIN; + MenuInfo->cxMenu += 2; + + /* Adjust popup height if it exceeds maximum */ + maxHeight = MENU_GetMaxPopupHeight(MenuInfo); + MenuInfo->iMaxTop = MenuInfo->cyMenu - MENU_TOP_MARGIN; + if (MenuInfo->cyMenu >= maxHeight) + { + MenuInfo->cyMenu = maxHeight; + MenuInfo->dwArrowsOn = 1; + } + else + { + MenuInfo->dwArrowsOn = 0; + } MenuCleanupRosMenuItemInfo(&lpitem); MenuSetRosMenuInfo(MenuInfo); @@ -1008,19 +1529,18 @@ static void FASTCALL MenuMenuBarCalcSize( HDC hdc, LPRECT lprect, int start, i, orgX, orgY, maxY, helpPos; if ((lprect == NULL) || (MenuInfo == NULL)) return; - if (MenuInfo->MenuItemCount == 0) return; + if (MenuInfo->cItems == 0) return; TRACE("left=%ld top=%ld right=%ld bottom=%ld\n", lprect->left, lprect->top, lprect->right, lprect->bottom); - MenuInfo->Width = lprect->right - lprect->left; - MenuInfo->Height = 0; + MenuInfo->cxMenu = lprect->right - lprect->left; + MenuInfo->cyMenu = 0; maxY = lprect->top + 1; start = 0; helpPos = -1; - MenuInfo->maxBmpSize.cx = 0; - MenuInfo->maxBmpSize.cy = 0; + MenuInfo->cxTextAlign = 0; MenuInitRosMenuItemInfo(&ItemInfo); - while (start < MenuInfo->MenuItemCount) + while (start < MenuInfo->cItems) { if (! MenuGetRosMenuItemInfo(MenuInfo->Self, start, &ItemInfo)) { @@ -1031,14 +1551,14 @@ static void FASTCALL MenuMenuBarCalcSize( HDC hdc, LPRECT lprect, orgY = maxY; /* Parse items until line break or end of menu */ - for (i = start; i < MenuInfo->MenuItemCount; i++) + for (i = start; i < MenuInfo->cItems; i++) { if ((helpPos == -1) && (ItemInfo.fType & MF_RIGHTJUSTIFY)) helpPos = i; if ((i != start) && (ItemInfo.fType & (MF_MENUBREAK | MF_MENUBARBREAK))) break; TRACE("calling MENU_CalcItemSize org=(%d, %d)\n", orgX, orgY); - MenuCalcItemSize(hdc, &ItemInfo, MenuInfo, hwndOwner, orgX, orgY, TRUE); + MenuCalcItemSize(hdc, &ItemInfo, MenuInfo, hwndOwner, orgX, orgY, TRUE, FALSE); if (! MenuSetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo)) { MenuCleanupRosMenuItemInfo(&ItemInfo); @@ -1052,7 +1572,7 @@ static void FASTCALL MenuMenuBarCalcSize( HDC hdc, LPRECT lprect, } maxY = max( maxY, ItemInfo.Rect.bottom ); orgX = ItemInfo.Rect.right; - if (i + 1 < MenuInfo->MenuItemCount) + if (i + 1 < MenuInfo->cItems) { if (! MenuGetRosMenuItemInfo(MenuInfo->Self, i + 1, &ItemInfo)) { @@ -1081,21 +1601,21 @@ HBMMENU_MBAR_CLOSE, MINIMIZE & RESTORE, look the same size as the menu bar! */ } lprect->bottom = maxY; - MenuInfo->Height = lprect->bottom - lprect->top; + MenuInfo->cyMenu = lprect->bottom - lprect->top; MenuSetRosMenuInfo(MenuInfo); if (helpPos != -1) { /* Flush right all items between the MF_RIGHTJUSTIFY and */ /* the last item (if several lines, only move the last line) */ - if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->MenuItemCount - 1, &ItemInfo)) + if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->cItems - 1, &ItemInfo)) { MenuCleanupRosMenuItemInfo(&ItemInfo); return; } orgY = ItemInfo.Rect.top; orgX = lprect->right; - for (i = MenuInfo->MenuItemCount - 1; helpPos <= i; i--) + for (i = MenuInfo->cItems - 1; helpPos <= i; i--) { if (i < helpPos) { @@ -1125,6 +1645,51 @@ HBMMENU_MBAR_CLOSE, MINIMIZE & RESTORE, look the same size as the menu bar! */ MenuCleanupRosMenuItemInfo(&ItemInfo); } +/*********************************************************************** + * MENU_DrawScrollArrows + * + * Draw scroll arrows. + */ +static void +MENU_DrawScrollArrows(PROSMENUINFO lppop, HDC hdc) +{ + HDC hdcMem = CreateCompatibleDC(hdc); + HBITMAP hOrigBitmap; + UINT arrow_bitmap_width, arrow_bitmap_height; + BITMAP bmp; + RECT rect; + + GetObjectW(get_down_arrow_bitmap(), sizeof(bmp), &bmp); + arrow_bitmap_width = bmp.bmWidth; + arrow_bitmap_height = bmp.bmHeight; + + + if (lppop->iTop) + hOrigBitmap = SelectObject(hdcMem, get_up_arrow_bitmap()); + else + hOrigBitmap = SelectObject(hdcMem, get_up_arrow_inactive_bitmap()); + rect.left = 0; + rect.top = 0; + rect.right = lppop->cxMenu; + rect.bottom = arrow_bitmap_height; + FillRect(hdc, &rect, GetSysColorBrush(COLOR_MENU)); + BitBlt(hdc, (lppop->cxMenu - arrow_bitmap_width) / 2, 0, + arrow_bitmap_width, arrow_bitmap_height, hdcMem, 0, 0, SRCCOPY); + rect.top = lppop->cyMenu - arrow_bitmap_height; + rect.bottom = lppop->cyMenu; + FillRect(hdc, &rect, GetSysColorBrush(COLOR_MENU)); + if (lppop->iTop < lppop->iMaxTop - (MENU_GetMaxPopupHeight(lppop) - 2 * arrow_bitmap_height)) + SelectObject(hdcMem, get_down_arrow_bitmap()); + else + SelectObject(hdcMem, get_down_arrow_inactive_bitmap()); + BitBlt(hdc, (lppop->cxMenu - arrow_bitmap_width) / 2, + lppop->cyMenu - arrow_bitmap_height, + arrow_bitmap_width, arrow_bitmap_height, hdcMem, 0, 0, SRCCOPY); + SelectObject(hdcMem, hOrigBitmap); + DeleteDC(hdcMem); +} + + /*********************************************************************** * MenuDrawMenuItem * @@ -1180,6 +1745,7 @@ static void FASTCALL MenuDrawMenuItem(HWND hWnd, PROSMENUINFO MenuInfo, HWND Wnd } rect = lpitem->Rect; + MENU_AdjustMenuItemRect(MenuInfo, &rect); if (lpitem->fType & MF_OWNERDRAW) { @@ -1199,9 +1765,13 @@ static void FASTCALL MenuDrawMenuItem(HWND hWnd, PROSMENUINFO MenuInfo, HWND Wnd dis.itemID = lpitem->wID; dis.itemData = (DWORD)lpitem->dwItemData; dis.itemState = 0; - if (lpitem->fState & MF_CHECKED) dis.itemState |= ODS_CHECKED; - if (lpitem->fState & MF_GRAYED) dis.itemState |= ODS_GRAYED | ODS_DISABLED; - if (lpitem->fState & MF_HILITE) dis.itemState |= ODS_SELECTED; + if (lpitem->fState & MF_CHECKED) dis.itemState |= ODS_CHECKED; + if (lpitem->fState & MF_DEFAULT) dis.itemState |= ODS_DEFAULT; + if (lpitem->fState & MF_DISABLED) dis.itemState |= ODS_DISABLED; + if (lpitem->fState & MF_GRAYED) dis.itemState |= ODS_GRAYED | ODS_DISABLED; + if (lpitem->fState & MF_HILITE) dis.itemState |= ODS_SELECTED; + //if (!(MenuInfo->fFlags & MNF_UNDERLINE)) dis.itemState |= ODS_NOACCEL; + //if (MenuInfo->fFlags & MNF_INACTIVE) dis.itemState |= ODS_INACTIVE; dis.itemAction = odaction; /* ODA_DRAWENTIRE | ODA_SELECT | ODA_FOCUS; */ dis.hwndItem = (HWND) MenuInfo->Self; dis.hDC = hdc; @@ -1346,8 +1916,8 @@ static void FASTCALL MenuDrawMenuItem(HWND hWnd, PROSMENUINFO MenuInfo, HWND Wnd bmpRect.left += check_bitmap_width + 2; if (!(checked && (MenuInfo->dwStyle & MNS_CHECKORBMP))) { - bmpRect.right = bmpRect.left + MenuInfo->maxBmpSize.cx; - MenuDrawBitmapItem(hdc, lpitem, &bmpRect, MenuInfo->Self, WndOwner, odaction, menuBar); + bmpRect.right = bmpRect.left + lpitem->maxBmpSize.cx; + MenuDrawBitmapItem(hdc, lpitem, &bmpRect, MenuInfo, WndOwner, odaction, menuBar); } } /* Draw the popup-menu arrow */ @@ -1365,7 +1935,7 @@ static void FASTCALL MenuDrawMenuItem(HWND hWnd, PROSMENUINFO MenuInfo, HWND Wnd } else if( lpitem->hbmpItem) { /* Draw the bitmap */ - MenuDrawBitmapItem(hdc, lpitem, &rect, MenuInfo->Self, WndOwner, odaction, menuBar); + MenuDrawBitmapItem(hdc, lpitem, &rect, MenuInfo, WndOwner, odaction, menuBar); } /* process text if present */ @@ -1374,13 +1944,14 @@ static void FASTCALL MenuDrawMenuItem(HWND hWnd, PROSMENUINFO MenuInfo, HWND Wnd register int i = 0; HFONT hfontOld = 0; - UINT uFormat = menuBar ? DT_CENTER | DT_VCENTER | DT_SINGLELINE - : DT_LEFT | DT_VCENTER | DT_SINGLELINE; + UINT uFormat = menuBar ? + DT_CENTER | DT_VCENTER | DT_SINGLELINE : + DT_LEFT | DT_VCENTER | DT_SINGLELINE; - if(MenuInfo->dwStyle & MNS_CHECKORBMP) - rect.left += max(0, MenuInfo->maxBmpSize.cx - GetSystemMetrics(SM_CXMENUCHECK)); + if((MenuInfo->dwStyle & MNS_CHECKORBMP)) + rect.left += max(0, MenuInfo->cxTextAlign - GetSystemMetrics(SM_CXMENUCHECK)); else - rect.left += MenuInfo->maxBmpSize.cx; + rect.left += MenuInfo->cxTextAlign; if ( lpitem->fState & MFS_DEFAULT ) { @@ -1482,21 +2053,26 @@ static void FASTCALL MenuDrawPopupMenu(HWND hwnd, HDC hdc, HMENU hmenu ) DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT); /* draw menu items */ - if (MenuGetRosMenuInfo(&MenuInfo, hmenu) && MenuInfo.MenuItemCount) + if (MenuGetRosMenuInfo(&MenuInfo, hmenu) && MenuInfo.cItems) { UINT u; - - MenuInitRosMenuItemInfo(&ItemInfo); + MenuInitRosMenuItemInfo(&ItemInfo); - for (u = 0; u < MenuInfo.MenuItemCount; u++) + for (u = 0; u < MenuInfo.cItems; u++) { if (MenuGetRosMenuItemInfo(MenuInfo.Self, u, &ItemInfo)) { - MenuDrawMenuItem(hwnd, &MenuInfo, MenuInfo.WndOwner, hdc, &ItemInfo, - MenuInfo.Height, FALSE, ODA_DRAWENTIRE); + HWND WndOwner = MenuInfo.spwndNotify ? MenuInfo.spwndNotify->head.h : NULL; + MenuDrawMenuItem(hwnd, &MenuInfo, WndOwner, hdc, &ItemInfo, + MenuInfo.cyMenu, FALSE, ODA_DRAWENTIRE); } } + /* draw scroll arrows */ + if (MenuInfo.dwArrowsOn) + MENU_DrawScrollArrows(&MenuInfo, hdc); + + MenuSetRosMenuInfo(&MenuInfo); MenuCleanupRosMenuItemInfo(&ItemInfo); } } else @@ -1530,15 +2106,16 @@ UINT MenuDrawMenuBar( HDC hDC, LPRECT lprect, HWND hwnd, MenuMenuBarCalcSize(hDC, lprect, &lppop, hwnd); - lprect->bottom = lprect->top + lppop.Height; + lprect->bottom = lprect->top + lppop.cyMenu; if (hfontOld) SelectObject( hDC, hfontOld); - return lppop.Height; + return lppop.cyMenu; } else return DrawMenuBarTemp(hwnd, hDC, lprect, hMenu, NULL); } + /*********************************************************************** * MenuShowPopup * @@ -1559,17 +2136,17 @@ static BOOL FASTCALL MenuShowPopup(HWND hwndOwner, HMENU hmenu, UINT id, UINT fl hwndOwner, hmenu, id, x, y, xanchor, yanchor); if (! MenuGetRosMenuInfo(&MenuInfo, hmenu)) return FALSE; - if (MenuInfo.FocusedItem != NO_SELECTED_ITEM) + if (MenuInfo.iItem != NO_SELECTED_ITEM) { MenuInitRosMenuItemInfo(&ItemInfo); - if (MenuGetRosMenuItemInfo(MenuInfo.Self, MenuInfo.FocusedItem, &ItemInfo)) + if (MenuGetRosMenuItemInfo(MenuInfo.Self, MenuInfo.iItem, &ItemInfo)) { ItemInfo.fMask |= MIIM_STATE; ItemInfo.fState &= ~(MF_HILITE|MF_MOUSESELECT); - MenuSetRosMenuItemInfo(MenuInfo.Self, MenuInfo.FocusedItem, &ItemInfo); + MenuSetRosMenuItemInfo(MenuInfo.Self, MenuInfo.iItem, &ItemInfo); } MenuCleanupRosMenuItemInfo(&ItemInfo); - MenuInfo.FocusedItem = NO_SELECTED_ITEM; + MenuInfo.iItem = NO_SELECTED_ITEM; } /* store the owner for DrawItem */ @@ -1578,15 +2155,15 @@ static BOOL FASTCALL MenuShowPopup(HWND hwndOwner, HMENU hmenu, UINT id, UINT fl SetLastError( ERROR_INVALID_WINDOW_HANDLE ); return FALSE; } - MenuInfo.WndOwner = hwndOwner; + MenuInfo.spwndNotify = ValidateHwndNoErr(hwndOwner); MenuSetRosMenuInfo(&MenuInfo); MenuPopupMenuCalcSize(&MenuInfo, hwndOwner); /* adjust popup menu pos so that it fits within the desktop */ - width = MenuInfo.Width + GetSystemMetrics(SM_CXBORDER); - height = MenuInfo.Height + GetSystemMetrics(SM_CYBORDER); + width = MenuInfo.cxMenu + GetSystemMetrics(SM_CXBORDER); + height = MenuInfo.cyMenu + GetSystemMetrics(SM_CYBORDER); /* FIXME: should use item rect */ pt.x = x; @@ -1647,6 +2224,44 @@ static BOOL FASTCALL MenuShowPopup(HWND hwndOwner, HMENU hmenu, UINT id, UINT fl return TRUE; } +/*********************************************************************** + * MENU_EnsureMenuItemVisible + */ +void +MENU_EnsureMenuItemVisible(PROSMENUINFO lppop, PROSMENUITEMINFO item, HDC hdc) +{ + if (lppop->dwArrowsOn) + { + //ITEM *item = &lppop->items[wIndex]; + UINT nMaxHeight = MENU_GetMaxPopupHeight(lppop); + UINT nOldPos = lppop->iTop; + RECT rc; + UINT arrow_bitmap_height; + BITMAP bmp; + + GetClientRect(lppop->Wnd, &rc); + + GetObjectW(get_down_arrow_bitmap(), sizeof(bmp), &bmp); + arrow_bitmap_height = bmp.bmHeight; + + rc.top += arrow_bitmap_height; + rc.bottom -= arrow_bitmap_height + MENU_BOTTOM_MARGIN; + + nMaxHeight -= GetSystemMetrics(SM_CYBORDER) + 2 * arrow_bitmap_height; + if (item->Rect.bottom > lppop->iTop + nMaxHeight) + { + lppop->iTop = item->Rect.bottom - nMaxHeight; + ScrollWindow(lppop->Wnd, 0, nOldPos - lppop->iTop, &rc, &rc); + MENU_DrawScrollArrows(lppop, hdc); + } + else if (item->Rect.top - MENU_TOP_MARGIN < lppop->iTop) + { + lppop->iTop = item->Rect.top - MENU_TOP_MARGIN; + ScrollWindow(lppop->Wnd, 0, nOldPos - lppop->iTop, &rc, &rc); + MENU_DrawScrollArrows(lppop, hdc); + } + } +} /*********************************************************************** * MenuSelectItem @@ -1660,9 +2275,9 @@ static void FASTCALL MenuSelectItem(HWND hwndOwner, PROSMENUINFO hmenu, UINT wIn TRACE("owner=%p menu=%p index=0x%04x select=0x%04x\n", hwndOwner, hmenu, wIndex, sendMenuSelect); - if (!hmenu || !hmenu->MenuItemCount || !hmenu->Wnd) return; - if (hmenu->FocusedItem == wIndex) return; - if (hmenu->Flags & MNF_POPUP) hdc = GetDC(hmenu->Wnd); + if (!hmenu || !hmenu->cItems || !hmenu->Wnd) return; + if (hmenu->iItem == wIndex) return; + if (hmenu->fFlags & MNF_POPUP) hdc = GetDC(hmenu->Wnd); else hdc = GetDCEx(hmenu->Wnd, 0, DCX_CACHE | DCX_WINDOW); if (!top_popup) { top_popup = hmenu->Wnd; @@ -1674,33 +2289,34 @@ static void FASTCALL MenuSelectItem(HWND hwndOwner, PROSMENUINFO hmenu, UINT wIn MenuInitRosMenuItemInfo(&ItemInfo); /* Clear previous highlighted item */ - if (hmenu->FocusedItem != NO_SELECTED_ITEM) + if (hmenu->iItem != NO_SELECTED_ITEM) { - if (MenuGetRosMenuItemInfo(hmenu->Self, hmenu->FocusedItem, &ItemInfo)) + if (MenuGetRosMenuItemInfo(hmenu->Self, hmenu->iItem, &ItemInfo)) { ItemInfo.fMask |= MIIM_STATE; ItemInfo.fState &= ~(MF_HILITE|MF_MOUSESELECT); - MenuSetRosMenuItemInfo(hmenu->Self, hmenu->FocusedItem, &ItemInfo); + MenuSetRosMenuItemInfo(hmenu->Self, hmenu->iItem, &ItemInfo); } + //MENU_EnsureMenuItemVisible(hmenu, &ItemInfo, hdc); MenuDrawMenuItem(hmenu->Wnd, hmenu, hwndOwner, hdc, &ItemInfo, - hmenu->Height, !(hmenu->Flags & MNF_POPUP), + hmenu->cyMenu, !(hmenu->fFlags & MNF_POPUP), ODA_SELECT); } /* Highlight new item (if any) */ - hmenu->FocusedItem = wIndex; + hmenu->iItem = wIndex; MenuSetRosMenuInfo(hmenu); - if (hmenu->FocusedItem != NO_SELECTED_ITEM) + if (hmenu->iItem != NO_SELECTED_ITEM) { - if (MenuGetRosMenuItemInfo(hmenu->Self, hmenu->FocusedItem, &ItemInfo)) + if (MenuGetRosMenuItemInfo(hmenu->Self, hmenu->iItem, &ItemInfo)) { if (!(ItemInfo.fType & MF_SEPARATOR)) { ItemInfo.fMask |= MIIM_STATE; ItemInfo.fState |= MF_HILITE; - MenuSetRosMenuItemInfo(hmenu->Self, hmenu->FocusedItem, &ItemInfo); + MenuSetRosMenuItemInfo(hmenu->Self, hmenu->iItem, &ItemInfo); MenuDrawMenuItem(hmenu->Wnd, hmenu, hwndOwner, hdc, - &ItemInfo, hmenu->Height, !(hmenu->Flags & MNF_POPUP), + &ItemInfo, hmenu->cyMenu, !(hmenu->fFlags & MNF_POPUP), ODA_SELECT); } if (sendMenuSelect) @@ -1708,7 +2324,7 @@ static void FASTCALL MenuSelectItem(HWND hwndOwner, PROSMENUINFO hmenu, UINT wIn WPARAM wParam = MAKEWPARAM( ItemInfo.hSubMenu ? wIndex : ItemInfo.wID, ItemInfo.fType | ItemInfo.fState | (ItemInfo.hSubMenu ? MF_POPUP : 0) | - (hmenu->Flags & MNF_SYSDESKMN ? MF_SYSMENU : 0 ) ); + (hmenu->fFlags & MNF_SYSDESKMN ? MF_SYSMENU : 0 ) ); SendMessageW(hwndOwner, WM_MENUSELECT, wParam, (LPARAM) hmenu->Self); } @@ -1727,7 +2343,7 @@ static void FASTCALL MenuSelectItem(HWND hwndOwner, PROSMENUINFO hmenu, UINT wIn { WPARAM wParam = MAKEWPARAM( Pos, ItemInfo.fType | ItemInfo.fState | (ItemInfo.hSubMenu ? MF_POPUP : 0) | - (TopMenuInfo.Flags & MNF_SYSDESKMN ? MF_SYSMENU : 0 ) ); + (TopMenuInfo.fFlags & MNF_SYSDESKMN ? MF_SYSMENU : 0 ) ); SendMessageW(hwndOwner, WM_MENUSELECT, wParam, (LPARAM) topmenu); } @@ -1755,7 +2371,7 @@ MenuMoveSelection(HWND WndOwner, PROSMENUINFO MenuInfo, INT Offset) TRACE("hwnd=%x menu=%x off=0x%04x\n", WndOwner, MenuInfo, Offset); /* Prevent looping */ - if (0 == MenuInfo->MenuItemCount || 0 == Offset) + if (0 == MenuInfo->cItems || 0 == Offset) return; else if (Offset < -1) Offset = -1; @@ -1764,7 +2380,7 @@ MenuMoveSelection(HWND WndOwner, PROSMENUINFO MenuInfo, INT Offset) MenuInitRosMenuItemInfo(&ItemInfo); - OrigPos = MenuInfo->FocusedItem; + OrigPos = MenuInfo->iItem; if (OrigPos == NO_SELECTED_ITEM) /* NO_SELECTED_ITEM is not -1 ! */ { OrigPos = 0; @@ -1772,7 +2388,7 @@ MenuMoveSelection(HWND WndOwner, PROSMENUINFO MenuInfo, INT Offset) } else { - i = MenuInfo->FocusedItem; + i = MenuInfo->iItem; } do @@ -1782,9 +2398,9 @@ MenuMoveSelection(HWND WndOwner, PROSMENUINFO MenuInfo, INT Offset) /* Clip and wrap around */ if (i < 0) { - i = MenuInfo->MenuItemCount - 1; + i = MenuInfo->cItems - 1; } - else if (i >= MenuInfo->MenuItemCount) + else if (i >= MenuInfo->cItems) { i = 0; } @@ -1802,13 +2418,13 @@ MenuMoveSelection(HWND WndOwner, PROSMENUINFO MenuInfo, INT Offset) MenuCleanupRosMenuItemInfo(&ItemInfo); } -// -// This breaks some test results. Should handle A2U if called! -// -LRESULT WINAPI PopupMenuWndProcA(HWND Wnd, UINT Message, WPARAM wParam, LPARAM lParam) +#if 0 +LRESULT WINAPI +PopupMenuWndProcW(HWND Wnd, UINT Message, WPARAM wParam, LPARAM lParam) { -#ifdef __REACTOS__ +#ifdef __REACTOS__ // Do this now, remove after Server side is fixed. PWND pWnd; + PPOPUPMENU pPopupMenu; pWnd = ValidateHwnd(Wnd); if (pWnd) @@ -1817,9 +2433,12 @@ LRESULT WINAPI PopupMenuWndProcA(HWND Wnd, UINT Message, WPARAM wParam, LPARAM l { if (Message != WM_NCCREATE) { - return DefWindowProcA(Wnd, Message, wParam, lParam); + return DefWindowProcW(Wnd, Message, wParam, lParam); } NtUserSetWindowFNID(Wnd, FNID_MENU); + pPopupMenu = HeapAlloc( GetProcessHeap(), 0, sizeof(POPUPMENU) ); + pPopupMenu->spwndPopupMenu = pWnd; + SetWindowLongPtrW(Wnd, 0, (LONG_PTR)pPopupMenu); } else { @@ -1828,18 +2447,19 @@ LRESULT WINAPI PopupMenuWndProcA(HWND Wnd, UINT Message, WPARAM wParam, LPARAM l ERR("Wrong window class for Menu!\n"); return 0; } + pPopupMenu = ((PMENUWND)pWnd)->ppopupmenu; } } #endif - TRACE("YES! hwnd=%x msg=0x%04x wp=0x%04lx lp=0x%08lx\n", Wnd, Message, wParam, lParam); + TRACE("hwnd=%x msg=0x%04x wp=0x%04lx lp=0x%08lx\n", Wnd, Message, wParam, lParam); switch(Message) { case WM_CREATE: { - CREATESTRUCTA *cs = (CREATESTRUCTA *) lParam; - SetWindowLongPtrA(Wnd, 0, (LONG_PTR)cs->lpCreateParams); + CREATESTRUCTW *cs = (CREATESTRUCTW *) lParam; + pPopupMenu->spmenu = ValidateHandle(cs->lpCreateParams, TYPE_MENU); return 0; } @@ -1850,16 +2470,15 @@ LRESULT WINAPI PopupMenuWndProcA(HWND Wnd, UINT Message, WPARAM wParam, LPARAM l { PAINTSTRUCT ps; BeginPaint(Wnd, &ps); - MenuDrawPopupMenu(Wnd, ps.hdc, (HMENU)GetWindowLongPtrA(Wnd, 0)); + MenuDrawPopupMenu(Wnd, ps.hdc, pPopupMenu->spmenu->head.h); EndPaint(Wnd, &ps); return 0; } case WM_PRINTCLIENT: { - MenuDrawPopupMenu( Wnd, (HDC)wParam, - (HMENU)GetWindowLongPtrW( Wnd, 0 ) ); - return 0; + MenuDrawPopupMenu( Wnd, (HDC)wParam, pPopupMenu->spmenu->head.h); + return 0; } case WM_ERASEBKGND: @@ -1874,39 +2493,51 @@ LRESULT WINAPI PopupMenuWndProcA(HWND Wnd, UINT Message, WPARAM wParam, LPARAM l } break; -#ifdef __REACTOS__ case WM_NCDESTROY: + { + HeapFree( GetProcessHeap(), 0, pPopupMenu ); + SetWindowLongPtrW(Wnd, 0, 0); NtUserSetWindowFNID(Wnd, FNID_DESTROY); break; -#endif + } case WM_SHOWWINDOW: if (0 != wParam) - { - if (0 == GetWindowLongPtrA(Wnd, 0)) - { + { + if (!pPopupMenu || !pPopupMenu->spmenu) + { OutputDebugStringA("no menu to display\n"); - } - } - else - { - SetWindowLongPtrA(Wnd, 0, 0); - } + } + } + /*else + { + pPopupMenu->spmenu = NULL; ///// WTF? + }*/ break; case MM_SETMENUHANDLE: - SetWindowLongPtrA(Wnd, 0, wParam); - break; + { + PMENU pmenu = ValidateHandle((HMENU)wParam, TYPE_MENU); + if (!pmenu) + { + ERR("Bad Menu Handle\n"); + break; + } + pPopupMenu->spmenu = pmenu; + break; + } case MM_GETMENUHANDLE: - case MN_GETHMENU: - return GetWindowLongPtrA(Wnd, 0); + case MN_GETHMENU: + return (LRESULT)(pPopupMenu ? (pPopupMenu->spmenu ? pPopupMenu->spmenu->head.h : NULL) : NULL); default: - return DefWindowProcA(Wnd, Message, wParam, lParam); + return DefWindowProcW(Wnd, Message, wParam, lParam); } + return 0; } +#endif LRESULT WINAPI PopupMenuWndProcW(HWND Wnd, UINT Message, WPARAM wParam, LPARAM lParam) @@ -2007,6 +2638,42 @@ PopupMenuWndProcW(HWND Wnd, UINT Message, WPARAM wParam, LPARAM lParam) return 0; } +// +// This breaks some test results. Should handle A2U if called! +// +LRESULT WINAPI PopupMenuWndProcA(HWND Wnd, UINT Message, WPARAM wParam, LPARAM lParam) +{ + PWND pWnd; + + pWnd = ValidateHwnd(Wnd); + if (pWnd && !pWnd->fnid && Message != WM_NCCREATE) + { + return DefWindowProcA(Wnd, Message, wParam, lParam); + } + TRACE("YES! hwnd=%x msg=0x%04x wp=0x%04lx lp=0x%08lx\n", Wnd, Message, wParam, lParam); + + switch(Message) + { + case WM_NCCREATE: + case WM_CREATE: + case WM_MOUSEACTIVATE: + case WM_PAINT: + case WM_PRINTCLIENT: + case WM_ERASEBKGND: + case WM_DESTROY: + case WM_NCDESTROY: + case WM_SHOWWINDOW: + case MM_SETMENUHANDLE: + case MM_GETMENUHANDLE: + case MN_GETHMENU: + return PopupMenuWndProcW(Wnd, Message, wParam, lParam); + + default: + return DefWindowProcA(Wnd, Message, wParam, lParam); + } + return 0; +} + /********************************************************************** * MENU_ParseResource * @@ -2129,7 +2796,7 @@ User32LoadSysMenuTemplateForKernel(PVOID Arguments, ULONG ArgumentLength) menuinfo.cbSize = sizeof(menuinfo); menuinfo.fMask = MIM_STYLE; GetMenuInfo(hmenu, &menuinfo); - menuinfo.dwStyle |= MNS_NOCHECK; + menuinfo.dwStyle |= MNS_CHECKORBMP; // test_menu_bmp_and_string MNS_CHECKORBMP SetMenuInfo(hmenu, &menuinfo); // adding bitmaps to menu items @@ -2241,12 +2908,12 @@ DrawMenuBarTemp(HWND Wnd, HDC DC, LPRECT Rect, HMENU Menu, HFONT Font) FontOld = SelectObject(DC, Font); - if (0 == MenuInfo.Height) + if (0 == MenuInfo.cyMenu) { MenuMenuBarCalcSize(DC, Rect, &MenuInfo, Wnd); } - Rect->bottom = Rect->top + MenuInfo.Height; + Rect->bottom = Rect->top + MenuInfo.cyMenu; FillRect(DC, Rect, GetSysColorBrush(flat_menu ? COLOR_MENUBAR : COLOR_MENU)); @@ -2255,28 +2922,57 @@ DrawMenuBarTemp(HWND Wnd, HDC DC, LPRECT Rect, HMENU Menu, HFONT Font) MoveToEx(DC, Rect->left, Rect->bottom - 1, NULL); LineTo(DC, Rect->right, Rect->bottom - 1); - if (0 == MenuInfo.MenuItemCount) + if (0 == MenuInfo.cItems) { SelectObject(DC, FontOld); return GetSystemMetrics(SM_CYMENU); } MenuInitRosMenuItemInfo(&ItemInfo); - for (i = 0; i < MenuInfo.MenuItemCount; i++) + for (i = 0; i < MenuInfo.cItems; i++) { if (MenuGetRosMenuItemInfo(MenuInfo.Self, i, &ItemInfo)) { MenuDrawMenuItem(Wnd, &MenuInfo, Wnd, DC, &ItemInfo, - MenuInfo.Height, TRUE, ODA_DRAWENTIRE); + MenuInfo.cyMenu, TRUE, ODA_DRAWENTIRE); } } MenuCleanupRosMenuItemInfo(&ItemInfo); SelectObject(DC, FontOld); - return MenuInfo.Height; + return MenuInfo.cyMenu; } +#if 0 +static BOOL MENU_InitPopup( HWND hwndOwner, HMENU hmenu, UINT flags ) +{ + POPUPMENU *menu; + DWORD ex_style = 0; + TRACE("owner=%p hmenu=%p\n", hwndOwner, hmenu); + + if (!(menu = MENU_GetMenu( hmenu ))) return FALSE; + + /* store the owner for DrawItem */ + if (!IsWindow( hwndOwner )) + { + SetLastError( ERROR_INVALID_WINDOW_HANDLE ); + return FALSE; + } + menu->hwndOwner = hwndOwner; + + if (flags & TPM_LAYOUTRTL) + ex_style = WS_EX_LAYOUTRTL; + + /* NOTE: In Windows, top menu popup is not owned. */ + menu->hWnd = CreateWindowExW( ex_style, (LPCWSTR)POPUPMENU_CLASS_ATOM, NULL, + WS_POPUP, 0, 0, 0, 0, + hwndOwner, 0, (HINSTANCE)GetWindowLongPtrW(hwndOwner, GWLP_HINSTANCE), + (LPVOID)hmenu ); + if( !menu->hWnd ) return FALSE; + return TRUE; +} +#endif /*********************************************************************** * MenuShowSubPopup * @@ -2295,13 +2991,13 @@ MenuShowSubPopup(HWND WndOwner, PROSMENUINFO MenuInfo, BOOL SelectFirst, UINT Fl TRACE("owner=%x menu=%p 0x%04x\n", WndOwner, MenuInfo, SelectFirst); - if (NO_SELECTED_ITEM == MenuInfo->FocusedItem) + if (NO_SELECTED_ITEM == MenuInfo->iItem) { return MenuInfo->Self; } MenuInitRosMenuItemInfo(&ItemInfo); - if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo)) + if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->iItem, &ItemInfo)) { MenuCleanupRosMenuItemInfo(&ItemInfo); return MenuInfo->Self; @@ -2319,10 +3015,10 @@ MenuShowSubPopup(HWND WndOwner, PROSMENUINFO MenuInfo, BOOL SelectFirst, UINT Fl if (0 == (Flags & TPM_NONOTIFY)) { SendMessageW(WndOwner, WM_INITMENUPOPUP, (WPARAM) ItemInfo.hSubMenu, - MAKELPARAM(MenuInfo->FocusedItem, IS_SYSTEM_MENU(MenuInfo))); + MAKELPARAM(MenuInfo->iItem, IS_SYSTEM_MENU(MenuInfo))); } - if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo)) + if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->iItem, &ItemInfo)) { MenuCleanupRosMenuItemInfo(&ItemInfo); return MenuInfo->Self; @@ -2332,7 +3028,7 @@ MenuShowSubPopup(HWND WndOwner, PROSMENUINFO MenuInfo, BOOL SelectFirst, UINT Fl /* correct item if modified as a reaction to WM_INITMENUPOPUP message */ if (0 == (ItemInfo.fState & MF_HILITE)) { - if (0 != (MenuInfo->Flags & MNF_POPUP)) + if (0 != (MenuInfo->fFlags & MNF_POPUP)) { Dc = GetDC(MenuInfo->Wnd); } @@ -2344,9 +3040,9 @@ MenuShowSubPopup(HWND WndOwner, PROSMENUINFO MenuInfo, BOOL SelectFirst, UINT Fl SelectObject(Dc, hMenuFont); ItemInfo.fMask |= MIIM_STATE; ItemInfo.fState |= MF_HILITE; - MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo); - MenuDrawMenuItem(MenuInfo->Wnd, MenuInfo, WndOwner, Dc, &ItemInfo, MenuInfo->Height, - ! (MenuInfo->Flags & MNF_POPUP), ODA_DRAWENTIRE); + MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->iItem, &ItemInfo); + MenuDrawMenuItem(MenuInfo->Wnd, MenuInfo, WndOwner, Dc, &ItemInfo, MenuInfo->cyMenu, + !(MenuInfo->fFlags & MNF_POPUP), ODA_DRAWENTIRE); ReleaseDC(MenuInfo->Wnd, Dc); } @@ -2358,10 +3054,11 @@ MenuShowSubPopup(HWND WndOwner, PROSMENUINFO MenuInfo, BOOL SelectFirst, UINT Fl ItemInfo.fMask |= MIIM_STATE; ItemInfo.fState |= MF_MOUSESELECT; - MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo); + MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->iItem, &ItemInfo); if (IS_SYSTEM_MENU(MenuInfo)) - { + { + ERR("Right click on window bar and Draw system menu!\n"); MenuInitSysMenuPopup(ItemInfo.hSubMenu, GetWindowLongPtrW(MenuInfo->Wnd, GWL_STYLE), GetClassLongPtrW(MenuInfo->Wnd, GCL_STYLE), HTSYSMENU); if (Flags & TPM_LAYOUTRTL) Rect.left; @@ -2369,19 +3066,23 @@ MenuShowSubPopup(HWND WndOwner, PROSMENUINFO MenuInfo, BOOL SelectFirst, UINT Fl Rect.top = Rect.bottom; Rect.right = GetSystemMetrics(SM_CXSIZE); Rect.bottom = GetSystemMetrics(SM_CYSIZE); - } + } else { GetWindowRect(MenuInfo->Wnd, &Rect); - if (0 != (MenuInfo->Flags & MNF_POPUP)) + if (0 != (MenuInfo->fFlags & MNF_POPUP)) { + RECT rc = ItemInfo.Rect; + + MENU_AdjustMenuItemRect(MenuInfo, &rc); + if(Flags & TPM_LAYOUTRTL) Rect.left += GetSystemMetrics(SM_CXBORDER); else Rect.left += ItemInfo.Rect.right- GetSystemMetrics(SM_CXBORDER); - Rect.top += ItemInfo.Rect.top - MENU_TOP_MARGIN;//3; - Rect.right = ItemInfo.Rect.left - ItemInfo.Rect.right + GetSystemMetrics(SM_CXBORDER); - Rect.bottom = ItemInfo.Rect.top - ItemInfo.Rect.bottom - MENU_TOP_MARGIN - MENU_BOTTOM_MARGIN/*2*/ + Rect.top += rc.top - MENU_TOP_MARGIN;//3; + Rect.right = rc.left - rc.right + GetSystemMetrics(SM_CXBORDER); + Rect.bottom = rc.top - rc.bottom - MENU_TOP_MARGIN - MENU_BOTTOM_MARGIN/*2*/ - GetSystemMetrics(SM_CYBORDER); } else @@ -2399,7 +3100,9 @@ MenuShowSubPopup(HWND WndOwner, PROSMENUINFO MenuInfo, BOOL SelectFirst, UINT Fl /* use default alignment for submenus */ Flags &= ~(TPM_CENTERALIGN | TPM_RIGHTALIGN | TPM_VCENTERALIGN | TPM_BOTTOMALIGN); - MenuShowPopup(WndOwner, ItemInfo.hSubMenu, MenuInfo->FocusedItem, Flags, + //MENU_InitPopup( WndOwner, ItemInfo.hSubMenu, Flags ); + + MenuShowPopup(WndOwner, ItemInfo.hSubMenu, MenuInfo->iItem, Flags, Rect.left, Rect.top, Rect.right, Rect.bottom ); if (SelectFirst && MenuGetRosMenuInfo(&SubMenuInfo, ItemInfo.hSubMenu)) { @@ -2425,7 +3128,7 @@ void MENU_EndMenu( HWND hwnd ) BOOL Ret = FALSE; if (top_popup_hmenu) Ret = MenuGetRosMenuInfo(&MenuInfo, top_popup_hmenu); - if (Ret && hwnd == MenuInfo.WndOwner) EndMenu(); + if (Ret && hwnd == (MenuInfo.spwndNotify ? MenuInfo.spwndNotify->head.h : NULL)) EndMenu(); } /*********************************************************************** @@ -2442,11 +3145,11 @@ MenuHideSubPopups(HWND WndOwner, PROSMENUINFO MenuInfo, TRACE("owner=%x menu=%x 0x%04x\n", WndOwner, MenuInfo, SendMenuSelect); - if (NULL != MenuInfo && NULL != top_popup && NO_SELECTED_ITEM != MenuInfo->FocusedItem) + if (NULL != MenuInfo && NULL != top_popup && NO_SELECTED_ITEM != MenuInfo->iItem) { MenuInitRosMenuItemInfo(&ItemInfo); ItemInfo.fMask |= MIIM_FTYPE | MIIM_STATE; - if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo) + if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->iItem, &ItemInfo) || 0 == (ItemInfo.hSubMenu) || 0 == (ItemInfo.fState & MF_MOUSESELECT)) { @@ -2455,7 +3158,7 @@ MenuHideSubPopups(HWND WndOwner, PROSMENUINFO MenuInfo, } ItemInfo.fState &= ~MF_MOUSESELECT; ItemInfo.fMask |= MIIM_STATE; - MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo); + MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->iItem, &ItemInfo); if (MenuGetRosMenuInfo(&SubMenuInfo, ItemInfo.hSubMenu)) { MenuHideSubPopups(WndOwner, &SubMenuInfo, FALSE, wFlags); @@ -2485,7 +3188,7 @@ MenuSwitchTracking(MTRACKER* Mt, PROSMENUINFO PtMenuInfo, UINT Index, UINT wFlag if (MenuGetRosMenuInfo(&TopMenuInfo, Mt->TopMenu) && Mt->TopMenu != PtMenuInfo->Self && - 0 == ((PtMenuInfo->Flags | TopMenuInfo.Flags) & MNF_POPUP)) + 0 == ((PtMenuInfo->fFlags | TopMenuInfo.fFlags) & MNF_POPUP)) { /* both are top level menus (system and menu-bar) */ MenuHideSubPopups(Mt->OwnerWnd, &TopMenuInfo, FALSE, wFlags); @@ -2518,13 +3221,13 @@ MenuExecFocusedItem(MTRACKER *Mt, PROSMENUINFO MenuInfo, UINT Flags) TRACE("%p menu=%p\n", Mt, MenuInfo); - if (0 == MenuInfo->MenuItemCount || NO_SELECTED_ITEM == MenuInfo->FocusedItem) + if (0 == MenuInfo->cItems || NO_SELECTED_ITEM == MenuInfo->iItem) { return -1; } MenuInitRosMenuItemInfo(&ItemInfo); - if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo)) + if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->iItem, &ItemInfo)) { MenuCleanupRosMenuItemInfo(&ItemInfo); return -1; @@ -2541,7 +3244,7 @@ MenuExecFocusedItem(MTRACKER *Mt, PROSMENUINFO MenuInfo, UINT Flags) do not send a message to the owner */ if (0 == (Flags & TPM_RETURNCMD)) { - if (0 != (MenuInfo->Flags & MNF_SYSDESKMN)) + if (0 != (MenuInfo->fFlags & MNF_SYSDESKMN)) { PostMessageW(Mt->OwnerWnd, WM_SYSCOMMAND, ItemInfo.wID, MAKELPARAM((SHORT) Mt->Pt.x, (SHORT) Mt->Pt.y)); @@ -2553,7 +3256,7 @@ MenuExecFocusedItem(MTRACKER *Mt, PROSMENUINFO MenuInfo, UINT Flags) DWORD dwStyle = MenuInfo->dwStyle | (ret ? topmenuI.dwStyle : 0); if (dwStyle & MNS_NOTIFYBYPOS) - PostMessageW(Mt->OwnerWnd, WM_MENUCOMMAND, MenuInfo->FocusedItem, (LPARAM)MenuInfo->Self); + PostMessageW(Mt->OwnerWnd, WM_MENUCOMMAND, MenuInfo->iItem, (LPARAM)MenuInfo->Self); else PostMessageW(Mt->OwnerWnd, WM_COMMAND, ItemInfo.wID, 0); } @@ -2610,7 +3313,7 @@ MenuButtonDown(MTRACKER* Mt, HMENU PtMenu, UINT Flags) if (!(Item.fType & MF_SEPARATOR) && !(Item.fState & (MFS_DISABLED | MFS_GRAYED)) ) { - if (MenuInfo.FocusedItem != Index) + if (MenuInfo.iItem != Index) { MenuSwitchTracking(Mt, &MenuInfo, Index, Flags); } @@ -2663,7 +3366,7 @@ MenuButtonUp(MTRACKER *Mt, HMENU PtMenu, UINT Flags) } MenuInitRosMenuItemInfo(&ItemInfo); if (0 <= Id && MenuGetRosMenuItemInfo(MenuInfo.Self, Id, &ItemInfo) && - MenuInfo.FocusedItem == Id) + MenuInfo.iItem == Id) { if (0 == (ItemInfo.hSubMenu)) { @@ -2710,10 +3413,10 @@ MenuPtMenu(HMENU Menu, POINT Pt) } /* try subpopup first (if any) */ - if (NO_SELECTED_ITEM != MenuInfo.FocusedItem) + if (NO_SELECTED_ITEM != MenuInfo.iItem) { MenuInitRosMenuItemInfo(&ItemInfo); - if (MenuGetRosMenuItemInfo(MenuInfo.Self, MenuInfo.FocusedItem, &ItemInfo) && + if (MenuGetRosMenuItemInfo(MenuInfo.Self, MenuInfo.iItem, &ItemInfo) && 0 != (ItemInfo.hSubMenu) && 0 != (ItemInfo.fState & MF_MOUSESELECT)) { @@ -2729,7 +3432,7 @@ MenuPtMenu(HMENU Menu, POINT Pt) /* check the current window (avoiding WM_HITTEST) */ Ht = DefWndNCHitTest(MenuInfo.Wnd, Pt); - if (0 != (MenuInfo.Flags & MNF_POPUP)) + if (0 != (MenuInfo.fFlags & MNF_POPUP)) { if (HTNOWHERE != Ht && HTERROR != Ht) { @@ -2789,7 +3492,7 @@ MenuMouseMove(MTRACKER *Mt, HMENU PtMenu, UINT Flags) TRUE, Mt->TopMenu); } } - else if (MenuInfo.FocusedItem != Index) + else if (MenuInfo.iItem != Index) { MenuInitRosMenuItemInfo(&ItemInfo); if (MenuGetRosMenuItemInfo(MenuInfo.Self, Index, &ItemInfo) && @@ -2817,13 +3520,13 @@ MenuGetSubPopup(HMENU Menu) ROSMENUITEMINFO ItemInfo; if (! MenuGetRosMenuInfo(&MenuInfo, Menu) - || NO_SELECTED_ITEM == MenuInfo.FocusedItem) + || NO_SELECTED_ITEM == MenuInfo.iItem) { return NULL; } MenuInitRosMenuItemInfo(&ItemInfo); - if (! MenuGetRosMenuItemInfo(MenuInfo.Self, MenuInfo.FocusedItem, &ItemInfo)) + if (! MenuGetRosMenuItemInfo(MenuInfo.Self, MenuInfo.iItem, &ItemInfo)) { MenuCleanupRosMenuItemInfo(&ItemInfo); return NULL; @@ -2854,8 +3557,8 @@ MenuDoNextMenu(MTRACKER* Mt, UINT Vk, UINT wFlags) return (LRESULT) FALSE; } - if ((VK_LEFT == Vk && 0 == TopMenuInfo.FocusedItem) - || (VK_RIGHT == Vk && TopMenuInfo.FocusedItem == TopMenuInfo.MenuItemCount - 1)) + if ((VK_LEFT == Vk && 0 == TopMenuInfo.iItem) + || (VK_RIGHT == Vk && TopMenuInfo.iItem == TopMenuInfo.cItems - 1)) { MDINEXTMENU NextMenu; HMENU NewMenu; @@ -2890,7 +3593,7 @@ MenuDoNextMenu(MTRACKER* Mt, UINT Vk, UINT wFlags) { return FALSE; } - Id = MenuInfo.MenuItemCount - 1; + Id = MenuInfo.cItems - 1; } } else if (0 != (Style & WS_SYSMENU)) @@ -3015,7 +3718,7 @@ MenuKeyEscape(MTRACKER *Mt, UINT Flags) if (Mt->CurrentMenu != Mt->TopMenu) { if (MenuGetRosMenuInfo(&MenuInfo, Mt->CurrentMenu) - && 0 != (MenuInfo.Flags & MNF_POPUP)) + && 0 != (MenuInfo.fFlags & MNF_POPUP)) { MenuPrev = MenuTmp = Mt->TopMenu; @@ -3087,7 +3790,7 @@ MenuKeyLeft(MTRACKER* Mt, UINT Flags) { return; } - if ((MenuPrev == Mt->TopMenu) && !(TopMenuInfo.Flags & MNF_POPUP)) + if ((MenuPrev == Mt->TopMenu) && !(TopMenuInfo.fFlags & MNF_POPUP)) { /* move menu bar selection if no more popups are left */ @@ -3127,7 +3830,7 @@ static void FASTCALL MenuKeyRight(MTRACKER *Mt, UINT Flags) Mt->CurrentMenu, Mt->TopMenu); if (! MenuGetRosMenuInfo(&MenuInfo, Mt->TopMenu)) return; - if ((MenuInfo.Flags & MNF_POPUP) || (Mt->CurrentMenu != Mt->TopMenu)) + if ((MenuInfo.fFlags & MNF_POPUP) || (Mt->CurrentMenu != Mt->TopMenu)) { /* If already displaying a popup, try to display sub-popup */ @@ -3157,7 +3860,7 @@ static void FASTCALL MenuKeyRight(MTRACKER *Mt, UINT Flags) return; } - if (!(MenuInfo.Flags & MNF_POPUP)) /* menu bar tracking */ + if (!(MenuInfo.fFlags & MNF_POPUP)) /* menu bar tracking */ { if (Mt->CurrentMenu != Mt->TopMenu) { @@ -3243,7 +3946,7 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y, while (! fEndMenu) { BOOL ErrorExit = FALSE; - PVOID menu = ValidateHandle(mt.CurrentMenu, TYPE_MENU); + PMENU menu = ValidateHandle(mt.CurrentMenu, TYPE_MENU); if (!menu) /* sometimes happens if I do a window manager close */ break; @@ -3268,7 +3971,7 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y, } if (!enterIdleSent) { - HWND win = MenuInfo.Flags & MNF_POPUP ? MenuInfo.Wnd : NULL; + HWND win = MenuInfo.fFlags & MNF_POPUP ? MenuInfo.Wnd : NULL; enterIdleSent = TRUE; SendMessageW( mt.OwnerWnd, WM_ENTERIDLE, MSGF_MENU, (LPARAM) win); } @@ -3316,6 +4019,7 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y, /* no WM_NC... messages in captured state */ case WM_RBUTTONDBLCLK: + ERR("WM_RBUTTONDBLCLK\n"); case WM_RBUTTONDOWN: if (!(wFlags & TPM_RIGHTBUTTON)) break; /* fall through */ @@ -3387,7 +4091,7 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y, case VK_DOWN: /* If on menu bar, pull-down the menu */ if (MenuGetRosMenuInfo(&MenuInfo, mt.CurrentMenu)) { - if (!(MenuInfo.Flags & MNF_POPUP)) + if (!(MenuInfo.fFlags & MNF_POPUP)) { if (MenuGetRosMenuInfo(&MenuInfo, mt.TopMenu)) mt.CurrentMenu = MenuShowSubPopup(mt.OwnerWnd, &MenuInfo, TRUE, wFlags); @@ -3417,13 +4121,13 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y, hi.iContextType = HELPINFO_MENUITEM; if (MenuGetRosMenuInfo(&MenuInfo, mt.CurrentMenu)) { - if (MenuInfo.FocusedItem == NO_SELECTED_ITEM) + if (MenuInfo.iItem == NO_SELECTED_ITEM) hi.iCtrlId = 0; else { MenuInitRosMenuItemInfo(&ItemInfo); if (MenuGetRosMenuItemInfo(MenuInfo.Self, - MenuInfo.FocusedItem, + MenuInfo.iItem, &ItemInfo)) { hi.iCtrlId = ItemInfo.wID; @@ -3510,7 +4214,7 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y, { MenuHideSubPopups(mt.OwnerWnd, &MenuInfo, FALSE, wFlags); - if (MenuInfo.Flags & MNF_POPUP) + if (MenuInfo.fFlags & MNF_POPUP) { IntNotifyWinEvent(EVENT_SYSTEM_MENUPOPUPEND, MenuInfo.Wnd, OBJID_CLIENT, CHILDID_SELF, 0); DestroyWindow(MenuInfo.Wnd); @@ -3574,7 +4278,7 @@ static BOOL FASTCALL MenuInitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT * menu sizes will be recalculated once the menu created/shown. */ - if (!MenuInfo.Height) + if (!MenuInfo.cyMenu) { /* app changed/recreated menu bar entries in WM_INITMENU Recalculate menu sizes else clicks will not work */ @@ -3586,7 +4290,7 @@ static BOOL FASTCALL MenuInitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT IntNotifyWinEvent( EVENT_SYSTEM_MENUSTART, hWnd, - MenuInfo.Flags & MNF_SYSDESKMN ? OBJID_SYSMENU : OBJID_MENU, + MenuInfo.fFlags & MNF_SYSDESKMN ? OBJID_SYSMENU : OBJID_MENU, CHILDID_SELF, 0); return TRUE; } @@ -3886,16 +4590,13 @@ MenuSetItemData( mii->fMask |= MIIM_STATE; } - if(Flags & MF_POPUP) + if(Flags & MF_POPUP && IsMenu((HMENU)IDNewItem)) { mii->fMask |= MIIM_SUBMENU; mii->hSubMenu = (HMENU)IDNewItem; } - else - { - mii->fMask |= MIIM_ID; - mii->wID = (UINT)IDNewItem; - } + mii->fMask |= MIIM_ID; + mii->wID = (UINT)IDNewItem; return TRUE; } @@ -3915,16 +4616,63 @@ User32CallLoadMenuFromKernel(PVOID Arguments, ULONG ArgumentLength) return ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS); } +/********************************************************************** + * MENU_NormalizeMenuItemInfoStruct + * + * Helper for SetMenuItemInfo and InsertMenuItemInfo: + * check, copy and extend the MENUITEMINFO struct from the version that the application + * supplied to the version used by wine source. */ +static BOOL MENU_NormalizeMenuItemInfoStruct( const MENUITEMINFOW *pmii_in, + MENUITEMINFOW *pmii_out ) +{ + /* do we recognize the size? */ + if( !pmii_in || (pmii_in->cbSize != sizeof( MENUITEMINFOW) && + pmii_in->cbSize != sizeof( MENUITEMINFOW) - sizeof( pmii_in->hbmpItem)) ) { + SetLastError( ERROR_INVALID_PARAMETER); + return FALSE; + } + /* copy the fields that we have */ + memcpy( pmii_out, pmii_in, pmii_in->cbSize); + /* if the hbmpItem member is missing then extend */ + if( pmii_in->cbSize != sizeof( MENUITEMINFOW)) { + pmii_out->cbSize = sizeof( MENUITEMINFOW); + pmii_out->hbmpItem = NULL; + } + /* test for invalid bit combinations */ + if( (pmii_out->fMask & MIIM_TYPE && + pmii_out->fMask & (MIIM_STRING | MIIM_FTYPE | MIIM_BITMAP)) || + (pmii_out->fMask & MIIM_FTYPE && pmii_out->fType & MFT_BITMAP)) { + ERR("invalid combination of fMask bits used\n"); + /* this does not happen on Win9x/ME */ + SetLastError( ERROR_INVALID_PARAMETER); + return FALSE; + } + /* convert old style (MIIM_TYPE) to the new and keep the old one too */ + if( pmii_out->fMask & MIIM_TYPE){ + pmii_out->fMask |= MIIM_FTYPE; + if( IS_STRING_ITEM(pmii_out->fType)){ + pmii_out->fMask |= MIIM_STRING; + } else if( (pmii_out->fType) & MFT_BITMAP){ + pmii_out->fMask |= MIIM_BITMAP; + pmii_out->hbmpItem = UlongToHandle(LOWORD(pmii_out->dwTypeData)); + } + } + if (pmii_out->fMask & MIIM_FTYPE ) + { + pmii_out->fType &= ~MENUITEMINFO_TYPE_MASK; + pmii_out->fType |= pmii_in->fType & MENUITEMINFO_TYPE_MASK; + } + if (pmii_out->fMask & MIIM_STATE) + /* Other menu items having MFS_DEFAULT are not converted + to normal items */ + pmii_out->fState = pmii_in->fState & MENUITEMINFO_STATE_MASK; + + return TRUE; +} + /* FUNCTIONS *****************************************************************/ -/*static BOOL -MenuIsStringItem(ULONG TypeData) -{ - return(MF_STRING == MENU_ITEM_TYPE(ItemInfo->fType)); -}*/ - - /* * @implemented */ @@ -3934,11 +4682,9 @@ AppendMenuA(HMENU hMenu, UINT_PTR uIDNewItem, LPCSTR lpNewItem) { - return(InsertMenuA(hMenu, -1, uFlags | MF_BYPOSITION, uIDNewItem, - lpNewItem)); + return(InsertMenuA(hMenu, -1, uFlags | MF_BYPOSITION, uIDNewItem, lpNewItem)); } - /* * @implemented */ @@ -3948,11 +4694,9 @@ AppendMenuW(HMENU hMenu, UINT_PTR uIDNewItem, LPCWSTR lpNewItem) { - return(InsertMenuW(hMenu, -1, uFlags | MF_BYPOSITION, uIDNewItem, - lpNewItem)); + return(InsertMenuW(hMenu, -1, uFlags | MF_BYPOSITION, uIDNewItem, lpNewItem)); } - /* * @implemented */ @@ -3961,141 +4705,86 @@ CheckMenuItem(HMENU hmenu, UINT uIDCheckItem, UINT uCheck) { + PMENU pMenu; + PITEM item; + DWORD Ret; + + if (!(pMenu = ValidateHandle(hmenu, TYPE_MENU))) + return -1; + + if (!(item = MENU_FindItem( &hmenu, &uIDCheckItem, uCheck ))) return -1; + + Ret = item->fState & MFS_CHECKED; + if ( Ret == (uCheck & MFS_CHECKED)) return Ret; // Already Checked... + return NtUserCheckMenuItem(hmenu, uIDCheckItem, uCheck); } -static -BOOL -MenuCheckMenuRadioItem(HMENU hMenu, UINT idFirst, UINT idLast, UINT idCheck, UINT uFlags, BOOL bCheck, PUINT pChecked, PUINT pUnchecked, PUINT pMenuChanged) -{ - UINT ItemCount, i; - PROSMENUITEMINFO Items = NULL; - UINT cChecked, cUnchecked; - BOOL bRet = TRUE; - //ROSMENUINFO mi; - - if(idFirst > idLast) - return FALSE; - - ItemCount = GetMenuItemCount(hMenu); - - //mi.cbSize = sizeof(ROSMENUINFO); - //if(!NtUserMenuInfo(hmenu, &mi, FALSE)) return ret; - - - if(MenuGetAllRosMenuItemInfo(hMenu, &Items) <= 0) - { - ERR("MenuGetAllRosMenuItemInfo failed\n"); - return FALSE; - } - - cChecked = cUnchecked = 0; - - for (i = 0 ; i < ItemCount; i++) - { - BOOL check = FALSE; - if (0 != (Items[i].fType & MF_MENUBARBREAK)) continue; - if (0 != (Items[i].fType & MF_SEPARATOR)) continue; - - if ((Items[i].hSubMenu) && (uFlags == MF_BYCOMMAND)) - { - MenuCheckMenuRadioItem(Items[i].hSubMenu, idFirst, idLast, idCheck, uFlags, bCheck, pChecked, pUnchecked, pMenuChanged); - continue; - } - if (uFlags & MF_BYPOSITION) - { - if (i < idFirst || i > idLast) - continue; - - if (i == idCheck) - { - cChecked++; - check = TRUE; - } - else - { - cUnchecked++; - } - } - else - { - if (Items[i].wID < idFirst || Items[i].wID > idLast) - continue; - - if (Items[i].wID == idCheck) - { - cChecked++; - check = TRUE; - } - else - { - cUnchecked++; - } - } - - if (!bCheck) - continue; - - Items[i].fMask = MIIM_STATE | MIIM_FTYPE; - if (check) - { - Items[i].fType |= MFT_RADIOCHECK; - Items[i].fState |= MFS_CHECKED; - } - else - { - Items[i].fState &= ~MFS_CHECKED; - } - - if(!MenuSetRosMenuItemInfo(hMenu, i ,&Items[i])) - { - ERR("MenuSetRosMenuItemInfo failed\n"); - bRet = FALSE; - break; - } - } - HeapFree(GetProcessHeap(), 0, Items); - - *pChecked += cChecked; - *pUnchecked += cUnchecked; - - if (cChecked || cUnchecked) - (*pMenuChanged)++; - - return bRet; -} /* * @implemented */ BOOL WINAPI -CheckMenuRadioItem(HMENU hmenu, - UINT idFirst, - UINT idLast, - UINT idCheck, - UINT uFlags) +CheckMenuRadioItem(HMENU hMenu, + UINT first, + UINT last, + UINT check, + UINT bypos) { - UINT cChecked = 0; - UINT cUnchecked = 0; - UINT cMenuChanged = 0; + BOOL done = FALSE; + UINT i; + PITEM mi_first = NULL, mi_check; + HMENU m_first, m_check; + MENUITEMINFOW mii; + mii.cbSize = sizeof( mii); - if (!MenuCheckMenuRadioItem(hmenu, idFirst, idLast, idCheck, uFlags, FALSE, &cChecked, &cUnchecked, &cMenuChanged)) - return FALSE; + for (i = first; i <= last; i++) + { + UINT pos = i; - if (cMenuChanged > 1) - return FALSE; + if (!mi_first) + { + m_first = hMenu; + mi_first = MENU_FindItem(&m_first, &pos, bypos); + if (!mi_first) continue; + mi_check = mi_first; + m_check = m_first; + } + else + { + m_check = hMenu; + mi_check = MENU_FindItem(&m_check, &pos, bypos); + if (!mi_check) continue; + } - cMenuChanged = 0; - cChecked = 0; - cUnchecked = 0; + if (m_first != m_check) continue; + if (mi_check->fType == MFT_SEPARATOR) continue; - if (!MenuCheckMenuRadioItem(hmenu, idFirst, idLast, idCheck, uFlags, TRUE, &cChecked, &cUnchecked, &cMenuChanged)) - return FALSE; - - return (cChecked != 0); + if (i == check) + { + if (!(mi_check->fType & MFT_RADIOCHECK) || !(mi_check->fState & MFS_CHECKED)) + { + mii.fMask = MIIM_FTYPE | MIIM_STATE; + mii.fType = (mi_check->fType & MENUITEMINFO_TYPE_MASK) | MFT_RADIOCHECK; + mii.fState = (mi_check->fState & MII_STATE_MASK) | MFS_CHECKED; + NtUserThunkedMenuItemInfo(m_check, i, bypos, FALSE, &mii, NULL); + } + done = TRUE; + } + else + { + /* MSDN is wrong, Windows does not remove MFT_RADIOCHECK */ + if (mi_check->fState & MFS_CHECKED) + { + mii.fMask = MIIM_STATE; + mii.fState = (mi_check->fState & MII_STATE_MASK) & ~MFS_CHECKED; + NtUserThunkedMenuItemInfo(m_check, i, bypos, FALSE, &mii, NULL); + } + } + } + return done; } - /* * @implemented */ @@ -4106,7 +4795,6 @@ CreateMenu(VOID) return NtUserxCreateMenu(); } - /* * @implemented */ @@ -4117,26 +4805,13 @@ CreatePopupMenu(VOID) return NtUserxCreatePopupMenu(); } - /* * @implemented */ BOOL WINAPI DrawMenuBar(HWND hWnd) { -// return NtUserxDrawMenuBar(hWnd); - ROSMENUINFO MenuInfo; - HMENU hMenu; - hMenu = GetMenu(hWnd); - if (!hMenu) - return FALSE; - MenuGetRosMenuInfo(&MenuInfo, hMenu); - MenuInfo.Height = 0; // make sure to recalc size - MenuSetRosMenuInfo(&MenuInfo); - - SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | - SWP_NOZORDER | SWP_FRAMECHANGED ); - return TRUE; + return NtUserxDrawMenuBar(hWnd); } /* @@ -4193,11 +4868,13 @@ BOOL WINAPI HiliteMenuItem( HWND hWnd, HMENU hMenu, UINT wItemID, if (!NtUserHiliteMenuItem(hWnd, hMenu, wItemID, wHilite)) return FALSE; // Without the above call we fail 3 out of the wine failed todo tests, see CORE-7967 // Now redraw menu. - if (!MenuGetRosMenuInfo(&MenuInfo, hMenu)) return FALSE; - if (MenuInfo.FocusedItem == wItemID) return TRUE; - MenuHideSubPopups( hWnd, &MenuInfo, FALSE, 0 ); - MenuSelectItem( hWnd, &MenuInfo, wItemID, TRUE, 0 ); - return TRUE; + if (MenuGetRosMenuInfo(&MenuInfo, hMenu)) + { + if (MenuInfo.iItem == wItemID) return TRUE; + MenuHideSubPopups( hWnd, &MenuInfo, FALSE, 0 ); + MenuSelectItem( hWnd, &MenuInfo, wItemID, TRUE, 0 ); + } + return TRUE; // Always returns TRUE! } /* @@ -4234,7 +4911,6 @@ BOOL WINAPI GetMenuBarInfo( HWND hwnd, LONG idObject, LONG idItem, PMENUBARINFO return TRUE; } - /* * @implemented */ @@ -4245,6 +4921,18 @@ GetMenuCheckMarkDimensions(VOID) GetSystemMetrics(SM_CYMENUCHECK))); } +/* + * @implemented + */ +DWORD +WINAPI +GetMenuContextHelpId(HMENU hmenu) +{ + PMENU pMenu; + if ((pMenu = ValidateHandle(hmenu, TYPE_MENU))) + return pMenu->dwContextHelpId; + return 0; +} /* * @implemented @@ -4254,9 +4942,13 @@ GetMenuDefaultItem(HMENU hMenu, UINT fByPos, UINT gmdiFlags) { - return NtUserGetMenuDefaultItem(hMenu, fByPos, gmdiFlags); -} + PMENU pMenu; + DWORD gismc = 0; + if (!(pMenu = ValidateHandle(hMenu, TYPE_MENU))) + return (UINT)-1; + return IntGetMenuDefaultItem( pMenu, (BOOL)fByPos, gmdiFlags, &gismc); +} /* * @implemented @@ -4265,9 +4957,7 @@ BOOL WINAPI GetMenuInfo(HMENU hmenu, LPMENUINFO lpcmi) { - ROSMENUINFO mi; - BOOL res = FALSE; - PVOID pMenu; + PMENU pMenu; if (!lpcmi || (lpcmi->cbSize != sizeof(MENUINFO))) { @@ -4278,29 +4968,36 @@ GetMenuInfo(HMENU hmenu, if (!(pMenu = ValidateHandle(hmenu, TYPE_MENU))) return FALSE; - RtlZeroMemory(&mi, sizeof(MENUINFO)); - mi.cbSize = sizeof(MENUINFO); - mi.fMask = lpcmi->fMask; + if (lpcmi->fMask & MIM_BACKGROUND) + lpcmi->hbrBack = pMenu->hbrBack; - res = NtUserMenuInfo(hmenu, &mi, FALSE); + if (lpcmi->fMask & MIM_HELPID) + lpcmi->dwContextHelpID = pMenu->dwContextHelpId; - memcpy(lpcmi, &mi, sizeof(MENUINFO)); - return res; + if (lpcmi->fMask & MIM_MAXHEIGHT) + lpcmi->cyMax = pMenu->cyMax; + + if (lpcmi->fMask & MIM_MENUDATA) + lpcmi->dwMenuData = pMenu->dwMenuData; + + if (lpcmi->fMask & MIM_STYLE) + lpcmi->dwStyle = pMenu->fFlags & MNS_STYLE_MASK; + + return TRUE; } - /* * @implemented */ int WINAPI -GetMenuItemCount(HMENU Menu) +GetMenuItemCount(HMENU hmenu) { - ROSMENUINFO MenuInfo; - - return MenuGetRosMenuInfo(&MenuInfo, Menu) ? MenuInfo.MenuItemCount : 0; + PMENU pMenu; + if ((pMenu = ValidateHandle(hmenu, TYPE_MENU))) + return pMenu->cItems; + return -1; } - /* * @implemented */ @@ -4308,180 +5005,86 @@ UINT WINAPI GetMenuItemID(HMENU hMenu, int nPos) { - ROSMENUITEMINFO mii; + PMENU pMenu; + PITEM pItem; + INT i = 0; - mii.cbSize = sizeof(MENUITEMINFOW); - mii.fMask = MIIM_ID | MIIM_SUBMENU; + if (!(pMenu = ValidateHandle(hMenu, TYPE_MENU))) + return -1; - if (! NtUserMenuItemInfo(hMenu, nPos, MF_BYPOSITION, &mii, FALSE)) - { - return -1; - } - - if (NULL != mii.hSubMenu) - { - return -1; - } - if (0 == mii.wID) - { - return -1; - } - - return mii.wID; + pItem = pMenu->rgItems ? DesktopPtrToUser(pMenu->rgItems) : NULL; + if ( nPos >= 0 ) + { + //pItem = &menu->rgItems[nPos]; or pItem[nPos]; after dptu. + while(pItem) // Do this for now. + { + if (i < (INT)pMenu->cItems) + { + if ( nPos == i && !pItem->spSubMenu) return pItem->wID; + } + pItem = pItem->Next ? DesktopPtrToUser(pItem->Next) : NULL; + i++; + } + } + return -1; } - /* * @implemented */ BOOL WINAPI GetMenuItemInfoA( - HMENU Menu, - UINT Item, - BOOL ByPosition, - LPMENUITEMINFOA mii) + HMENU hmenu, + UINT item, + BOOL bypos, + LPMENUITEMINFOA lpmii) { - MENUITEMINFOW miiW; - LPSTR AnsiBuffer; - INT Count; + BOOL ret; + MENUITEMINFOA mii; - if (mii->cbSize != sizeof(MENUITEMINFOA) && - mii->cbSize != sizeof(MENUITEMINFOA) - sizeof(HBITMAP)) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - if(!(mii->fMask & (MIIM_TYPE | MIIM_STRING))) - { - /* No text requested, just pass on */ - return NtUserMenuItemInfo(Menu, Item, ByPosition, (PROSMENUITEMINFO) mii, FALSE); - } - - AnsiBuffer = mii->dwTypeData; - Count = miiW.cch = mii->cch; - RtlCopyMemory(&miiW, mii, mii->cbSize); - miiW.dwTypeData = 0; - - if (AnsiBuffer) - { - miiW.dwTypeData = RtlAllocateHeap(GetProcessHeap(), 0, - miiW.cch * sizeof(WCHAR)); - if (miiW.dwTypeData == NULL) return FALSE; - miiW.dwTypeData[0] = 0; - } - - if (!NtUserMenuItemInfo(Menu, Item, ByPosition, (PROSMENUITEMINFO)&miiW, FALSE)) - { - if (miiW.dwTypeData) RtlFreeHeap(GetProcessHeap(), 0, miiW.dwTypeData); - return FALSE; - } - - RtlCopyMemory(mii, &miiW, miiW.cbSize); - - if (!AnsiBuffer || !Count) - { - if (miiW.dwTypeData) RtlFreeHeap(GetProcessHeap(), 0, miiW.dwTypeData); - mii->dwTypeData = AnsiBuffer; - mii->cch = miiW.cch; - return TRUE; - } - - if ((miiW.fMask & MIIM_STRING) || (IS_STRING_ITEM(miiW.fType))) - { - if (miiW.cch) - { - if (!WideCharToMultiByte(CP_ACP, 0, miiW.dwTypeData, miiW.cch, AnsiBuffer, mii->cch, NULL, NULL)) - { - AnsiBuffer[0] = 0; - } - if (Count > miiW.cch) - { - AnsiBuffer[miiW.cch] = 0; - } - mii->cch = miiW.cch; - } - } - else - { - AnsiBuffer[0] = 0; - } - - RtlFreeHeap(GetProcessHeap(), 0, miiW.dwTypeData); - mii->dwTypeData = AnsiBuffer; - - return TRUE; + if( lpmii->cbSize != sizeof( mii) && + lpmii->cbSize != sizeof( mii) - sizeof ( mii.hbmpItem)) + { + SetLastError( ERROR_INVALID_PARAMETER); + return FALSE; + } + memcpy( &mii, lpmii, lpmii->cbSize); + mii.cbSize = sizeof( mii); + ret = GetMenuItemInfo_common (hmenu, + item, + bypos, + (LPMENUITEMINFOW)&mii, + FALSE); + mii.cbSize = lpmii->cbSize; + memcpy( lpmii, &mii, mii.cbSize); + return ret; } - /* * @implemented */ BOOL WINAPI GetMenuItemInfoW( - HMENU Menu, + HMENU hMenu, UINT Item, - BOOL ByPosition, - LPMENUITEMINFOW mii) + BOOL bypos, + LPMENUITEMINFOW lpmii) { - MENUITEMINFOW miiW; - LPWSTR String; - INT Count; - - if (mii->cbSize != sizeof(MENUITEMINFOW) && - mii->cbSize != sizeof(MENUITEMINFOW) - sizeof(HBITMAP)) + BOOL ret; + MENUITEMINFOW mii; + if( lpmii->cbSize != sizeof( mii) && lpmii->cbSize != sizeof( mii) - sizeof ( mii.hbmpItem)) { - SetLastError(ERROR_INVALID_PARAMETER); + SetLastError( ERROR_INVALID_PARAMETER); return FALSE; } - - if(!(mii->fMask & (MIIM_TYPE | MIIM_STRING))) - { - /* No text requested, just pass on */ - return NtUserMenuItemInfo(Menu, Item, ByPosition, (PROSMENUITEMINFO) mii, FALSE); - } - - String = mii->dwTypeData; - Count = mii->cch; - RtlCopyMemory(&miiW, mii, mii->cbSize); - miiW.dwTypeData = 0; - - if (String) - { - miiW.dwTypeData = RtlAllocateHeap(GetProcessHeap(), 0, - miiW.cch * sizeof(WCHAR)); - if (miiW.dwTypeData == NULL) return FALSE; - miiW.dwTypeData[0] = 0; - } - - if (!NtUserMenuItemInfo(Menu, Item, ByPosition, (PROSMENUITEMINFO) &miiW, FALSE)) - { - if (miiW.dwTypeData) RtlFreeHeap(GetProcessHeap(), 0, miiW.dwTypeData); - return FALSE; - } - - RtlCopyMemory(mii, &miiW, miiW.cbSize); // Okay to over write user data. - - if (!String || !Count) - { - if (miiW.dwTypeData) RtlFreeHeap(GetProcessHeap(), 0, miiW.dwTypeData); - mii->dwTypeData = String; // may not be zero. - mii->cch = miiW.cch; - return TRUE; - } - - if ((miiW.fMask & MIIM_STRING) || (IS_STRING_ITEM(miiW.fType))) - { - lstrcpynW( String, miiW.dwTypeData, Count ); - } - - RtlFreeHeap(GetProcessHeap(), 0, miiW.dwTypeData); - mii->dwTypeData = String; - mii->cch = strlenW(String); - return TRUE; + memcpy( &mii, lpmii, lpmii->cbSize); + mii.cbSize = sizeof( mii); + ret = GetMenuItemInfo_common (hMenu, Item, bypos, &mii, TRUE); + mii.cbSize = lpmii->cbSize; + memcpy( lpmii, &mii, mii.cbSize); + return ret; } - /* * @implemented */ @@ -4492,39 +5095,21 @@ GetMenuState( UINT uId, UINT uFlags) { - ROSMENUINFO MenuInfo; - ROSMENUITEMINFO mii; - memset( &mii, 0, sizeof(mii) ); - mii.cbSize = sizeof(MENUITEMINFOW); - mii.fMask = MIIM_STATE | MIIM_FTYPE | MIIM_SUBMENU; + PITEM pItem; + TRACE("(menu=%p, id=%04x, flags=%04x);\n", hMenu, uId, uFlags); + if (!(pItem = MENU_FindItem( &hMenu, &uId, uFlags ))) return -1; - SetLastError(0); - if(NtUserMenuItemInfo(hMenu, uId, uFlags, &mii, FALSE)) - { - UINT nSubItems = 0; - if(mii.hSubMenu) - { - if (! MenuGetRosMenuInfo(&MenuInfo, mii.hSubMenu)) - { - return (UINT) -1; - } - nSubItems = MenuInfo.MenuItemCount; - - /* FIXME - ported from wine, does that work (0xff)? */ - if(GetLastError() != ERROR_INVALID_MENU_HANDLE) - return (nSubItems << 8) | ((mii.fState | mii.fType) & 0xff); - - return (UINT)-1; /* Invalid submenu */ - } - - /* FIXME - ported from wine, does that work? */ - return (mii.fType | mii.fState); - } - - return (UINT)-1; + if (pItem->spSubMenu) + { + PMENU pSubMenu = DesktopPtrToUser(pItem->spSubMenu); + HMENU hsubmenu = UserHMGetHandle(pSubMenu); + if (!IsMenu(hsubmenu)) return (UINT)-1; + else return (pSubMenu->cItems << 8) | ((pItem->fState|pItem->fType) & 0xff); + } + else + return (pItem->fType | pItem->fState); } - /* * @implemented */ @@ -4537,11 +5122,10 @@ GetMenuStringA( int nMaxCount, UINT uFlag) { - MENUITEMINFOA mii; +/* MENUITEMINFOA mii; memset( &mii, 0, sizeof(mii) ); mii.dwTypeData = lpString; - mii.fMask = MIIM_STRING | MIIM_FTYPE; - mii.fType = MFT_STRING; + mii.fMask = MIIM_STRING; mii.cbSize = sizeof(MENUITEMINFOA); mii.cch = nMaxCount; @@ -4549,8 +5133,29 @@ GetMenuStringA( return 0; else return mii.cch; -} +*/ + ITEM *item; + LPWSTR text; + ////// wine Code, seems to be faster. + TRACE("menu=%p item=%04x ptr=%p len=%d flags=%04x\n", hMenu, uIDItem, lpString, nMaxCount, uFlag ); + if (lpString && nMaxCount) lpString[0] = '\0'; + + if (!(item = MENU_FindItem( &hMenu, &uIDItem, uFlag ))) + { + SetLastError( ERROR_MENU_ITEM_NOT_FOUND); + return 0; + } + + text = item->Xlpstr ? DesktopPtrToUser(item->Xlpstr) : NULL; + + if (!text) return 0; + if (!lpString || !nMaxCount) return WideCharToMultiByte( CP_ACP, 0, text, -1, NULL, 0, NULL, NULL ); + if (!WideCharToMultiByte( CP_ACP, 0, text, -1, lpString, nMaxCount, NULL, NULL )) + lpString[nMaxCount-1] = 0; + ERR("returning %s\n", lpString); + return strlen(lpString); +} /* * @implemented @@ -4564,7 +5169,7 @@ GetMenuStringW( int nMaxCount, UINT uFlag) { - MENUITEMINFOW miiW; +/* MENUITEMINFOW miiW; memset( &miiW, 0, sizeof(miiW) ); miiW.dwTypeData = lpString; miiW.fMask = MIIM_STRING | MIIM_FTYPE; @@ -4576,8 +5181,32 @@ GetMenuStringW( return 0; else return miiW.cch; -} +*/ + ITEM *item; + LPWSTR text; + TRACE("menu=%p item=%04x ptr=%p len=%d flags=%04x\n", hMenu, uIDItem, lpString, nMaxCount, uFlag ); + + if (lpString && nMaxCount) lpString[0] = '\0'; + + if (!(item = MENU_FindItem( &hMenu, &uIDItem, uFlag ))) + { + SetLastError( ERROR_MENU_ITEM_NOT_FOUND); + return 0; + } + + text = item->Xlpstr ? DesktopPtrToUser(item->Xlpstr) : NULL; + + if (!lpString || !nMaxCount) return text ? strlenW(text) : 0; + if( !(text)) + { + lpString[0] = 0; + return 0; + } + lstrcpynW( lpString, text, nMaxCount ); + ERR("returning %S\n", lpString); + return strlenW(lpString); +} /* * @implemented @@ -4588,16 +5217,15 @@ GetSubMenu( HMENU hMenu, int nPos) { - ROSMENUITEMINFO mi; - - mi.cbSize = sizeof(MENUITEMINFOW); - mi.fMask = MIIM_SUBMENU; - - if (NtUserMenuItemInfo(hMenu, (UINT)nPos, MF_BYPOSITION, &mi, FALSE)) - { - return IsMenu(mi.hSubMenu) ? mi.hSubMenu : NULL; - } + PITEM pItem; + if (!(pItem = MENU_FindItem( &hMenu, (UINT*)&nPos, MF_BYPOSITION ))) return NULL; + if (pItem->spSubMenu) + { + PMENU pSubMenu = DesktopPtrToUser(pItem->spSubMenu); + HMENU hsubmenu = UserHMGetHandle(pSubMenu); + if (IsMenu(hsubmenu)) return hsubmenu; + } return NULL; } @@ -4617,7 +5245,6 @@ GetSystemMenu( return NULL == TopMenu ? NULL : GetSubMenu(TopMenu, 0); } - /* * @implemented */ @@ -4644,8 +5271,6 @@ InsertMenuA( return InsertMenuItemA(hMenu, uPosition, (BOOL)((MF_BYPOSITION & uFlags) > 0), &mii); } - - /* * @implemented */ @@ -4657,43 +5282,38 @@ InsertMenuItemA( BOOL fByPosition, LPCMENUITEMINFOA lpmii) { - MENUITEMINFOW mi; - UNICODE_STRING MenuText; - BOOL res = FALSE; - BOOL CleanHeap = FALSE; + MENUITEMINFOW mii; + UNICODE_STRING UnicodeString; + BOOL res; - if((lpmii->cbSize == sizeof(MENUITEMINFOA)) || - (lpmii->cbSize == sizeof(MENUITEMINFOA) - sizeof(HBITMAP))) + TRACE("hmenu %p, item %04x, by pos %d, info %p\n", hMenu, uItem, fByPosition, lpmii); + + RtlInitUnicodeString(&UnicodeString, 0); + + if (!MENU_NormalizeMenuItemInfoStruct( (const MENUITEMINFOW *)lpmii, &mii )) return FALSE; + + /* copy the text string */ + if (((mii.fMask & MIIM_STRING) || + ((mii.fMask & MIIM_TYPE) && (MENU_ITEM_TYPE(mii.fType) == MF_STRING))) + && mii.dwTypeData && !(GdiValidateHandle((HGDIOBJ)mii.dwTypeData)) ) { - RtlCopyMemory ( &mi, lpmii, lpmii->cbSize ); - - if( lpmii->cbSize != sizeof( MENUITEMINFOW)) - { - mi.cbSize = sizeof( MENUITEMINFOW); - mi.hbmpItem = NULL; - } - /* copy the text string */ - if (((mi.fMask & MIIM_STRING) || - ((mi.fMask & MIIM_TYPE) && (MENU_ITEM_TYPE(mi.fType) == MF_STRING))) - && mi.dwTypeData != NULL) - { - if (!RtlCreateUnicodeStringFromAsciiz(&MenuText, (LPSTR)mi.dwTypeData)) + if (!RtlCreateUnicodeStringFromAsciiz(&UnicodeString, (LPSTR)mii.dwTypeData)) { SetLastError (ERROR_NOT_ENOUGH_MEMORY); return FALSE; } - mi.dwTypeData = MenuText.Buffer; - mi.cch = MenuText.Length / sizeof(WCHAR); - CleanHeap = TRUE; - } - res = NtUserThunkedMenuItemInfo(hMenu, uItem, fByPosition, TRUE, &mi, NULL); - - if ( CleanHeap ) RtlFreeUnicodeString ( &MenuText ); + mii.dwTypeData = UnicodeString.Buffer; + mii.cch = UnicodeString.Length / sizeof(WCHAR); } + else + { + UnicodeString.Buffer = NULL; + } + res = NtUserThunkedMenuItemInfo(hMenu, uItem, fByPosition, TRUE, &mii, &UnicodeString); + if ( UnicodeString.Buffer ) RtlFreeUnicodeString ( &UnicodeString ); return res; } - /* * @implemented */ @@ -4705,7 +5325,7 @@ InsertMenuItemW( BOOL fByPosition, LPCMENUITEMINFOW lpmii) { - MENUITEMINFOW mi; + MENUITEMINFOW mii; UNICODE_STRING MenuText; BOOL res = FALSE; @@ -4713,31 +5333,25 @@ InsertMenuItemW( if a bad user passes bad data, we crash his process instead of the entire kernel */ - if((lpmii->cbSize == sizeof(MENUITEMINFOW)) || - (lpmii->cbSize == sizeof(MENUITEMINFOW) - sizeof(HBITMAP))) - { - RtlCopyMemory(&mi, lpmii, lpmii->cbSize); + TRACE("hmenu %p, item %04x, by pos %d, info %p\n", hMenu, uItem, fByPosition, lpmii); - if( lpmii->cbSize != sizeof( MENUITEMINFOW)) - { - mi.cbSize = sizeof( MENUITEMINFOW); - mi.hbmpItem = NULL; - } - /* copy the text string */ - if (((mi.fMask & MIIM_STRING) || - ((mi.fMask & MIIM_TYPE) && (MENU_ITEM_TYPE(mi.fType) == MF_STRING))) - && mi.dwTypeData != NULL) - { - RtlInitUnicodeString(&MenuText, (PWSTR)lpmii->dwTypeData); - mi.dwTypeData = MenuText.Buffer; - mi.cch = MenuText.Length / sizeof(WCHAR); - } - res = NtUserThunkedMenuItemInfo(hMenu, uItem, fByPosition, TRUE, &mi, NULL); + RtlInitUnicodeString(&MenuText, 0); + + if (!MENU_NormalizeMenuItemInfoStruct( (const MENUITEMINFOW *)lpmii, &mii )) return FALSE; + + /* copy the text string */ + if (((mii.fMask & MIIM_STRING) || + ((mii.fMask & MIIM_TYPE) && (MENU_ITEM_TYPE(mii.fType) == MF_STRING))) + && mii.dwTypeData && !(GdiValidateHandle((HGDIOBJ)mii.dwTypeData)) ) + { + RtlInitUnicodeString(&MenuText, (PWSTR)lpmii->dwTypeData); + mii.dwTypeData = MenuText.Buffer; + mii.cch = MenuText.Length / sizeof(WCHAR); } + res = NtUserThunkedMenuItemInfo(hMenu, uItem, fByPosition, TRUE, &mii, &MenuText); return res; } - /* * @implemented */ @@ -4764,7 +5378,6 @@ InsertMenuW( return InsertMenuItemW(hMenu, uPosition, (BOOL)((MF_BYPOSITION & uFlags) > 0), &mii); } - /* * @implemented */ @@ -4777,7 +5390,6 @@ IsMenu( return FALSE; } - /* * @implemented */ @@ -4793,7 +5405,6 @@ LoadMenuA(HINSTANCE hInstance, return(LoadMenuIndirectA((PVOID)LoadResource(hInstance, Resource))); } - /* * @implemented */ @@ -4803,7 +5414,6 @@ LoadMenuIndirectA(CONST MENUTEMPLATE *lpMenuTemplate) return(LoadMenuIndirectW(lpMenuTemplate)); } - /* * @implemented */ @@ -4845,7 +5455,6 @@ LoadMenuIndirectW(CONST MENUTEMPLATE *lpMenuTemplate) } } - /* * @implemented */ @@ -4861,7 +5470,6 @@ LoadMenuW(HINSTANCE hInstance, return(LoadMenuIndirectW((PVOID)LoadResource(hInstance, Resource))); } - /* * @implemented */ @@ -4875,7 +5483,6 @@ MenuItemFromPoint( return NtUserMenuItemFromPoint(hWnd, hMenu, ptScreen.x, ptScreen.y); } - /* * @implemented */ @@ -4888,41 +5495,26 @@ ModifyMenuA( UINT_PTR uIDNewItem, LPCSTR lpNewItem) { - ROSMENUINFO mi; - ROSMENUITEMINFO rmii; MENUITEMINFOA mii; memset( &mii, 0, sizeof(mii) ); - mii.cbSize = sizeof(MENUITEMINFOA); + mii.cbSize = sizeof(MENUITEMINFOA); mii.fMask = MIIM_FTYPE; - if (!MenuGetRosMenuInfo( &mi, hMnu )) return FALSE; - - mi.Height = 0; - - if (!MenuSetRosMenuInfo( &mi )) return FALSE; - - MenuInitRosMenuItemInfo( &rmii ); - - if(!MenuGetRosMenuItemInfo( hMnu, uPosition, &rmii)) return FALSE; - - if (rmii.hSubMenu && (uFlags & MF_POPUP) && (rmii.hSubMenu != (HMENU)uIDNewItem)) - NtUserDestroyMenu( rmii.hSubMenu ); /* ModifyMenu() spec */ - - MenuCleanupRosMenuItemInfo( &rmii ); - MenuSetItemData((LPMENUITEMINFOW) &mii, uFlags, uIDNewItem, (LPCWSTR) lpNewItem, FALSE); + //if (mii.hSubMenu && (uFlags & MF_POPUP) && (mii.hSubMenu != (HMENU)uIDNewItem)) + // NtUserDestroyMenu( mii.hSubMenu ); /* ModifyMenu() spec */ + return SetMenuItemInfoA( hMnu, uPosition, (BOOL)(MF_BYPOSITION & uFlags), &mii); } - /* * @implemented */ @@ -4935,28 +5527,11 @@ ModifyMenuW( UINT_PTR uIDNewItem, LPCWSTR lpNewItem) { - ROSMENUINFO mi; - ROSMENUITEMINFO rmii; MENUITEMINFOW mii; memset ( &mii, 0, sizeof(mii) ); mii.cbSize = sizeof(MENUITEMINFOW); mii.fMask = MIIM_FTYPE; - if (!MenuGetRosMenuInfo( &mi, hMnu )) return FALSE; - - mi.Height = 0; // Force size recalculation. - - if (!MenuSetRosMenuInfo( &mi )) return FALSE; - - MenuInitRosMenuItemInfo( &rmii ); - - if(!MenuGetRosMenuItemInfo( hMnu, uPosition, &rmii)) return FALSE; - - if (rmii.hSubMenu && (uFlags & MF_POPUP) && (rmii.hSubMenu != (HMENU)uIDNewItem)) - NtUserDestroyMenu( rmii.hSubMenu ); /* ModifyMenu() spec */ - - MenuCleanupRosMenuItemInfo( &rmii ); - /* Init new data for this menu item */ MenuSetItemData( &mii, uFlags, @@ -4964,14 +5539,15 @@ ModifyMenuW( lpNewItem, TRUE); - /* Now, make Win32k IntSetMenuItemInfo handle the changes to this menu item. */ + //if (mii.hSubMenu && (uFlags & MF_POPUP) && (mii.hSubMenu != (HMENU)uIDNewItem)) + // NtUserDestroyMenu( mii.hSubMenu ); /* ModifyMenu() spec */ + return SetMenuItemInfoW( hMnu, uPosition, (BOOL)(MF_BYPOSITION & uFlags), &mii); } - /* * @implemented */ @@ -4982,7 +5558,6 @@ SetMenu(HWND hWnd, return NtUserSetMenu(hWnd, hMenu, TRUE); } - /* * @implemented */ @@ -5002,10 +5577,9 @@ SetMenuInfo( } memcpy(&mi, lpcmi, sizeof(MENUINFO)); - return NtUserMenuInfo(hmenu, &mi, TRUE); + return NtUserThunkedMenuInfo(hmenu, (LPCMENUINFO)&mi); } - /* * @implemented */ @@ -5018,88 +5592,63 @@ SetMenuItemBitmaps( HBITMAP hBitmapUnchecked, HBITMAP hBitmapChecked) { - ROSMENUITEMINFO uItem; + MENUITEMINFOW uItem; memset ( &uItem, 0, sizeof(uItem) ); - uItem.fMask = MIIM_STATE | MIIM_BITMAP; - - if(!(NtUserMenuItemInfo(hMenu, uPosition, - (BOOL)(MF_BYPOSITION & uFlags), &uItem, FALSE))) return FALSE; - - if (!hBitmapChecked && !hBitmapUnchecked) - { - uItem.fState &= ~MF_USECHECKBITMAPS; - } - else /* Install new bitmaps */ - { - uItem.hbmpChecked = hBitmapChecked; - uItem.hbmpUnchecked = hBitmapUnchecked; - uItem.fState |= MF_USECHECKBITMAPS; - } - return NtUserMenuItemInfo(hMenu, uPosition, - (BOOL)(MF_BYPOSITION & uFlags), &uItem, TRUE); + uItem.cbSize = sizeof(MENUITEMINFOW); + uItem.fMask = MIIM_CHECKMARKS; + uItem.hbmpUnchecked = hBitmapUnchecked; + uItem.hbmpChecked = hBitmapChecked; + return SetMenuItemInfoW(hMenu, uPosition, (BOOL)(uFlags & MF_BYPOSITION), &uItem); } - /* * @implemented */ BOOL WINAPI SetMenuItemInfoA( - HMENU hMenu, - UINT uItem, - BOOL fByPosition, + HMENU hmenu, + UINT item, + BOOL bypos, LPCMENUITEMINFOA lpmii) { - MENUITEMINFOW MenuItemInfoW; + MENUITEMINFOW mii; UNICODE_STRING UnicodeString; - ULONG Result = FALSE; + BOOL Ret; - RtlCopyMemory(&MenuItemInfoW, lpmii, min(lpmii->cbSize, sizeof(MENUITEMINFOW))); + TRACE("hmenu %p, item %u, by pos %d, info %p\n", hmenu, item, bypos, lpmii); - if( lpmii->cbSize != sizeof( MENUITEMINFOW)) - { - MenuItemInfoW.cbSize = sizeof( MENUITEMINFOW); - MenuItemInfoW.hbmpItem = NULL; - } + RtlInitUnicodeString(&UnicodeString, 0); + + if (!MENU_NormalizeMenuItemInfoStruct( (const MENUITEMINFOW *)lpmii, &mii )) return FALSE; /* * MIIM_STRING == good * MIIM_TYPE & MFT_STRING == good * MIIM_STRING & MFT_STRING == good - * MIIM_STRING & MFT_OWNERSRAW == good + * MIIM_STRING & MFT_OWNERDRAW == good */ - if (((MenuItemInfoW.fMask & MIIM_STRING) || - ((MenuItemInfoW.fMask & MIIM_TYPE) && - (MENU_ITEM_TYPE(MenuItemInfoW.fType) == MF_STRING))) - && MenuItemInfoW.dwTypeData != NULL) + if (((mii.fMask & MIIM_STRING) || + ((mii.fMask & MIIM_TYPE) && (MENU_ITEM_TYPE(mii.fType) == MF_STRING))) + && mii.dwTypeData && !(GdiValidateHandle((HGDIOBJ)mii.dwTypeData)) ) { -/* cch is ignored when the content of a menu item is set by calling SetMenuItemInfo. */ - if (!RtlCreateUnicodeStringFromAsciiz(&UnicodeString, - (LPSTR)MenuItemInfoW.dwTypeData)) - { + /* cch is ignored when the content of a menu item is set by calling SetMenuItemInfo. */ + if (!RtlCreateUnicodeStringFromAsciiz(&UnicodeString, (LPSTR)mii.dwTypeData)) + { SetLastError (ERROR_NOT_ENOUGH_MEMORY); return FALSE; - } - MenuItemInfoW.dwTypeData = UnicodeString.Buffer; - MenuItemInfoW.cch = UnicodeString.Length / sizeof(WCHAR); + } + mii.dwTypeData = UnicodeString.Buffer; + mii.cch = UnicodeString.Length / sizeof(WCHAR); } else { - UnicodeString.Buffer = NULL; + UnicodeString.Buffer = NULL; } - - Result = NtUserMenuItemInfo(hMenu, uItem, fByPosition, - (PROSMENUITEMINFO)&MenuItemInfoW, TRUE); - - if (UnicodeString.Buffer != NULL) - { - RtlFreeUnicodeString(&UnicodeString); - } - - return Result; + Ret = NtUserThunkedMenuItemInfo(hmenu, item, bypos, FALSE, &mii, &UnicodeString); + if (UnicodeString.Buffer != NULL) RtlFreeUnicodeString(&UnicodeString); + return Ret; } - /* * @implemented */ @@ -5112,27 +5661,26 @@ SetMenuItemInfoW( LPCMENUITEMINFOW lpmii) { MENUITEMINFOW MenuItemInfoW; - ULONG Result; + UNICODE_STRING UnicodeString; + BOOL Ret; - RtlCopyMemory(&MenuItemInfoW, lpmii, min(lpmii->cbSize, sizeof(MENUITEMINFOW))); + TRACE("hmenu %p, item %u, by pos %d, info %p\n", hMenu, uItem, fByPosition, lpmii); - if( lpmii->cbSize != sizeof( MENUITEMINFOW)) - { - MenuItemInfoW.cbSize = sizeof( MENUITEMINFOW); - MenuItemInfoW.hbmpItem = NULL; - } + RtlInitUnicodeString(&UnicodeString, 0); + + if (!MENU_NormalizeMenuItemInfoStruct( (const MENUITEMINFOW *)lpmii, &MenuItemInfoW )) return FALSE; if (((MenuItemInfoW.fMask & MIIM_STRING) || ((MenuItemInfoW.fMask & MIIM_TYPE) && (MENU_ITEM_TYPE(MenuItemInfoW.fType) == MF_STRING))) - && MenuItemInfoW.dwTypeData != NULL) + && MenuItemInfoW.dwTypeData && !(GdiValidateHandle((HGDIOBJ)MenuItemInfoW.dwTypeData)) ) { - MenuItemInfoW.cch = strlenW(MenuItemInfoW.dwTypeData); + RtlInitUnicodeString(&UnicodeString, (PCWSTR)MenuItemInfoW.dwTypeData); + MenuItemInfoW.cch = strlenW(MenuItemInfoW.dwTypeData); } - Result = NtUserMenuItemInfo(hMenu, uItem, fByPosition, - (PROSMENUITEMINFO)&MenuItemInfoW, TRUE); + Ret = NtUserThunkedMenuItemInfo(hMenu, uItem, fByPosition, FALSE, &MenuItemInfoW, &UnicodeString); - return Result; + return Ret; } /* @@ -5182,23 +5730,6 @@ NEWTrackPopupMenu( } -/* - * @implemented - */ -DWORD -WINAPI -GetMenuContextHelpId(HMENU hmenu) -{ - ROSMENUINFO mi; - mi.cbSize = sizeof(ROSMENUINFO); - mi.fMask = MIM_HELPID; - - if(NtUserMenuInfo(hmenu, &mi, FALSE)) - { - return mi.dwContextHelpID; - } - return 0; -} /* * @unimplemented @@ -5331,7 +5862,3 @@ ChangeMenuA( }; } - - - - diff --git a/win32ss/user/user32/windows/window.c b/win32ss/user/user32/windows/window.c index 452237951ee..a2c22c6032b 100644 --- a/win32ss/user/user32/windows/window.c +++ b/win32ss/user/user32/windows/window.c @@ -120,8 +120,8 @@ CloseWindow(HWND hWnd) return HandleToUlong(hWnd); } -VOID FORCEINLINE +VOID RtlInitLargeString( OUT PLARGE_STRING plstr, LPCVOID psz, diff --git a/win32ss/user/winsrv/consrv/condrv/coninput.c b/win32ss/user/winsrv/consrv/condrv/coninput.c index 27c6b3670c6..afd6a6420a9 100644 --- a/win32ss/user/winsrv/consrv/condrv/coninput.c +++ b/win32ss/user/winsrv/consrv/condrv/coninput.c @@ -246,7 +246,7 @@ ConDrvReadConsole(IN PCONSOLE Console, NTSTATUS Status = STATUS_PENDING; PLIST_ENTRY CurrentEntry; ConsoleInput *Input; - ULONG i = ReadControl->nInitialChars; + ULONG i; if (Console == NULL || InputBuffer == NULL || /* Buffer == NULL || */ ReadControl == NULL || ReadControl->nLength != sizeof(CONSOLE_READCONSOLE_CONTROL)) @@ -261,6 +261,8 @@ ConDrvReadConsole(IN PCONSOLE Console, /* We haven't read anything (yet) */ + i = ReadControl->nInitialChars; + if (InputBuffer->Mode & ENABLE_LINE_INPUT) { if (Console->LineBuffer == NULL) diff --git a/win32ss/user/winsrv/consrv/condrv/text.c b/win32ss/user/winsrv/consrv/condrv/text.c index da6459d3e7c..d44c9b39786 100644 --- a/win32ss/user/winsrv/consrv/condrv/text.c +++ b/win32ss/user/winsrv/consrv/condrv/text.c @@ -595,8 +595,8 @@ ConDrvChangeScreenBufferAttributes(IN PCONSOLE Console, PCHAR_INFO Ptr; COORD TopLeft = {0}; - ULONG NumCodesToWrite = Buffer->ScreenBufferSize.X * Buffer->ScreenBufferSize.Y; - USHORT OldScreenAttrib = Buffer->ScreenDefaultAttrib; + ULONG NumCodesToWrite; + USHORT OldScreenAttrib; if (Console == NULL || Buffer == NULL) { @@ -606,9 +606,13 @@ ConDrvChangeScreenBufferAttributes(IN PCONSOLE Console, /* Validity check */ ASSERT(Console == Buffer->Header.Console); + NumCodesToWrite = Buffer->ScreenBufferSize.X * Buffer->ScreenBufferSize.Y; + OldScreenAttrib = Buffer->ScreenDefaultAttrib; + X = TopLeft.X; Y = (TopLeft.Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y; Length = NumCodesToWrite; + // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work // Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X]; // May work diff --git a/win32ss/user/winsrv/consrv/settings.c b/win32ss/user/winsrv/consrv/settings.c index ec7042a65e3..7373f04401c 100644 --- a/win32ss/user/winsrv/consrv/settings.c +++ b/win32ss/user/winsrv/consrv/settings.c @@ -156,7 +156,7 @@ ConSrvOpenUserSettings(DWORD ProcessId, TranslateConsoleName(szBuffer2, ConsoleTitle, MAX_PATH); /* Create the registry path */ - wcsncat(szBuffer, szBuffer2, MAX_PATH); + wcsncat(szBuffer, szBuffer2, MAX_PATH - wcslen(szBuffer) - 1); /* Create or open the registry key */ if (bCreate) @@ -351,7 +351,7 @@ do { * or we are saving settings for a particular console, which differs * from the default ones. */ - swprintf(szValueName, L"ColorTable%02d", i); + swprintf(szValueName, L"ColorTable%02u", i); SetConsoleSetting(szValueName, REG_DWORD, sizeof(DWORD), &ConsoleInfo->Colors[i], s_Colors[i]); } diff --git a/win32ss/user/winsrv/consrv_new/settings.c b/win32ss/user/winsrv/consrv_new/settings.c index 738d5bfce3c..f85fe1396c7 100644 --- a/win32ss/user/winsrv/consrv_new/settings.c +++ b/win32ss/user/winsrv/consrv_new/settings.c @@ -355,7 +355,7 @@ do { * or we are saving settings for a particular console, which differs * from the default ones. */ - swprintf(szValueName, L"ColorTable%02d", i); + swprintf(szValueName, L"ColorTable%02u", i); SetConsoleSetting(szValueName, REG_DWORD, sizeof(DWORD), &ConsoleInfo->Colors[i], s_Colors[i]); } diff --git a/win32ss/w32ksvc.db b/win32ss/w32ksvc.db index e5330ea2b65..58244a95c30 100644 --- a/win32ss/w32ksvc.db +++ b/win32ss/w32ksvc.db @@ -596,7 +596,6 @@ NtUserWaitForInputIdle 3 NtUserWaitForMsgAndEvent 1 NtUserWaitMessage 0 NtUserWin32PoolAllocationStats 6 -NtUserWindowFromPhysicalPoint 2 NtUserWindowFromPoint 2 NtUserYieldTask 0 NtUserRemoteConnect 3 @@ -681,11 +680,7 @@ NtGdiGetFontFamilyInfo 4 NtGdiOffsetViewportOrgEx 4 NtGdiOffsetWindowOrgEx 4 # -NtUserBuildMenuItemList 4 -NtUserGetMenuDefaultItem 3 NtUserGetMonitorInfo 2 -NtUserMenuInfo 3 -NtUserMenuItemInfo 5 NtUserMonitorFromPoint 3 NtUserMonitorFromRect 2 NtUserMonitorFromWindow 2 diff --git a/win32ss/w32ksvc.h b/win32ss/w32ksvc.h index daf987312c7..a780e82a0b0 100644 --- a/win32ss/w32ksvc.h +++ b/win32ss/w32ksvc.h @@ -603,7 +603,6 @@ SVC_(UserWaitForInputIdle, 3) SVC_(UserWaitForMsgAndEvent, 1) SVC_(UserWaitMessage, 0) SVC_(UserWin32PoolAllocationStats, 6) -SVC_(UserWindowFromPhysicalPoint, 2) SVC_(UserWindowFromPoint, 2) SVC_(UserYieldTask, 0) SVC_(UserRemoteConnect, 3) @@ -688,11 +687,7 @@ SVC_(GdiGetFontFamilyInfo, 4) SVC_(GdiOffsetViewportOrgEx, 4) SVC_(GdiOffsetWindowOrgEx, 4) -SVC_(UserBuildMenuItemList, 4) -SVC_(UserGetMenuDefaultItem, 3) SVC_(UserGetMonitorInfo, 2) -SVC_(UserMenuInfo, 3) -SVC_(UserMenuItemInfo, 5) SVC_(UserMonitorFromPoint, 3) SVC_(UserMonitorFromRect, 2) SVC_(UserMonitorFromWindow, 2)