Sync with trunk r62529.

svn path=/branches/shell-experiments/; revision=62530
This commit is contained in:
David Quintana 2014-03-18 14:39:04 +00:00
commit 64227df624
33 changed files with 1151 additions and 401 deletions

View file

@ -4,6 +4,7 @@ add_subdirectory(find)
add_subdirectory(help)
add_subdirectory(hostname)
add_subdirectory(lodctr)
add_subdirectory(mode)
add_subdirectory(more)
add_subdirectory(reg)
add_subdirectory(taskkill)

View file

@ -2,7 +2,7 @@
#include "doskey.h"
#define REACTOS_STR_FILE_DESCRIPTION "W32 doskey command"
#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Doskey Command"
#define REACTOS_STR_INTERNAL_NAME "doskey"
#define REACTOS_STR_ORIGINAL_FILENAME "doskey.exe"
#include <reactos/version.rc>

View file

@ -2,7 +2,7 @@
#include "resource.h"
#define REACTOS_STR_FILE_DESCRIPTION "W32 find command"
#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Find Command"
#define REACTOS_STR_INTERNAL_NAME "find"
#define REACTOS_STR_ORIGINAL_FILENAME "find.exe"
#include <reactos/version.rc>

View file

@ -0,0 +1,7 @@
add_executable(mode mode.c mode.rc)
set_module_type(mode win32cui UNICODE)
set_target_properties(mode PROPERTIES SUFFIX ".com")
add_importlibs(mode user32 msvcrt kernel32)
add_cd_file(TARGET mode DESTINATION reactos/system32 FOR all)

View file

@ -0,0 +1,551 @@
/*
* ReactOS mode console command
*
* mode.c
*
* Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <windows.h>
#include <stdio.h>
#define MAX_PORTNAME_LEN 20
#define MAX_COMPORT_NUM 10
#define MAX_COMPARAM_LEN 20
#define NUM_ELEMENTS(a) (sizeof(a)/sizeof(a[0]))
#define ASSERT(a)
const WCHAR* const usage_strings[] =
{
L"Device Status: MODE [device] [/STATUS]",
L"Select code page: MODE CON[:] CP SELECT=yyy",
L"Code page status: MODE CON[:] CP [/STATUS]",
L"Display mode: MODE CON[:] [COLS=c] [LINES=n]",
L"Typematic rate: MODE CON[:] [RATE=r DELAY=d]",
L"Redirect printing: MODE LPTn[:]=COMm[:]",
L"Serial port: MODE COMm[:] [BAUD=b] [PARITY=p] [DATA=d] [STOP=s]\n" \
L" [to=on|off] [xon=on|off] [odsr=on|off]\n" \
L" [octs=on|off] [dtr=on|off|hs]\n" \
L" [rts=on|off|hs|tg] [idsr=on|off]",
};
const WCHAR* const parity_strings[] =
{
L"None", // default
L"Odd", // only symbol in this set to have a 'd' in it
L"Even", // ... 'v' in it
L"Mark", // ... 'm' in it
L"Space" // ... 's' and/or a 'c' in it
};
const WCHAR* const control_strings[] = { L"OFF", L"ON", L"HANDSHAKE", L"TOGGLE" };
const WCHAR* const stopbit_strings[] = { L"1", L"1.5", L"2" };
int Usage()
{
int i;
wprintf(L"\nConfigures system devices.\n\n");
for (i = 0; i < NUM_ELEMENTS(usage_strings); i++)
{
wprintf(L"%s\n", usage_strings[i]);
}
wprintf(L"\n");
return 0;
}
int QueryDevices()
{
WCHAR buffer[20240];
int len;
WCHAR* ptr = buffer;
*ptr = L'\0';
if (QueryDosDeviceW(NULL, buffer, NUM_ELEMENTS(buffer)))
{
while (*ptr != L'\0')
{
len = wcslen(ptr);
if (wcsstr(ptr, L"COM"))
{
wprintf(L" Found serial device - %s\n", ptr);
}
else if (wcsstr(ptr, L"PRN"))
{
wprintf(L" Found printer device - %s\n", ptr);
}
else if (wcsstr(ptr, L"LPT"))
{
wprintf(L" Found parallel device - %s\n", ptr);
}
else
{
// wprintf(L" Found other device - %s\n", ptr);
}
ptr += (len+1);
}
}
else
{
wprintf(L" ERROR: QueryDosDeviceW(...) failed: 0x%lx\n", GetLastError());
}
return 1;
}
int ShowParallelStatus(int nPortNum)
{
WCHAR buffer[250];
WCHAR szPortName[MAX_PORTNAME_LEN];
swprintf(szPortName, L"LPT%d", nPortNum);
wprintf(L"\nStatus for device LPT%d:\n", nPortNum);
wprintf(L"-----------------------\n");
if (QueryDosDeviceW(szPortName, buffer, NUM_ELEMENTS(buffer)))
{
WCHAR* ptr = wcsrchr(buffer, L'\\');
if (ptr != NULL)
{
if (0 == wcscmp(szPortName, ++ptr))
{
wprintf(L" Printer output is not being rerouted.\n");
}
else
{
wprintf(L" Printer output is being rerouted to serial port %s\n", ptr);
}
return 0;
}
else
{
wprintf(L" QueryDosDeviceW(%s) returned unrecognised form %s.\n", szPortName, buffer);
}
}
else
{
wprintf(L" ERROR: QueryDosDeviceW(%s) failed: 0x%lx\n", szPortName, GetLastError());
}
return 1;
}
int ShowConsoleStatus()
{
DWORD dwKbdDelay;
DWORD dwKbdSpeed;
CONSOLE_SCREEN_BUFFER_INFO ConsoleScreenBufferInfo;
HANDLE hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
wprintf(L"\nStatus for device CON:\n");
wprintf(L"-----------------------\n");
if (GetConsoleScreenBufferInfo(hConsoleOutput, &ConsoleScreenBufferInfo))
{
wprintf(L" Lines: %d\n", ConsoleScreenBufferInfo.dwSize.Y);
wprintf(L" Columns: %d\n", ConsoleScreenBufferInfo.dwSize.X);
}
if (SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &dwKbdDelay, 0))
{
wprintf(L" Keyboard delay: %ld\n", dwKbdDelay);
}
if (SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &dwKbdSpeed, 0))
{
wprintf(L" Keyboard rate: %ld\n", dwKbdSpeed);
}
wprintf(L" Code page: %d\n", GetConsoleOutputCP());
return 0;
}
static
BOOL SerialPortQuery(int nPortNum, LPDCB pDCB, LPCOMMTIMEOUTS pCommTimeouts, BOOL bWrite)
{
BOOL result;
HANDLE hPort;
WCHAR szPortName[MAX_PORTNAME_LEN];
ASSERT(pDCB);
ASSERT(pCommTimeouts);
swprintf(szPortName, L"COM%d", nPortNum);
hPort = CreateFileW(szPortName,
GENERIC_READ | GENERIC_WRITE,
0, // exclusive
NULL, // sec attr
OPEN_EXISTING,
0, // no attributes
NULL); // no template
if (hPort == INVALID_HANDLE_VALUE)
{
wprintf(L"Illegal device name - %s\n", szPortName);
wprintf(L"Last error = 0x%lx\n", GetLastError());
return FALSE;
}
result = bWrite ? SetCommState(hPort, pDCB)
: GetCommState(hPort, pDCB);
if (!result)
{
wprintf(L"Failed to %s the status for device COM%d:\n", bWrite ? L"set" : L"get", nPortNum);
CloseHandle(hPort);
return FALSE;
}
result = bWrite ? SetCommTimeouts(hPort, pCommTimeouts)
: GetCommTimeouts(hPort, pCommTimeouts);
if (!result)
{
wprintf(L"Failed to %s Timeout status for device COM%d:\n", bWrite ? L"set" : L"get", nPortNum);
CloseHandle(hPort);
return FALSE;
}
CloseHandle(hPort);
return TRUE;
}
int ShowSerialStatus(int nPortNum)
{
DCB dcb;
COMMTIMEOUTS CommTimeouts;
if (!SerialPortQuery(nPortNum, &dcb, &CommTimeouts, FALSE))
{
return 1;
}
if (dcb.Parity > NUM_ELEMENTS(parity_strings))
{
wprintf(L"ERROR: Invalid value for Parity Bits %d:\n", dcb.Parity);
dcb.Parity = 0;
}
if (dcb.StopBits > NUM_ELEMENTS(stopbit_strings))
{
wprintf(L"ERROR: Invalid value for Stop Bits %d:\n", dcb.StopBits);
dcb.StopBits = 0;
}
wprintf(L"\nStatus for device COM%d:\n", nPortNum);
wprintf(L"-----------------------\n");
wprintf(L" Baud: %ld\n", dcb.BaudRate);
wprintf(L" Parity: %s\n", parity_strings[dcb.Parity]);
wprintf(L" Data Bits: %d\n", dcb.ByteSize);
wprintf(L" Stop Bits: %s\n", stopbit_strings[dcb.StopBits]);
wprintf(L" Timeout: %s\n", CommTimeouts.ReadIntervalTimeout ? L"ON" : L"OFF");
wprintf(L" XON/XOFF: %s\n", dcb.fOutX ? L"ON" : L"OFF");
wprintf(L" CTS handshaking: %s\n", dcb.fOutxCtsFlow ? L"ON" : L"OFF");
wprintf(L" DSR handshaking: %s\n", dcb.fOutxDsrFlow ? L"ON" : L"OFF");
wprintf(L" DSR sensitivity: %s\n", dcb.fDsrSensitivity ? L"ON" : L"OFF");
wprintf(L" DTR circuit: %s\n", control_strings[dcb.fDtrControl]);
wprintf(L" RTS circuit: %s\n", control_strings[dcb.fRtsControl]);
return 0;
}
int SetParallelState(int nPortNum)
{
WCHAR szPortName[MAX_PORTNAME_LEN];
WCHAR szTargetPath[MAX_PORTNAME_LEN];
swprintf(szPortName, L"LPT%d", nPortNum);
swprintf(szTargetPath, L"COM%d", nPortNum);
if (!DefineDosDeviceW(DDD_REMOVE_DEFINITION, szPortName, szTargetPath))
{
wprintf(L"SetParallelState(%d) - DefineDosDevice(%s) failed: 0x%lx\n", nPortNum, szPortName, GetLastError());
}
return 0;
}
/*
\??\COM1
\Device\NamedPipe\Spooler\LPT1
BOOL DefineDosDevice(
DWORD dwFlags, // options
LPCTSTR lpDeviceName, // device name
LPCTSTR lpTargetPath // path string
);
DWORD QueryDosDevice(
LPCTSTR lpDeviceName, // MS-DOS device name string
LPTSTR lpTargetPath, // query results buffer
DWORD ucchMax // maximum size of buffer
);
*/
int SetConsoleState()
{
/*
"Select code page: MODE CON[:] CP SELECT=yyy",
"Code page status: MODE CON[:] CP [/STATUS]",
"Display mode: MODE CON[:] [COLS=c] [LINES=n]",
"Typematic rate: MODE CON[:] [RATE=r DELAY=d]",
*/
return 0;
}
static
int ExtractModeSerialParams(const WCHAR* param)
{
if (wcsstr(param, L"OFF"))
return 0;
else if (wcsstr(param, L"ON"))
return 1;
else if (wcsstr(param, L"HS"))
return 2;
else if (wcsstr(param, L"TG"))
return 3;
return -1;
}
int SetSerialState(int nPortNum, int args, WCHAR *argv[])
{
int arg;
int value;
DCB dcb;
COMMTIMEOUTS CommTimeouts;
WCHAR buf[MAX_COMPARAM_LEN+1];
if (SerialPortQuery(nPortNum, &dcb, &CommTimeouts, FALSE))
{
for (arg = 2; arg < args; arg++)
{
if (wcslen(argv[arg]) > MAX_COMPARAM_LEN)
{
wprintf(L"Invalid parameter (too long) - %s\n", argv[arg]);
return 1;
}
wcscpy(buf, argv[arg]);
_wcslwr(buf);
if (wcsstr(buf, L"baud="))
{
wscanf(buf+5, L"%lu", &dcb.BaudRate);
}
else if (wcsstr(buf, L"parity="))
{
if (wcschr(buf, L'D'))
dcb.Parity = 1;
else if (wcschr(buf, L'V'))
dcb.Parity = 2;
else if (wcschr(buf, L'M'))
dcb.Parity = 3;
else if (wcschr(buf, L'S'))
dcb.Parity = 4;
else
dcb.Parity = 0;
}
else if (wcsstr(buf, L"data="))
{
wscanf(buf+5, L"%lu", &dcb.ByteSize);
}
else if (wcsstr(buf, L"stop="))
{
if (wcschr(buf, L'5'))
dcb.StopBits = 1;
else if (wcschr(buf, L'2'))
dcb.StopBits = 2;
else
dcb.StopBits = 0;
}
else if (wcsstr(buf, L"to=")) // to=on|off
{
value = ExtractModeSerialParams(buf);
if (value != -1)
{
}
else
{
goto invalid_serial_parameter;
}
}
else if (wcsstr(buf, L"xon=")) // xon=on|off
{
value = ExtractModeSerialParams(buf);
if (value != -1)
{
dcb.fOutX = value;
dcb.fInX = value;
}
else
{
goto invalid_serial_parameter;
}
}
else if (wcsstr(buf, L"odsr=")) // odsr=on|off
{
value = ExtractModeSerialParams(buf);
if (value != -1)
{
dcb.fOutxDsrFlow = value;
}
else
{
goto invalid_serial_parameter;
}
}
else if (wcsstr(buf, L"octs=")) // octs=on|off
{
value = ExtractModeSerialParams(buf);
if (value != -1)
{
dcb.fOutxCtsFlow = value;
}
else
{
goto invalid_serial_parameter;
}
}
else if (wcsstr(buf, L"dtr=")) // dtr=on|off|hs
{
value = ExtractModeSerialParams(buf);
if (value != -1)
{
dcb.fDtrControl = value;
}
else
{
goto invalid_serial_parameter;
}
}
else if (wcsstr(buf, L"rts=")) // rts=on|off|hs|tg
{
value = ExtractModeSerialParams(buf);
if (value != -1)
{
dcb.fRtsControl = value;
}
else
{
goto invalid_serial_parameter;
}
}
else if (wcsstr(buf, L"idsr=")) // idsr=on|off
{
value = ExtractModeSerialParams(buf);
if (value != -1)
{
dcb.fDsrSensitivity = value;
}
else
{
goto invalid_serial_parameter;
}
}
else
{
invalid_serial_parameter:;
wprintf(L"Invalid parameter - %s\n", buf);
return 1;
}
}
SerialPortQuery(nPortNum, &dcb, &CommTimeouts, TRUE);
}
return 0;
}
int find_portnum(const WCHAR* cmdverb)
{
int portnum = -1;
if (cmdverb[3] >= L'0' && cmdverb[3] <= L'9')
{
portnum = cmdverb[3] - L'0';
if (cmdverb[4] >= L'0' && cmdverb[4] <= L'9')
{
portnum *= 10;
portnum += cmdverb[4] - L'0';
}
}
return portnum;
}
int wmain(int argc, WCHAR* argv[])
{
int nPortNum;
WCHAR param1[MAX_COMPARAM_LEN+1];
WCHAR param2[MAX_COMPARAM_LEN+1];
if (argc > 1)
{
if (wcslen(argv[1]) > MAX_COMPARAM_LEN)
{
wprintf(L"Invalid parameter (too long) - %s\n", argv[1]);
return 1;
}
wcscpy(param1, argv[1]);
_wcslwr(param1);
if (argc > 2)
{
if (wcslen(argv[2]) > MAX_COMPARAM_LEN)
{
wprintf(L"Invalid parameter (too long) - %s\n", argv[2]);
return 1;
}
wcscpy(param2, argv[2]);
_wcslwr(param2);
}
else
{
param2[0] = L'\0';
}
if (wcsstr(param1, L"/?") || wcsstr(param1, L"-?"))
{
return Usage();
}
else if (wcsstr(param1, L"/status"))
{
goto show_status;
}
else if (wcsstr(param1, L"lpt"))
{
nPortNum = find_portnum(param1);
if (nPortNum != -1)
return ShowParallelStatus(nPortNum);
}
else if (wcsstr(param1, L"con"))
{
return ShowConsoleStatus();
}
else if (wcsstr(param1, L"com"))
{
nPortNum = find_portnum(param1);
if (nPortNum != -1)
{
if (param2[0] == L'\0' || wcsstr(param2, L"/status"))
{
return ShowSerialStatus(nPortNum);
}
else
{
return SetSerialState(nPortNum, argc, argv);
}
}
}
wprintf(L"Invalid parameter - %s\n", param1);
return 1;
}
else
{
show_status:;
QueryDevices();
/*
ShowParallelStatus(1);
for (nPortNum = 0; nPortNum < MAX_COMPORT_NUM; nPortNum++)
{
ShowSerialStatus(nPortNum + 1);
}
ShowConsoleStatus();
*/
}
return 0;
}

View file

@ -0,0 +1,5 @@
#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Mode Utility"
#define REACTOS_STR_INTERNAL_NAME "mode"
#define REACTOS_STR_ORIGINAL_FILENAME "mode.com"
#include <reactos/version.rc>

View file

@ -1,5 +1,7 @@
add_executable(more more.c more.rc)
set_module_type(more win32cui)
set_target_properties(more PROPERTIES SUFFIX ".com")
add_importlibs(more user32 msvcrt kernel32)
add_cd_file(TARGET more DESTINATION reactos/system32 FOR all)

View file

@ -2,9 +2,9 @@
#include "resource.h"
#define REACTOS_STR_FILE_DESCRIPTION "W32 more command"
#define REACTOS_STR_FILE_DESCRIPTION "ReactOS More Command"
#define REACTOS_STR_INTERNAL_NAME "more"
#define REACTOS_STR_ORIGINAL_FILENAME "more.exe"
#define REACTOS_STR_ORIGINAL_FILENAME "more.com"
#include <reactos/version.rc>
/* UTF-8 */

View file

@ -20,7 +20,7 @@
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
#define REACTOS_STR_FILE_DESCRIPTION "xcopy command"
#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Xcopy Command"
#define REACTOS_STR_INTERNAL_NAME "xcopy"
#define REACTOS_STR_ORIGINAL_FILENAME "xcopy.exe"
#include <reactos/version.rc>

View file

@ -182,7 +182,7 @@ ajustes previos anteponiendo a cualquier modificador - (hyphen)--por ejemplo, /-
STRING_DIR_HELP3 " El volumen en la unidad %c no tiene etiqueta.\n"
STRING_DIR_HELP4 " El volumen Serial Number is %04X-%04X\n"
STRING_DIR_HELP5 "\n Total de archivos mostrados:\n%16i archivo(s)% 14s bytes\n"
STRING_DIR_HELP6 "%16i Directorio(s)% 15s bytes\n"
STRING_DIR_HELP6 "%16i Directorio(s)% 15s bytes libres\n"
STRING_DIR_HELP7 "\n Directorio %s\n\n"
STRING_DIR_HELP8 "%16i archivo(s)% 14s bytes\n"
STRING_DIRSTACK_HELP1 "Almacena el directorio actual para usarlo por el comando, \n\

View file

@ -192,7 +192,7 @@ Modifier les paramètres mémorisés avec un - (tiret)--par exemple, /-W.\n"
STRING_DIR_HELP3 " Le lecteur %c n'a pas de nom de volume\n"
STRING_DIR_HELP4 " Le numéro de série du volume est %04X-%04X\n"
STRING_DIR_HELP5 "\n Total de fichiers listés :\n%16i Fichier(s)% 14s octets\n"
STRING_DIR_HELP6 "%16i Rep(s)% 15s octets\n"
STRING_DIR_HELP6 "%16i Rep(s)% 15s octets libres\n"
STRING_DIR_HELP7 "\n Répertoire de %s\n\n"
STRING_DIR_HELP8 "%16i Fichier(s)% 14s octets\n"
STRING_DIRSTACK_HELP1 "Stocke le répertoire courant pour utilisation avec la commande POPD,\n\

View file

@ -170,7 +170,7 @@ A kapcsolók a DIRCMD környezeti változóban is lehetnek.\n"
STRING_DIR_HELP3 " A (%c) meghajtóban található kötetnek nincs címkéje.\n"
STRING_DIR_HELP4 " A kötet sorozatszáma: %04X-%04X\n"
STRING_DIR_HELP5 "\n Összes állomány:\n%16i Állomány(ok)% 14s bájt\n"
STRING_DIR_HELP6 "%16i Mappa %15s bájt"
STRING_DIR_HELP6 "%16i Mappa %15s bájt szabad"
STRING_DIR_HELP7 "\n %s tartalma\n\n"
STRING_DIR_HELP8 "%16i Állomány %14s bájt\n"
STRING_DIRSTACK_HELP1 "Megjegyzi az aktuális mappát, majd átvált egy máasikra.\n\n\

View file

@ -181,7 +181,7 @@ preset dengan mengawali setiap saklar dengan - (minus)--contohnya, /-W.\n"
STRING_DIR_HELP3 " Volume di drive %c tidak berlabel.\n"
STRING_DIR_HELP4 " Nomor Seri Volume adalah %04X-%04X\n"
STRING_DIR_HELP5 "\n Total File Didaftar:\n%16i File% 14s byte\n"
STRING_DIR_HELP6 "%16i Dir% 15s byte\n"
STRING_DIR_HELP6 "%16i Dir% 15s byte tersisa\n"
STRING_DIR_HELP7 "\n Direktori %s\n\n"
STRING_DIR_HELP8 "%16i File% 14s byte\n"
STRING_DIRSTACK_HELP1 "Menyimpan direktori sekarang untuk digunakan oleh perintah POPD, lalu\n\

View file

@ -178,7 +178,7 @@ le selezioni preimpostate mettendo - (trattino) prima della selezione per esempi
STRING_DIR_HELP3 " Il Volume nel disco %c non ha etichetta.\n"
STRING_DIR_HELP4 " Il numero di serie del Volume è %04X-%04X\n"
STRING_DIR_HELP5 "\n Numero dei file elencati:\n%16i % 14s byte\n"
STRING_DIR_HELP6 "%16i Cartelle% 15s byte\n"
STRING_DIR_HELP6 "%16i Cartelle% 15s byte liberi\n"
STRING_DIR_HELP7 "\n Cartelle di %s\n\n"
STRING_DIR_HELP8 "%16i File% 14s byte\n"
STRING_DIRSTACK_HELP1 "Salva la cartella corrente per l'uso con il comando POPD, poi\n\

View file

@ -179,7 +179,7 @@ forhåndsinnstilte brytere ved å sette en bindestrek (-) foran, for eksempel, /
STRING_DIR_HELP3 " Volumet i stasjon %c er uten navn.\n"
STRING_DIR_HELP4 " Volumserienummeret er %04X-%04X\n"
STRING_DIR_HELP5 "\n Totalt filer listet:\n%16i fil(er)% 14s byte\n"
STRING_DIR_HELP6 "%16i mappe(r)% 15s byte\n"
STRING_DIR_HELP6 "%16i mappe(r)% 15s byte ledig\n"
STRING_DIR_HELP7 "\n mappe av %s\n\n"
STRING_DIR_HELP8 "%16i fil(er)% 14s byte\n"
STRING_DIRSTACK_HELP1 "Lagrer gjeldende mappe for bruk av POPD kommando, og\n\

View file

@ -187,7 +187,7 @@ odwrócić działanie parametrów przedrostkiem - (myślnik)-- na przykład, /-W
STRING_DIR_HELP3 " Wolumin w napędzie %c nie posiada etykiety.\n"
STRING_DIR_HELP4 " Numer seryjny woluminu to: %04X-%04X\n"
STRING_DIR_HELP5 "\n Ogółem wyświetonych:\n%16i plik(ów)% 14s bajtów\n"
STRING_DIR_HELP6 "%16i katalog(ów)% 15s bajtów\n"
STRING_DIR_HELP6 "%16i katalog(ów)% 15s bajtów wolne\n"
STRING_DIR_HELP7 "\n katalog %s\n\n"
STRING_DIR_HELP8 "%16i plik(ów)% 14s bajtów\n"
STRING_DIRSTACK_HELP1 "Przechowuje obecny katalog dla potrzeb komendy POPD, następnie\n\

View file

@ -180,7 +180,7 @@ DELAY [/m]n\n\n\
STRING_DIR_HELP3 " Том в устройстве %c не имеет метки.\n"
STRING_DIR_HELP4 " Серийный номер тома: %04X-%04X\n"
STRING_DIR_HELP5 "\n Всего:\n%16i Файл(ов)% 14s байт\n"
STRING_DIR_HELP6 "%16i Dir(s)% 15s байт\n"
STRING_DIR_HELP6 "%16i Dir(s)% 15s байт свободно\n"
STRING_DIR_HELP7 "\n Каталог of %s\n\n"
STRING_DIR_HELP8 "%16i файл(ов)% 14s байт\n"
STRING_DIRSTACK_HELP1 "Сохраняет текущую директорию для использования командой POPD, затем\n\

View file

@ -179,7 +179,7 @@ förinställda växlar med ett bindestreck (-) före, till exempel, /-W.\n"
STRING_DIR_HELP3 " Volumet i enhet %c är utan namn.\n"
STRING_DIR_HELP4 " Volymens serienummer är %04X-%04X\n"
STRING_DIR_HELP5 "\n Totalt filer listet:\n%16i fil(är)% 14s byte\n"
STRING_DIR_HELP6 "%16i mapp(ar)% 15s byte\n"
STRING_DIR_HELP6 "%16i mapp(ar)% 15s byte ledigt\n"
STRING_DIR_HELP7 "\n mapp av %s\n\n"
STRING_DIR_HELP8 "%16i fil(er)% 14s byte\n"
STRING_DIRSTACK_HELP1 "Sparar aktuell mapp for användning av POPD kommandot, och\n\

View file

@ -302,7 +302,7 @@ function(spec2def _dllname _spec_file)
endfunction()
macro(macro_mc FLAG FILE)
set(COMMAND_MC ${CMAKE_MC_COMPILER} ${FLAG} -r ${REACTOS_BINARY_DIR}/include/reactos -h ${REACTOS_BINARY_DIR}/include/reactos ${CMAKE_CURRENT_SOURCE_DIR}/${FILE}.mc)
set(COMMAND_MC ${CMAKE_MC_COMPILER} ${FLAG} -b ${CMAKE_CURRENT_SOURCE_DIR}/${FILE}.mc -r ${REACTOS_BINARY_DIR}/include/reactos -h ${REACTOS_BINARY_DIR}/include/reactos)
endmacro()
#pseh workaround

View file

@ -966,6 +966,10 @@ LsaApLogonUser(IN PLSA_CLIENT_REQUEST ClientRequest,
PSAMPR_USER_INFO_BUFFER UserInfo = NULL;
UNICODE_STRING LogonServer;
BOOLEAN SessionCreated = FALSE;
LARGE_INTEGER LogonTime;
// LARGE_INTEGER AccountExpires;
LARGE_INTEGER PasswordMustChange;
LARGE_INTEGER PasswordLastSet;
NTSTATUS Status;
TRACE("()\n");
@ -1005,6 +1009,10 @@ LsaApLogonUser(IN PLSA_CLIENT_REQUEST ClientRequest,
return STATUS_NOT_IMPLEMENTED;
}
/* Get the logon time */
NtQuerySystemTime(&LogonTime);
/* Get the domain SID */
Status = GetDomainSid(&AccountDomainSid);
if (!NT_SUCCESS(Status))
{
@ -1080,9 +1088,20 @@ LsaApLogonUser(IN PLSA_CLIENT_REQUEST ClientRequest,
goto done;
}
TRACE("UserName: %S\n", UserInfo->All.UserName.Buffer);
/* Check the password */
if ((UserInfo->All.UserAccountControl & USER_PASSWORD_NOT_REQUIRED) == 0)
{
Status = MsvpCheckPassword(&(LogonInfo->Password),
UserInfo);
if (!NT_SUCCESS(Status))
{
TRACE("MsvpCheckPassword failed (Status %08lx)\n", Status);
goto done;
}
}
/* Check account restrictions for non-administrator accounts */
if (RelativeIds.Element[0] != DOMAIN_USER_RID_ADMIN)
{
@ -1098,29 +1117,48 @@ LsaApLogonUser(IN PLSA_CLIENT_REQUEST ClientRequest,
/* Check if the account has been locked */
if (UserInfo->All.UserAccountControl & USER_ACCOUNT_AUTO_LOCKED)
{
ERR("Account disabled!\n");
ERR("Account locked!\n");
*SubStatus = STATUS_ACCOUNT_LOCKED_OUT;
Status = STATUS_ACCOUNT_RESTRICTION;
goto done;
}
/* FIXME: more checks */
// *SubStatus = STATUS_PASSWORD_EXPIRED;
// *SubStatus = STATUS_INVALID_LOGON_HOURS;
// *SubStatus = STATUS_INVALID_WORKSTATION;
#if 0
/* Check if the account expired */
AccountExpires.LowPart = UserInfo->All.AccountExpires.LowPart;
AccountExpires.HighPart = UserInfo->All.AccountExpires.HighPart;
}
/* Check the password */
if ((UserInfo->All.UserAccountControl & USER_PASSWORD_NOT_REQUIRED) == 0)
{
Status = MsvpCheckPassword(&(LogonInfo->Password),
UserInfo);
if (!NT_SUCCESS(Status))
if (AccountExpires.QuadPart != 0 &&
LogonTime.QuadPart >= AccountExpires.QuadPart)
{
TRACE("MsvpCheckPassword failed (Status %08lx)\n", Status);
ERR("Account expired!\n");
*SubStatus = STATUS_ACCOUNT_EXPIRED;
Status = STATUS_ACCOUNT_RESTRICTION;
goto done;
}
#endif
/* Check if the password expired */
PasswordMustChange.LowPart = UserInfo->All.PasswordMustChange.LowPart;
PasswordMustChange.HighPart = UserInfo->All.PasswordMustChange.HighPart;
PasswordLastSet.LowPart = UserInfo->All.PasswordLastSet.LowPart;
PasswordLastSet.HighPart = UserInfo->All.PasswordLastSet.HighPart;
if (LogonTime.QuadPart >= PasswordMustChange.QuadPart)
{
ERR("Password expired!\n");
if (PasswordLastSet.QuadPart == 0)
*SubStatus = STATUS_PASSWORD_MUST_CHANGE;
else
*SubStatus = STATUS_PASSWORD_EXPIRED;
Status = STATUS_ACCOUNT_RESTRICTION;
goto done;
}
/* FIXME: more checks */
// STATUS_INVALID_LOGON_HOURS;
// STATUS_INVALID_WORKSTATION;
}
/* Return logon information */
@ -1220,7 +1258,7 @@ done:
Status = STATUS_LOGON_FAILURE;
}
TRACE("LsaApLogonUser done (Status %08lx)\n", Status);
TRACE("LsaApLogonUser done (Status 0x%08lx SubStatus 0x%08lx)\n", Status, *SubStatus);
return Status;
}

View file

@ -437,6 +437,7 @@ StartProcedure(
Status = EnableInterrupts(DeviceExtension, FlagsToDisable, FlagsToEnable);
if (!NT_SUCCESS(Status))
{
WARN_(I8042PRT, "EnableInterrupts failed: %lx\n", Status);
DeviceExtension->Flags &= ~(KEYBOARD_PRESENT | MOUSE_PRESENT);
return Status;
}
@ -454,6 +455,10 @@ StartProcedure(
{
DeviceExtension->Flags |= KEYBOARD_INITIALIZED;
}
else
{
WARN_(I8042PRT, "i8042ConnectKeyboardInterrupt failed: %lx\n", Status);
}
}
if (DeviceExtension->Flags & MOUSE_PRESENT &&
@ -467,7 +472,11 @@ StartProcedure(
{
DeviceExtension->Flags |= MOUSE_INITIALIZED;
}
else
{
WARN_(I8042PRT, "i8042ConnectMouseInterrupt failed: %lx\n", Status);
}
/* Start the mouse */
Irql = KeAcquireInterruptSpinLock(DeviceExtension->HighestDIRQLInterrupt);
i8042IsrWritePort(DeviceExtension, MOU_CMD_RESET, CTRL_WRITE_MOUSE);
@ -533,7 +542,7 @@ i8042PnpStartDevice(
{
if (ResourceDescriptor->u.Port.Length == 1)
{
/* We assume that the first ressource will
/* We assume that the first resource will
* be the control port and the second one
* will be the data port...
*/
@ -551,8 +560,8 @@ i8042PnpStartDevice(
}
else
{
WARN_(I8042PRT, "Too much I/O ranges provided: 0x%lx\n", ResourceDescriptor->u.Port.Length);
return STATUS_INVALID_PARAMETER;
/* FIXME: implement PS/2 Active Multiplexing */
ERR_(I8042PRT, "Unhandled I/O ranges provided: 0x%lx\n", ResourceDescriptor->u.Port.Length);
}
}
else

View file

@ -17,7 +17,7 @@
* Notes:
* This driver was obsoleted in Windows XP and most functions
* became pure stubs. But some of them were retained for backward
* compatibilty with existing drivers.
* compatibility with existing drivers.
*
* Preserved functions:
*

View file

@ -648,7 +648,7 @@ IopStartDevice2(IN PDEVICE_OBJECT DeviceObject)
ASSERT(!(DeviceNode->Flags & DNF_DISABLED));
/* Build the I/O stack locaiton */
/* Build the I/O stack location */
RtlZeroMemory(&Stack, sizeof(IO_STACK_LOCATION));
Stack.MajorFunction = IRP_MJ_PNP;
Stack.MinorFunction = IRP_MN_START_DEVICE;

View file

@ -271,7 +271,7 @@ IntCreateMenu(PHANDLE Handle, BOOL IsMenuBar)
Menu->MenuInfo.dwMenuData = 0; /* Default */
Menu->MenuInfo.Self = *Handle;
Menu->MenuInfo.FocusedItem = NO_SELECTED_ITEM;
Menu->MenuInfo.Flags = (IsMenuBar ? 0 : MF_POPUP);
Menu->MenuInfo.Flags = (IsMenuBar ? 0 : MNF_POPUP);
Menu->MenuInfo.Wnd = NULL;
Menu->MenuInfo.WndOwner = NULL;
Menu->MenuInfo.Height = 0;
@ -454,7 +454,17 @@ IntSetMenuInfo(PMENU_OBJECT Menu, PROSMENUINFO lpmi)
Menu->MenuInfo.dwStyle = lpmi->dwStyle;
if(lpmi->fMask & MIM_APPLYTOSUBMENUS)
{
/* FIXME */
int i;
PMENU_ITEM item = Menu->MenuItemList;
for ( i = Menu->MenuInfo.MenuItemCount; i; i--, item = item->Next)
{
if ( item->hSubMenu )
{
PMENU_OBJECT SubMenu;
if (!(SubMenu = UserGetMenuObject(item->hSubMenu))) continue;
IntSetMenuInfo( SubMenu, lpmi);
}
}
}
if (sizeof(MENUINFO) < lpmi->cbSize)
{
@ -741,7 +751,7 @@ IntSetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, PROSMENUITEMINF
SubMenuObject = UserGetMenuObject(MenuItem->hSubMenu);
if (SubMenuObject != NULL)
{
SubMenuObject->MenuInfo.Flags |= MF_POPUP;
SubMenuObject->MenuInfo.Flags |= MNF_POPUP;
}
}
}
@ -775,7 +785,7 @@ IntSetMenuItemInfo(PMENU_OBJECT MenuObject, PMENU_ITEM MenuItem, PROSMENUITEMINF
}
else
{
if (0 == (MenuObject->MenuInfo.Flags & MF_SYSMENU))
if (0 == (MenuObject->MenuInfo.Flags & MNF_SYSDESKMN))
{
MenuItem->fType |= MF_SEPARATOR;
}
@ -1724,6 +1734,50 @@ 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
*/
@ -1734,219 +1788,126 @@ NtUserGetMenuBarInfo(
LONG idItem,
PMENUBARINFO pmbi)
{
BOOL Res = TRUE;
PMENU_OBJECT MenuObject;
PMENU_ITEM mi;
PWND WindowObject;
PWND pWnd;
HMENU hMenu;
POINT Offset;
RECTL Rect;
MENUBARINFO kmbi;
BOOL Ret;
NTSTATUS Status = STATUS_SUCCESS;
PMENU_OBJECT Menu = NULL;
DECLARE_RETURN(BOOL);
TRACE("Enter NtUserGetMenuBarInfo\n");
UserEnterShared();
if (!(WindowObject = UserGetWindowObject(hwnd)))
{
if (!(pWnd = UserGetWindowObject(hwnd)))
{
EngSetLastError(ERROR_INVALID_WINDOW_HANDLE);
RETURN(FALSE);
}
hMenu = (HMENU)(DWORD_PTR)WindowObject->IDMenu;
if (!(MenuObject = UserGetMenuObject(hMenu)))
{
EngSetLastError(ERROR_INVALID_MENU_HANDLE);
RETURN(FALSE);
}
if (pmbi->cbSize != sizeof(MENUBARINFO))
{
EngSetLastError(ERROR_INVALID_PARAMETER);
RETURN(FALSE);
}
kmbi.cbSize = sizeof(MENUBARINFO);
kmbi.fBarFocused = FALSE;
kmbi.fFocused = FALSE;
kmbi.hwndMenu = NULL;
}
switch (idObject)
{
case OBJID_MENU:
{
PMENU_OBJECT SubMenuObject;
kmbi.hMenu = hMenu;
if (idItem) /* Non-Zero-Based. */
{
if (IntGetMenuItemByFlag(MenuObject, idItem-1, MF_BYPOSITION, NULL, &mi, NULL) > -1)
kmbi.rcBar = mi->Rect;
else
{
Res = FALSE;
break;
}
}
else
{
/* If items is zero we assume info for the menu itself. */
if (!(IntGetClientOrigin(WindowObject, &Offset)))
{
Res = FALSE;
break;
}
Rect.left = Offset.x;
Rect.right = Offset.x + MenuObject->MenuInfo.Width;
Rect.bottom = Offset.y;
Rect.top = Offset.y - MenuObject->MenuInfo.Height;
kmbi.rcBar = Rect;
TRACE("Rect top = %d bottom = %d left = %d right = %d \n",
Rect.top, Rect.bottom, Rect.left, Rect.right);
}
if (idItem)
{
if (idItem-1 == MenuObject->MenuInfo.FocusedItem)
kmbi.fFocused = TRUE;
}
if (MenuObject->MenuInfo.FocusedItem != NO_SELECTED_ITEM)
kmbi.fBarFocused = TRUE;
if (MenuObject->MenuItemList)
{
SubMenuObject = UserGetMenuObject(MenuObject->MenuItemList->hSubMenu);
if(SubMenuObject) kmbi.hwndMenu = SubMenuObject->MenuInfo.Wnd;
}
TRACE("OBJID_MENU, idItem = %d\n",idItem);
break;
}
case OBJID_CLIENT:
{
PMENU_OBJECT SubMenuObject, XSubMenuObject;
HMENU hMenuChk;
// Windows does this! Wine checks for Atom and uses GetWindowLongPtrW.
hMenuChk = (HMENU)co_IntSendMessage(hwnd, MN_GETHMENU, 0, 0);
if (!(MenuObject = UserGetMenuObject(hMenuChk)))
{
ERR("Window does not have a Popup Menu!\n");
case OBJID_CLIENT:
if (!pWnd->pcls->fnid)
RETURN(FALSE);
if (pWnd->pcls->fnid != FNID_MENU)
{
WARN("called on invalid window: %d\n", pWnd->pcls->fnid);
EngSetLastError(ERROR_INVALID_MENU_HANDLE);
RETURN(FALSE);
}
SubMenuObject = UserGetMenuObject(MenuObject->MenuItemList->hSubMenu);
if(SubMenuObject) kmbi.hMenu = SubMenuObject->MenuInfo.Self;
else
{
Res = FALSE;
ERR("OBJID_CLIENT, No SubMenu!\n");
break;
}
if (idItem)
{
if (IntGetMenuItemByFlag(SubMenuObject, idItem-1, MF_BYPOSITION, NULL, &mi, NULL) > -1)
kmbi.rcBar = mi->Rect;
else
{
Res = FALSE;
break;
}
}
else
{
PWND SubWinObj;
if (!(SubWinObj = UserGetWindowObject(SubMenuObject->MenuInfo.Wnd)))
{
Res = FALSE;
break;
}
if (!(IntGetClientOrigin(SubWinObj, &Offset)))
{
Res = FALSE;
break;
}
Rect.left = Offset.x;
Rect.right = Offset.x + SubMenuObject->MenuInfo.Width;
Rect.top = Offset.y;
Rect.bottom = Offset.y + SubMenuObject->MenuInfo.Height;
kmbi.rcBar = Rect;
}
if (idItem)
{
if (idItem-1 == SubMenuObject->MenuInfo.FocusedItem)
kmbi.fFocused = TRUE;
}
if (SubMenuObject->MenuInfo.FocusedItem != NO_SELECTED_ITEM)
kmbi.fBarFocused = TRUE;
XSubMenuObject = UserGetMenuObject(SubMenuObject->MenuItemList->hSubMenu);
if (XSubMenuObject) kmbi.hwndMenu = XSubMenuObject->MenuInfo.Wnd;
TRACE("OBJID_CLIENT, idItem = %d\n",idItem);
break;
}
case OBJID_SYSMENU:
{
PMENU_OBJECT SysMenuObject, SubMenuObject;
if(!(SysMenuObject = IntGetSystemMenu(WindowObject, FALSE, FALSE)))
{
Res = FALSE;
break;
}
kmbi.hMenu = SysMenuObject->MenuInfo.Self;
if (idItem)
{
if (IntGetMenuItemByFlag(SysMenuObject, idItem-1, MF_BYPOSITION, NULL, &mi, NULL) > -1)
kmbi.rcBar = mi->Rect;
else
{
Res = FALSE;
break;
}
}
else
{
PWND SysWinObj;
if (!(SysWinObj = UserGetWindowObject(SysMenuObject->MenuInfo.Wnd)))
{
Res = FALSE;
break;
}
if (!(IntGetClientOrigin(SysWinObj, &Offset)))
{
Res = FALSE;
break;
}
Rect.left = Offset.x;
Rect.right = Offset.x + SysMenuObject->MenuInfo.Width;
Rect.top = Offset.y;
Rect.bottom = Offset.y + SysMenuObject->MenuInfo.Height;
kmbi.rcBar = Rect;
}
if (idItem)
{
if (idItem-1 == SysMenuObject->MenuInfo.FocusedItem)
kmbi.fFocused = TRUE;
}
if (SysMenuObject->MenuInfo.FocusedItem != NO_SELECTED_ITEM)
kmbi.fBarFocused = TRUE;
SubMenuObject = UserGetMenuObject(SysMenuObject->MenuItemList->hSubMenu);
if(SubMenuObject) kmbi.hwndMenu = SubMenuObject->MenuInfo.Wnd;
TRACE("OBJID_SYSMENU, idItem = %d\n",idItem);
break;
}
default:
Res = FALSE;
ERR("Unknown idObject = %d, idItem = %d\n",idObject,idItem);
}
// Windows does this! Wine checks for Atom and uses GetWindowLongPtrW.
hMenu = (HMENU)co_IntSendMessage(hwnd, MN_GETHMENU, 0, 0);
break;
case OBJID_MENU:
hMenu = UlongToHandle(pWnd->IDMenu);
break;
case OBJID_SYSMENU:
if (!(pWnd->style & WS_SYSMENU)) RETURN(FALSE);
Menu = IntGetSystemMenu(pWnd, FALSE, FALSE);
hMenu = Menu->MenuInfo.Self;
break;
default:
RETURN(FALSE);
}
if (Res)
{
NTSTATUS Status = MmCopyToCaller(pmbi, &kmbi, sizeof(MENUBARINFO));
if (! NT_SUCCESS(Status))
{
SetLastNtError(Status);
RETURN(FALSE);
}
}
RETURN(Res);
if (!hMenu)
RETURN(FALSE);
_SEH2_TRY
{
kmbi.cbSize = pmbi->cbSize;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
kmbi.cbSize = 0;
}
_SEH2_END
if (kmbi.cbSize != sizeof(MENUBARINFO))
{
EngSetLastError(ERROR_INVALID_PARAMETER);
RETURN(FALSE);
}
if (!Menu) Menu = UserGetMenuObject(hMenu);
if (!Menu)
RETURN(FALSE);
if (idItem < 0 || idItem > Menu->MenuInfo.MenuItemCount)
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;
ERR("idItem 0 %d\n",Ret);
}
else
{
Ret = IntGetMenuItemRect(pWnd, Menu, idItem-1, &kmbi.rcBar);
ERR("idItem X %d\n", Ret);
}
kmbi.hMenu = hMenu;
kmbi.hwndMenu = NULL;
//kmbi.fBarFocused = top_popup_hmenu == hMenu;
if (idItem)
{
PMENU_OBJECT SubMenuObject;
kmbi.fFocused = Menu->MenuInfo.FocusedItem == idItem-1;
if ( kmbi.fFocused && Menu->MenuItemList->hSubMenu )
{
SubMenuObject = UserGetMenuObject(Menu->MenuItemList->hSubMenu);
if (SubMenuObject) kmbi.hwndMenu = SubMenuObject->MenuInfo.Wnd;
}
}
/* else
{
kmbi.fFocused = kmbi.fBarFocused;
}
*/
_SEH2_TRY
{
RtlCopyMemory(pmbi, &kmbi, sizeof(MENUBARINFO));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
RETURN(FALSE);
}
RETURN(TRUE);
CLEANUP:
TRACE("Leave NtUserGetMenuBarInfo, ret=%i\n",_ret_);
@ -2002,9 +1963,9 @@ NtUserGetMenuItemRect(
PWND ReferenceWnd;
LONG XMove, YMove;
RECTL Rect;
NTSTATUS Status;
PMENU_OBJECT Menu;
PMENU_ITEM MenuItem;
NTSTATUS Status = STATUS_SUCCESS;
DECLARE_RETURN(BOOL);
TRACE("Enter NtUserGetMenuItemRect\n");
@ -2029,7 +1990,7 @@ NtUserGetMenuItemRect(
if (!(ReferenceWnd = UserGetWindowObject(hWnd))) RETURN( FALSE);
if(MenuItem->hSubMenu)
if (Menu->MenuInfo.Flags & MNF_POPUP)
{
XMove = ReferenceWnd->rcClient.left;
YMove = ReferenceWnd->rcClient.top;
@ -2045,13 +2006,22 @@ NtUserGetMenuItemRect(
Rect.right += XMove;
Rect.bottom += YMove;
Status = MmCopyToCaller(lprcItem, &Rect, sizeof(RECT));
if (! NT_SUCCESS(Status))
_SEH2_TRY
{
RtlCopyMemory(lprcItem, &Rect, sizeof(RECTL));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
}
_SEH2_END
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
RETURN( FALSE);
RETURN(FALSE);
}
RETURN( TRUE);
RETURN(TRUE);
CLEANUP:
TRACE("Leave NtUserGetMenuItemRect, ret=%i\n",_ret_);

View file

@ -931,7 +931,7 @@ IntGetSystemMenu(PWND Window, BOOL bRevert, BOOL RetMenu)
if(NewMenu)
{
Window->SystemMenu = NewMenu->MenuInfo.Self;
NewMenu->MenuInfo.Flags |= MF_SYSMENU;
NewMenu->MenuInfo.Flags |= MNF_SYSDESKMN;
NewMenu->MenuInfo.Wnd = Window->head.h;
ret = NewMenu;
//IntReleaseMenuObject(NewMenu);
@ -950,7 +950,7 @@ IntGetSystemMenu(PWND Window, BOOL bRevert, BOOL RetMenu)
UserDestroyMenu(hSysMenu);
return NULL;
}
SysMenu->MenuInfo.Flags |= MF_SYSMENU;
SysMenu->MenuInfo.Flags |= MNF_SYSDESKMN;
SysMenu->MenuInfo.Wnd = Window->head.h;
hNewMenu = co_IntLoadSysMenuTemplate();
if(!hNewMenu)
@ -970,7 +970,8 @@ IntGetSystemMenu(PWND Window, BOOL bRevert, BOOL RetMenu)
NewMenu = IntCloneMenu(Menu);
if(NewMenu)
{
NewMenu->MenuInfo.Flags |= MF_SYSMENU | MF_POPUP;
NewMenu->MenuInfo.Flags |= MNF_SYSDESKMN | MNF_POPUP;
NewMenu->MenuInfo.dwStyle = MNS_CHECKORBMP;
IntReleaseMenuObject(NewMenu);
UserSetMenuDefaultItem(NewMenu, SC_CLOSE, FALSE);
@ -1426,7 +1427,7 @@ IntSetSystemMenu(PWND Window, PMENU_OBJECT Menu)
OldMenu = IntGetMenuObject(Window->SystemMenu);
if(OldMenu)
{
OldMenu->MenuInfo.Flags &= ~ MF_SYSMENU;
OldMenu->MenuInfo.Flags &= ~ MNF_SYSDESKMN;
IntReleaseMenuObject(OldMenu);
}
}
@ -1435,7 +1436,7 @@ IntSetSystemMenu(PWND Window, PMENU_OBJECT Menu)
{
/* FIXME: Check window style, propably return FALSE? */
Window->SystemMenu = Menu->MenuInfo.Self;
Menu->MenuInfo.Flags |= MF_SYSMENU;
Menu->MenuInfo.Flags |= MNF_SYSDESKMN;
}
else
Window->SystemMenu = (HMENU)0;

View file

@ -36,6 +36,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(menu);
#define TPM_BUTTONDOWN 0x40000000 /* menu was clicked before tracking */
#define TPM_POPUPMENU 0x20000000 /* menu is a popup menu */
/* top and bottom margins for popup menus */
#define MENU_TOP_MARGIN 3
#define MENU_BOTTOM_MARGIN 2
#define MENU_TYPE_MASK (MF_STRING | MF_BITMAP | MF_OWNERDRAW | MF_SEPARATOR)
@ -46,10 +49,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(menu);
#define IS_MAGIC_BITMAP(id) ((id) && ((INT_PTR)(id) < 12) && ((INT_PTR)(id) >= -1))
#define IS_SYSTEM_MENU(MenuInfo) \
(0 == ((MenuInfo)->Flags & MF_POPUP) && 0 != ((MenuInfo)->Flags & MF_SYSMENU))
(0 == ((MenuInfo)->Flags & MNF_POPUP) && 0 != ((MenuInfo)->Flags & MNF_SYSDESKMN))
#define IS_SYSTEM_POPUP(MenuInfo) \
(0 != ((MenuInfo)->Flags & MF_POPUP) && 0 != ((MenuInfo)->Flags & MF_SYSMENU))
(0 != ((MenuInfo)->Flags & MNF_POPUP) && 0 != ((MenuInfo)->Flags & MNF_SYSDESKMN))
#define IS_BITMAP_ITEM(flags) (MF_BITMAP == MENU_ITEM_TYPE(flags))
@ -507,6 +510,7 @@ static UINT FASTCALL MenuFindItemByKey(HWND WndOwner, PROSMENUINFO MenuInfo,
PROSMENUITEMINFO Items, ItemInfo;
LRESULT MenuChar;
UINT i;
WORD Flags = 0;
TRACE("\tlooking for '%c' (0x%02x) in [%p]\n", (char) Key, Key, MenuInfo);
@ -546,8 +550,11 @@ static UINT FASTCALL MenuFindItemByKey(HWND WndOwner, PROSMENUINFO MenuInfo,
}
}
Flags |= MenuInfo->Flags & MNF_POPUP ? MF_POPUP : 0;
Flags |= MenuInfo->Flags & MNF_SYSDESKMN ? MF_SYSMENU : 0;
MenuChar = SendMessageW(WndOwner, WM_MENUCHAR,
MAKEWPARAM(Key, MenuInfo->Flags), (LPARAM) MenuInfo->Self);
MAKEWPARAM(Key, Flags), (LPARAM) MenuInfo->Self);
if (HIWORD(MenuChar) == MNC_EXECUTE) return LOWORD(MenuChar);
if (HIWORD(MenuChar) == MNC_CLOSE) return (UINT)(-2);
}
@ -1299,7 +1306,7 @@ static void FASTCALL MenuDrawMenuItem(HWND hWnd, PROSMENUINFO MenuInfo, HWND Wnd
HBITMAP bm;
INT y = rect.top + rect.bottom;
RECT rc = rect;
int checked = FALSE;
BOOL checked = FALSE;
UINT check_bitmap_width = GetSystemMetrics( SM_CXMENUCHECK );
UINT check_bitmap_height = GetSystemMetrics( SM_CYMENUCHECK );
/* Draw the check mark
@ -1547,6 +1554,7 @@ static BOOL FASTCALL MenuShowPopup(HWND hwndOwner, HMENU hmenu, UINT id, UINT fl
POINT pt;
HMONITOR monitor;
MONITORINFO info;
DWORD ex_style = 0;
TRACE("owner=%p hmenu=%p id=0x%04x x=0x%04x y=0x%04x xa=0x%04x ya=0x%04x\n",
hwndOwner, hmenu, id, x, y, xanchor, yanchor);
@ -1588,6 +1596,11 @@ static BOOL FASTCALL MenuShowPopup(HWND hwndOwner, HMENU hmenu, UINT id, UINT fl
info.cbSize = sizeof(info);
GetMonitorInfoW( monitor, &info );
if (flags & TPM_LAYOUTRTL)
{
ex_style = WS_EX_LAYOUTRTL;
flags ^= TPM_RIGHTALIGN;
}
if( flags & TPM_RIGHTALIGN ) x -= width;
if( flags & TPM_CENTERALIGN ) x -= width / 2;
@ -1615,7 +1628,7 @@ static BOOL FASTCALL MenuShowPopup(HWND hwndOwner, HMENU hmenu, UINT id, UINT fl
if( y < info.rcMonitor.top ) y = info.rcMonitor.top;
/* NOTE: In Windows, top menu popup is not owned. */
MenuInfo.Wnd = CreateWindowExW( 0, WC_MENU, NULL,
MenuInfo.Wnd = CreateWindowExW( ex_style, WC_MENU, NULL,
WS_POPUP, x, y, width, height,
hwndOwner, 0, (HINSTANCE) GetWindowLongPtrW(hwndOwner, GWLP_HINSTANCE),
(LPVOID) MenuInfo.Self);
@ -1650,7 +1663,7 @@ static void FASTCALL MenuSelectItem(HWND hwndOwner, PROSMENUINFO hmenu, UINT wIn
if (!hmenu || !hmenu->MenuItemCount || !hmenu->Wnd) return;
if (hmenu->FocusedItem == wIndex) return;
if (hmenu->Flags & MF_POPUP) hdc = GetDC(hmenu->Wnd);
if (hmenu->Flags & MNF_POPUP) hdc = GetDC(hmenu->Wnd);
else hdc = GetDCEx(hmenu->Wnd, 0, DCX_CACHE | DCX_WINDOW);
if (!top_popup) {
top_popup = hmenu->Wnd;
@ -1671,7 +1684,7 @@ static void FASTCALL MenuSelectItem(HWND hwndOwner, PROSMENUINFO hmenu, UINT wIn
MenuSetRosMenuItemInfo(hmenu->Self, hmenu->FocusedItem, &ItemInfo);
}
MenuDrawMenuItem(hmenu->Wnd, hmenu, hwndOwner, hdc, &ItemInfo,
hmenu->Height, ! (hmenu->Flags & MF_POPUP),
hmenu->Height, !(hmenu->Flags & MNF_POPUP),
ODA_SELECT);
}
@ -1688,20 +1701,24 @@ static void FASTCALL MenuSelectItem(HWND hwndOwner, PROSMENUINFO hmenu, UINT wIn
ItemInfo.fState |= MF_HILITE;
MenuSetRosMenuItemInfo(hmenu->Self, hmenu->FocusedItem, &ItemInfo);
MenuDrawMenuItem(hmenu->Wnd, hmenu, hwndOwner, hdc,
&ItemInfo, hmenu->Height, ! (hmenu->Flags & MF_POPUP),
&ItemInfo, hmenu->Height, !(hmenu->Flags & MNF_POPUP),
ODA_SELECT);
}
if (sendMenuSelect)
{
SendMessageW(hwndOwner, WM_MENUSELECT,
MAKELONG(ItemInfo.hSubMenu ? wIndex : ItemInfo.wID,
ItemInfo.fType | ItemInfo.fState | MF_MOUSESELECT |
(hmenu->Flags & (MF_SYSMENU|MF_POPUP))), (LPARAM) hmenu->Self);
WPARAM wParam = MAKEWPARAM( ItemInfo.hSubMenu ? wIndex : ItemInfo.wID,
ItemInfo.fType | ItemInfo.fState |
(ItemInfo.hSubMenu ? MF_POPUP : 0) |
(hmenu->Flags & MNF_SYSDESKMN ? MF_SYSMENU : 0 ) );
SendMessageW(hwndOwner, WM_MENUSELECT, wParam, (LPARAM) hmenu->Self);
}
}
}
else if (sendMenuSelect) {
if(topmenu) {
else if (sendMenuSelect)
{
if(topmenu)
{
int pos;
pos = MenuFindSubMenu(&topmenu, hmenu->Self);
if (pos != NO_SELECTED_ITEM)
@ -1709,11 +1726,11 @@ static void FASTCALL MenuSelectItem(HWND hwndOwner, PROSMENUINFO hmenu, UINT wIn
if (MenuGetRosMenuInfo(&TopMenuInfo, topmenu)
&& MenuGetRosMenuItemInfo(topmenu, pos, &ItemInfo))
{
SendMessageW(hwndOwner, WM_MENUSELECT,
MAKELONG(Pos, ItemInfo.fType | ItemInfo.fState
| MF_MOUSESELECT
| (TopMenuInfo.Flags & MF_SYSMENU)),
(LPARAM) topmenu);
WPARAM wParam = MAKEWPARAM( Pos, ItemInfo.fType | ItemInfo.fState |
(ItemInfo.hSubMenu ? MF_POPUP : 0) |
(TopMenuInfo.Flags & MNF_SYSDESKMN ? MF_SYSMENU : 0 ) );
SendMessageW(hwndOwner, WM_MENUSELECT, wParam, (LPARAM) topmenu);
}
}
}
@ -1995,11 +2012,11 @@ PopupMenuWndProcW(HWND Wnd, UINT Message, WPARAM wParam, LPARAM lParam)
*
* NOTE: flags is equivalent to the mtOption field
*/
static LPCSTR MENU_ParseResource( LPCSTR res, HMENU hMenu, BOOL unicode )
static LPCSTR MENU_ParseResource( LPCSTR res, HMENU hMenu)
{
WORD flags, id = 0;
HMENU hSubMenu;
LPCSTR str;
LPCWSTR str;
BOOL end = FALSE;
do
@ -2016,46 +2033,19 @@ static LPCSTR MENU_ParseResource( LPCSTR res, HMENU hMenu, BOOL unicode )
id = GET_WORD(res);
res += sizeof(WORD);
}
str = res;
if(!unicode)
res += strlen(str) + 1;
else
res += (strlenW((LPCWSTR)str) + 1) * sizeof(WCHAR);
str = (LPCWSTR)res;
res += (strlenW(str) + 1) * sizeof(WCHAR);
if (flags & MF_POPUP)
{
hSubMenu = CreatePopupMenu();
if(!hSubMenu) return NULL;
if(!(res = MENU_ParseResource(res, hSubMenu, unicode)))
return NULL;
if(!unicode)
AppendMenuA(hMenu, flags, (UINT)hSubMenu, str);
else
AppendMenuW(hMenu, flags, (UINT)hSubMenu, (LPCWSTR)str);
if(!(res = MENU_ParseResource(res, hSubMenu))) return NULL;
AppendMenuW(hMenu, flags, (UINT_PTR)hSubMenu, (LPCWSTR)str);
}
else /* Not a popup */
{
if(!unicode)
{
if (*str == 0)
flags = MF_SEPARATOR;
}
else
{
if (*(LPCWSTR)str == 0)
flags = MF_SEPARATOR;
}
if (flags & MF_SEPARATOR)
{
if (!(flags & (MF_GRAYED | MF_DISABLED)))
flags |= MF_GRAYED | MF_DISABLED;
}
if(!unicode)
AppendMenuA(hMenu, flags, id, *str ? str : NULL);
else
AppendMenuW(hMenu, flags, id,
*(LPCWSTR)str ? (LPCWSTR)str : NULL);
AppendMenuW(hMenu, flags, id, *(LPCWSTR)str ? (LPCWSTR)str : NULL);
}
} while(!end);
return res;
@ -2071,10 +2061,10 @@ static LPCSTR MENU_ParseResource( LPCSTR res, HMENU hMenu, BOOL unicode )
static LPCSTR MENUEX_ParseResource(LPCSTR res, HMENU hMenu)
{
WORD resinfo;
MENUITEMINFOW mii;
do
{
MENUITEMINFOW mii;
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STATE | MIIM_ID | MIIM_TYPE;
mii.fType = GET_DWORD(res);
@ -2114,13 +2104,12 @@ static LPCSTR MENUEX_ParseResource(LPCSTR res, HMENU hMenu)
return NULL;
}
mii.fMask |= MIIM_SUBMENU;
/*mii.wID = (UINT)mii.hSubMenu;*/
}
else if (!mii.dwTypeData[0])
else if (!mii.dwTypeData[0] && !(mii.fType & MF_SEPARATOR))
{
mii.fType |= MF_SEPARATOR;
if (!InsertMenuItemW(hMenu, -1, MF_BYPOSITION, &mii))
ERR("InsertMenuItemW failed\n");
}
InsertMenuItemW(hMenu, -1, MF_BYPOSITION, &mii);
} while (!(resinfo & MF_END));
return res;
}
@ -2327,7 +2316,7 @@ MenuShowSubPopup(HWND WndOwner, PROSMENUINFO MenuInfo, BOOL SelectFirst, UINT Fl
if (0 == (Flags & TPM_NONOTIFY))
{
SendMessageW(WndOwner, WM_INITMENUPOPUP, (WPARAM) ItemInfo.hSubMenu,
MAKELONG(MenuInfo->FocusedItem, IS_SYSTEM_MENU(MenuInfo)));
MAKELPARAM(MenuInfo->FocusedItem, IS_SYSTEM_MENU(MenuInfo)));
}
if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo))
@ -2340,7 +2329,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 & MF_POPUP))
if (0 != (MenuInfo->Flags & MNF_POPUP))
{
Dc = GetDC(MenuInfo->Wnd);
}
@ -2354,7 +2343,7 @@ MenuShowSubPopup(HWND WndOwner, PROSMENUINFO MenuInfo, BOOL SelectFirst, UINT Fl
ItemInfo.fState |= MF_HILITE;
MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo);
MenuDrawMenuItem(MenuInfo->Wnd, MenuInfo, WndOwner, Dc, &ItemInfo, MenuInfo->Height,
! (MenuInfo->Flags & MF_POPUP), ODA_DRAWENTIRE);
! (MenuInfo->Flags & MNF_POPUP), ODA_DRAWENTIRE);
ReleaseDC(MenuInfo->Wnd, Dc);
}
@ -2372,38 +2361,47 @@ MenuShowSubPopup(HWND WndOwner, PROSMENUINFO MenuInfo, BOOL SelectFirst, UINT Fl
{
MenuInitSysMenuPopup(ItemInfo.hSubMenu, GetWindowLongPtrW(MenuInfo->Wnd, GWL_STYLE),
GetClassLongPtrW(MenuInfo->Wnd, GCL_STYLE), HTSYSMENU);
if (Flags & TPM_LAYOUTRTL) Rect.left;
NcGetSysPopupPos(MenuInfo->Wnd, &Rect);
Rect.top = Rect.bottom;
Rect.right = GetSystemMetrics(SM_CXSIZE);
Rect.bottom = GetSystemMetrics(SM_CYSIZE);
}
else
{
{
GetWindowRect(MenuInfo->Wnd, &Rect);
if (0 != (MenuInfo->Flags & MF_POPUP))
{
Rect.left += ItemInfo.Rect.right - GetSystemMetrics(SM_CXBORDER);
Rect.top += ItemInfo.Rect.top - 3;
if (0 != (MenuInfo->Flags & MNF_POPUP))
{
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 - 3 - 2
- GetSystemMetrics(SM_CYBORDER);
}
Rect.bottom = ItemInfo.Rect.top - ItemInfo.Rect.bottom - MENU_TOP_MARGIN - MENU_BOTTOM_MARGIN/*2*/
- GetSystemMetrics(SM_CYBORDER);
}
else
{
Rect.left += ItemInfo.Rect.left;
{
if(Flags & TPM_LAYOUTRTL)
Rect.left += Rect.right - ItemInfo.Rect.left;
else
Rect.left += ItemInfo.Rect.left;
Rect.top += ItemInfo.Rect.bottom;
Rect.right = ItemInfo.Rect.right - ItemInfo.Rect.left;
Rect.bottom = ItemInfo.Rect.bottom - ItemInfo.Rect.top;
}
}
}
}
/* use default alignment for submenus */
Flags &= ~(TPM_CENTERALIGN | TPM_RIGHTALIGN | TPM_VCENTERALIGN | TPM_BOTTOMALIGN);
MenuShowPopup(WndOwner, ItemInfo.hSubMenu, MenuInfo->FocusedItem, Flags,
Rect.left, Rect.top, Rect.right, Rect.bottom );
if (SelectFirst && MenuGetRosMenuInfo(&SubMenuInfo, ItemInfo.hSubMenu))
{
{
MenuMoveSelection(WndOwner, &SubMenuInfo, ITEM_NEXT);
}
}
Ret = ItemInfo.hSubMenu;
MenuCleanupRosMenuItemInfo(&ItemInfo);
@ -2484,7 +2482,7 @@ MenuSwitchTracking(MTRACKER* Mt, PROSMENUINFO PtMenuInfo, UINT Index, UINT wFlag
if (MenuGetRosMenuInfo(&TopMenuInfo, Mt->TopMenu) &&
Mt->TopMenu != PtMenuInfo->Self &&
0 == ((PtMenuInfo->Flags | TopMenuInfo.Flags) & MF_POPUP))
0 == ((PtMenuInfo->Flags | TopMenuInfo.Flags) & MNF_POPUP))
{
/* both are top level menus (system and menu-bar) */
MenuHideSubPopups(Mt->OwnerWnd, &TopMenuInfo, FALSE, wFlags);
@ -2540,17 +2538,20 @@ MenuExecFocusedItem(MTRACKER *Mt, PROSMENUINFO MenuInfo, UINT Flags)
do not send a message to the owner */
if (0 == (Flags & TPM_RETURNCMD))
{
if (0 != (MenuInfo->Flags & MF_SYSMENU))
if (0 != (MenuInfo->Flags & MNF_SYSDESKMN))
{
PostMessageW(Mt->OwnerWnd, WM_SYSCOMMAND, ItemInfo.wID,
MAKELPARAM((SHORT) Mt->Pt.x, (SHORT) Mt->Pt.y));
}
else
{
if (MenuInfo->dwStyle & MNS_NOTIFYBYPOS)
PostMessageW(Mt->OwnerWnd, WM_MENUCOMMAND,
MenuInfo->FocusedItem,
(LPARAM)MenuInfo->Self);
BOOL ret;
ROSMENUINFO topmenuI;
ret = MenuGetRosMenuInfo(&topmenuI, Mt->TopMenu);
DWORD dwStyle = MenuInfo->dwStyle | (ret ? topmenuI.dwStyle : 0);
if (dwStyle & MNS_NOTIFYBYPOS)
PostMessageW(Mt->OwnerWnd, WM_MENUCOMMAND, MenuInfo->FocusedItem, (LPARAM)MenuInfo->Self);
else
PostMessageW(Mt->OwnerWnd, WM_COMMAND, ItemInfo.wID, 0);
}
@ -2726,7 +2727,7 @@ MenuPtMenu(HMENU Menu, POINT Pt)
/* check the current window (avoiding WM_HITTEST) */
Ht = DefWndNCHitTest(MenuInfo.Wnd, Pt);
if (0 != (MenuInfo.Flags & MF_POPUP))
if (0 != (MenuInfo.Flags & MNF_POPUP))
{
if (HTNOWHERE != Ht && HTERROR != Ht)
{
@ -2977,20 +2978,20 @@ MenuSuspendPopup(MTRACKER* Mt, UINT uMsg)
switch( uMsg )
{
case WM_KEYDOWN:
PeekMessageW( &msg, 0, 0, 0, PM_NOYIELD | PM_NOREMOVE);
if( msg.message == WM_KEYUP || msg.message == WM_PAINT )
{
PeekMessageW( &msg, 0, 0, 0, PM_NOYIELD | PM_REMOVE);
PeekMessageW( &msg, 0, 0, 0, PM_NOYIELD | PM_NOREMOVE);
if( msg.message == WM_KEYDOWN &&
(msg.wParam == VK_LEFT || msg.wParam == VK_RIGHT))
{
Mt->TrackFlags |= TF_SUSPENDPOPUP;
return TRUE;
}
}
break;
case WM_KEYDOWN:
PeekMessageW( &msg, 0, 0, 0, PM_NOYIELD | PM_NOREMOVE);
if( msg.message == WM_KEYUP || msg.message == WM_PAINT )
{
PeekMessageW( &msg, 0, 0, 0, PM_NOYIELD | PM_REMOVE);
PeekMessageW( &msg, 0, 0, 0, PM_NOYIELD | PM_NOREMOVE);
if( msg.message == WM_KEYDOWN &&
(msg.wParam == VK_LEFT || msg.wParam == VK_RIGHT))
{
Mt->TrackFlags |= TF_SUSPENDPOPUP;
return TRUE;
}
}
break;
}
/* failures go through this */
Mt->TrackFlags &= ~TF_SUSPENDPOPUP;
@ -3012,7 +3013,7 @@ MenuKeyEscape(MTRACKER *Mt, UINT Flags)
if (Mt->CurrentMenu != Mt->TopMenu)
{
if (MenuGetRosMenuInfo(&MenuInfo, Mt->CurrentMenu)
&& 0 != (MenuInfo.Flags & MF_POPUP))
&& 0 != (MenuInfo.Flags & MNF_POPUP))
{
MenuPrev = MenuTmp = Mt->TopMenu;
@ -3084,7 +3085,7 @@ MenuKeyLeft(MTRACKER* Mt, UINT Flags)
{
return;
}
if ((MenuPrev == Mt->TopMenu) && !(TopMenuInfo.Flags & MF_POPUP))
if ((MenuPrev == Mt->TopMenu) && !(TopMenuInfo.Flags & MNF_POPUP))
{
/* move menu bar selection if no more popups are left */
@ -3124,7 +3125,7 @@ static void FASTCALL MenuKeyRight(MTRACKER *Mt, UINT Flags)
Mt->CurrentMenu, Mt->TopMenu);
if (! MenuGetRosMenuInfo(&MenuInfo, Mt->TopMenu)) return;
if ((MenuInfo.Flags & MF_POPUP) || (Mt->CurrentMenu != Mt->TopMenu))
if ((MenuInfo.Flags & MNF_POPUP) || (Mt->CurrentMenu != Mt->TopMenu))
{
/* If already displaying a popup, try to display sub-popup */
@ -3154,7 +3155,7 @@ static void FASTCALL MenuKeyRight(MTRACKER *Mt, UINT Flags)
return;
}
if (!(MenuInfo.Flags & MF_POPUP)) /* menu bar tracking */
if (!(MenuInfo.Flags & MNF_POPUP)) /* menu bar tracking */
{
if (Mt->CurrentMenu != Mt->TopMenu)
{
@ -3265,7 +3266,7 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y,
}
if (!enterIdleSent)
{
HWND win = MenuInfo.Flags & MF_POPUP ? MenuInfo.Wnd : NULL;
HWND win = MenuInfo.Flags & MNF_POPUP ? MenuInfo.Wnd : NULL;
enterIdleSent = TRUE;
SendMessageW( mt.OwnerWnd, WM_ENTERIDLE, MSGF_MENU, (LPARAM) win);
}
@ -3384,7 +3385,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 & MF_POPUP))
if (!(MenuInfo.Flags & MNF_POPUP))
{
if (MenuGetRosMenuInfo(&MenuInfo, mt.TopMenu))
mt.CurrentMenu = MenuShowSubPopup(mt.OwnerWnd, &MenuInfo, TRUE, wFlags);
@ -3507,16 +3508,15 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y,
{
MenuHideSubPopups(mt.OwnerWnd, &MenuInfo, FALSE, wFlags);
if (MenuInfo.Flags & MF_POPUP)
if (MenuInfo.Flags & MNF_POPUP)
{
IntNotifyWinEvent(EVENT_SYSTEM_MENUPOPUPEND, MenuInfo.Wnd, OBJID_CLIENT, CHILDID_SELF, 0);
DestroyWindow(MenuInfo.Wnd);
MenuInfo.Wnd = NULL;
if (!(MenuInfo.Flags & TPM_NONOTIFY))
if (!(wFlags & TPM_NONOTIFY))
SendMessageW( mt.OwnerWnd, WM_UNINITMENUPOPUP, (WPARAM)mt.TopMenu,
MAKELPARAM(0, IS_SYSTEM_MENU(&MenuInfo)) );
}
MenuSelectItem( mt.OwnerWnd, &MenuInfo, NO_SELECTED_ITEM, FALSE, 0 );
}
@ -3584,7 +3584,7 @@ static BOOL FASTCALL MenuInitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT
IntNotifyWinEvent( EVENT_SYSTEM_MENUSTART,
hWnd,
MenuInfo.Flags & MF_SYSMENU ? OBJID_SYSMENU : OBJID_MENU,
MenuInfo.Flags & MNF_SYSDESKMN ? OBJID_SYSMENU : OBJID_MENU,
CHILDID_SELF, 0);
return TRUE;
}
@ -3615,6 +3615,7 @@ VOID MenuTrackMouseMenuBar( HWND hWnd, ULONG ht, POINT pt)
TRACE("wnd=%p ht=0x%04x (%ld,%ld)\n", hWnd, ht, pt.x, pt.y);
if (GetWindowLongW( hWnd, GWL_EXSTYLE ) & WS_EX_LAYOUTRTL) wFlags |= TPM_LAYOUTRTL;
if (IsMenu(hMenu))
{
/* map point to parent client coordinates */
@ -3716,6 +3717,7 @@ BOOL WINAPI TrackPopupMenuEx( HMENU Menu, UINT Flags, int x, int y,
/* ReactOS Check */
if (!ValidateHwnd(Wnd))
{
/* invalid window see wine menu.c test_menu_trackpopupmenu line 3146 */
return FALSE;
}
@ -4815,7 +4817,7 @@ LoadMenuIndirectW(CONST MENUTEMPLATE *lpMenuTemplate)
offset = GET_WORD(p);
p += sizeof(WORD) + offset;
if (!(hMenu = CreateMenu())) return 0;
if (!MENU_ParseResource(p, hMenu, TRUE))
if (!MENU_ParseResource(p, hMenu))
{
DestroyMenu(hMenu);
return 0;
@ -4897,7 +4899,7 @@ ModifyMenuA(
if(!MenuGetRosMenuItemInfo( hMnu, uPosition, &rmii)) return FALSE;
if ((rmii.hSubMenu) && (uFlags & MF_POPUP) && (rmii.hSubMenu != (HMENU)uIDNewItem))
if (rmii.hSubMenu && (uFlags & MF_POPUP) && (rmii.hSubMenu != (HMENU)uIDNewItem))
NtUserDestroyMenu( rmii.hSubMenu ); /* ModifyMenu() spec */
MenuCleanupRosMenuItemInfo( &rmii );
@ -4944,7 +4946,7 @@ ModifyMenuW(
if(!MenuGetRosMenuItemInfo( hMnu, uPosition, &rmii)) return FALSE;
if ((rmii.hSubMenu) && (uFlags & MF_POPUP) && (rmii.hSubMenu != (HMENU)uIDNewItem))
if (rmii.hSubMenu && (uFlags & MF_POPUP) && (rmii.hSubMenu != (HMENU)uIDNewItem))
NtUserDestroyMenu( rmii.hSubMenu ); /* ModifyMenu() spec */
MenuCleanupRosMenuItemInfo( &rmii );

View file

@ -88,7 +88,8 @@ GRAPHICS_BUFFER_Initialize(OUT PCONSOLE_SCREEN_BUFFER* Buffer,
/* We do not use anything else than uncompressed bitmaps */
if (GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biCompression != BI_RGB)
{
DPRINT1("biCompression == %d != BI_RGB, correct that!\n", GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biCompression);
DPRINT1("biCompression == %d != BI_RGB, fix that!\n",
GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biCompression);
GraphicsInfo->Info.lpBitMapInfo->bmiHeader.biCompression = BI_RGB;
}

View file

@ -585,6 +585,78 @@ ConioWriteConsole(PCONSOLE Console,
return STATUS_SUCCESS;
}
NTSTATUS NTAPI
ConDrvChangeScreenBufferAttributes(IN PCONSOLE Console,
IN PTEXTMODE_SCREEN_BUFFER Buffer,
IN USHORT NewScreenAttrib,
IN USHORT NewPopupAttrib)
{
DWORD X, Y, Length;
PCHAR_INFO Ptr;
COORD TopLeft = {0};
ULONG NumCodesToWrite = Buffer->ScreenBufferSize.X * Buffer->ScreenBufferSize.Y;
USHORT OldScreenAttrib = Buffer->ScreenDefaultAttrib;
if (Console == NULL || Buffer == NULL)
{
return STATUS_INVALID_PARAMETER;
}
/* Validity check */
ASSERT(Console == Buffer->Header.Console);
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
while (Length--)
{
// Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work either
Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X];
/*
* Change the current colors only if they are the old ones.
*/
/* Foreground color */
if ((Ptr->Attributes & 0x0F) == (OldScreenAttrib & 0x0F))
Ptr->Attributes = (Ptr->Attributes & 0xFFF0) | (NewScreenAttrib & 0x0F);
/* Background color */
if ((Ptr->Attributes & 0xF0) == (OldScreenAttrib & 0xF0))
Ptr->Attributes = (Ptr->Attributes & 0xFF0F) | (NewScreenAttrib & 0xF0);
// ++Ptr;
if (++X == Buffer->ScreenBufferSize.X)
{
X = 0;
if (++Y == Buffer->ScreenBufferSize.Y)
{
Y = 0;
}
}
}
/* Save foreground and background colors for both screen and popup */
Buffer->ScreenDefaultAttrib = (NewScreenAttrib & 0x00FF);
Buffer->PopupDefaultAttrib = (NewPopupAttrib & 0x00FF);
/* Refresh the display if needed */
if ((PCONSOLE_SCREEN_BUFFER)Buffer == Console->ActiveBuffer)
{
SMALL_RECT UpdateRect;
ConioComputeUpdateRect(Buffer, &UpdateRect, &TopLeft, NumCodesToWrite);
TermDrawRegion(Console, &UpdateRect);
}
return STATUS_SUCCESS;
}
/* PUBLIC DRIVER APIS *********************************************************/
@ -947,7 +1019,6 @@ ConDrvWriteConsoleOutputString(IN PCONSOLE Console,
PWCHAR tmpString = NULL;
DWORD X, Y, Length; // , Written = 0;
ULONG CodeSize;
SMALL_RECT UpdateRect;
PCHAR_INFO Ptr;
if (Console == NULL || Buffer == NULL ||
@ -1046,6 +1117,7 @@ ConDrvWriteConsoleOutputString(IN PCONSOLE Console,
if ((PCONSOLE_SCREEN_BUFFER)Buffer == Console->ActiveBuffer)
{
SMALL_RECT UpdateRect;
ConioComputeUpdateRect(Buffer, &UpdateRect, WriteCoord, NumCodesToWrite);
TermDrawRegion(Console, &UpdateRect);
}
@ -1071,7 +1143,6 @@ ConDrvFillConsoleOutput(IN PCONSOLE Console,
{
DWORD X, Y, Length; // , Written = 0;
PCHAR_INFO Ptr;
SMALL_RECT UpdateRect;
if (Console == NULL || Buffer == NULL || Code == NULL ||
WriteCoord == NULL /* || CodesWritten == NULL */)
@ -1144,6 +1215,7 @@ ConDrvFillConsoleOutput(IN PCONSOLE Console,
if ((PCONSOLE_SCREEN_BUFFER)Buffer == Console->ActiveBuffer)
{
SMALL_RECT UpdateRect;
ConioComputeUpdateRect(Buffer, &UpdateRect, WriteCoord, NumCodesToWrite);
TermDrawRegion(Console, &UpdateRect);
}

View file

@ -16,19 +16,100 @@
/* FUNCTIONS ******************************************************************/
VOID
GuiCopyFromGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer)
GuiCopyFromGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer,
PGUI_CONSOLE_DATA GuiData)
{
/*
* This function supposes that the system clipboard was opened.
*/
// PCONSOLE Console = Buffer->Header.Console;
PCONSOLE Console = Buffer->Header.Console;
UNIMPLEMENTED;
HDC hMemDC;
HBITMAP hBitmapTarget, hBitmapOld;
HPALETTE hPalette, hPaletteOld;
ULONG selWidth, selHeight;
if (Buffer->BitMap == NULL) return;
selWidth = Console->Selection.srSelection.Right - Console->Selection.srSelection.Left + 1;
selHeight = Console->Selection.srSelection.Bottom - Console->Selection.srSelection.Top + 1;
DPRINT1("Selection is (%d|%d) to (%d|%d)\n",
Console->Selection.srSelection.Left,
Console->Selection.srSelection.Top,
Console->Selection.srSelection.Right,
Console->Selection.srSelection.Bottom);
hMemDC = CreateCompatibleDC(GuiData->hMemDC);
if (hMemDC == NULL) return;
/* Allocate a bitmap to be given to the clipboard, so it will not be freed here */
hBitmapTarget = CreateCompatibleBitmap(GuiData->hMemDC, selWidth, selHeight);
if (hBitmapTarget == NULL)
{
DeleteDC(hMemDC);
return;
}
/* Select the new bitmap */
hBitmapOld = SelectObject(hMemDC, hBitmapTarget);
/* Change the palette in hMemDC if the current palette does exist */
if (Buffer->PaletteHandle == NULL)
hPalette = GuiData->hSysPalette;
else
hPalette = Buffer->PaletteHandle;
if (hPalette) hPaletteOld = SelectPalette(hMemDC, hPalette, FALSE);
/* Grab the mutex */
NtWaitForSingleObject(Buffer->Mutex, FALSE, NULL);
// The equivalent of a SetDIBitsToDevice call...
// It seems to be broken: it does not copy the tail of the bitmap.
// http://wiki.allegro.cc/index.php?title=StretchDIBits
#if 0
StretchDIBits(hMemDC,
0, 0,
selWidth, selHeight,
Console->Selection.srSelection.Left,
Console->Selection.srSelection.Top,
selWidth, selHeight,
Buffer->BitMap,
Buffer->BitMapInfo,
Buffer->BitMapUsage,
SRCCOPY);
#else
SetDIBitsToDevice(hMemDC,
/* Coordinates / size of the repainted rectangle, in the framebuffer's frame */
0, 0,
selWidth, selHeight,
/* Coordinates / size of the corresponding image portion, in the graphics screen-buffer's frame */
Console->Selection.srSelection.Left,
Console->Selection.srSelection.Top,
0,
Buffer->ScreenBufferSize.Y, // == Buffer->BitMapInfo->bmiHeader.biHeight
Buffer->BitMap,
Buffer->BitMapInfo,
Buffer->BitMapUsage);
#endif
/* Release the mutex */
NtReleaseMutant(Buffer->Mutex, NULL);
/* Restore the palette and the old bitmap */
if (hPalette) SelectPalette(hMemDC, hPaletteOld, FALSE);
SelectObject(hMemDC, hBitmapOld);
EmptyClipboard();
SetClipboardData(CF_BITMAP, hBitmapTarget);
DeleteDC(hMemDC);
}
VOID
GuiPasteToGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer)
GuiPasteToGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer,
PGUI_CONSOLE_DATA GuiData)
{
/*
* This function supposes that the system clipboard was opened.

View file

@ -52,7 +52,7 @@ typedef struct _GUI_CONSOLE_DATA
HWND hWindow; /* Handle to the console's window */
HDC hMemDC; /* Memory DC holding the console framebuffer */
HBITMAP hBitmap; /* Console framebuffer */
HBITMAP hBitmap; /* Console framebuffer */
HPALETTE hSysPalette; /* Handle to the original system palette */
HICON hIcon; /* Handle to the console's icon (big) */

View file

@ -1333,8 +1333,12 @@ Quit:
return 0;
}
VOID GuiCopyFromTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer);
VOID GuiCopyFromGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer);
VOID
GuiCopyFromTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
PGUI_CONSOLE_DATA GuiData);
VOID
GuiCopyFromGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer,
PGUI_CONSOLE_DATA GuiData);
static VOID
GuiConsoleCopy(PGUI_CONSOLE_DATA GuiData)
@ -1346,11 +1350,11 @@ GuiConsoleCopy(PGUI_CONSOLE_DATA GuiData)
if (GetType(Buffer) == TEXTMODE_BUFFER)
{
GuiCopyFromTextModeBuffer((PTEXTMODE_SCREEN_BUFFER)Buffer);
GuiCopyFromTextModeBuffer((PTEXTMODE_SCREEN_BUFFER)Buffer, GuiData);
}
else /* if (GetType(Buffer) == GRAPHICS_BUFFER) */
{
GuiCopyFromGraphicsBuffer((PGRAPHICS_SCREEN_BUFFER)Buffer);
GuiCopyFromGraphicsBuffer((PGRAPHICS_SCREEN_BUFFER)Buffer, GuiData);
}
CloseClipboard();
@ -1361,8 +1365,12 @@ GuiConsoleCopy(PGUI_CONSOLE_DATA GuiData)
}
}
VOID GuiPasteToTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer);
VOID GuiPasteToGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer);
VOID
GuiPasteToTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
PGUI_CONSOLE_DATA GuiData);
VOID
GuiPasteToGraphicsBuffer(PGRAPHICS_SCREEN_BUFFER Buffer,
PGUI_CONSOLE_DATA GuiData);
static VOID
GuiConsolePaste(PGUI_CONSOLE_DATA GuiData)
@ -1373,11 +1381,11 @@ GuiConsolePaste(PGUI_CONSOLE_DATA GuiData)
if (GetType(Buffer) == TEXTMODE_BUFFER)
{
GuiPasteToTextModeBuffer((PTEXTMODE_SCREEN_BUFFER)Buffer);
GuiPasteToTextModeBuffer((PTEXTMODE_SCREEN_BUFFER)Buffer, GuiData);
}
else /* if (GetType(Buffer) == GRAPHICS_BUFFER) */
{
GuiPasteToGraphicsBuffer((PGRAPHICS_SCREEN_BUFFER)Buffer);
GuiPasteToGraphicsBuffer((PGRAPHICS_SCREEN_BUFFER)Buffer, GuiData);
}
CloseClipboard();
@ -1909,6 +1917,8 @@ GuiConsoleWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
EnableMenuItem(hMenu, ID_SYSTEM_EDIT_COPY , MF_BYCOMMAND |
((Console->Selection.dwFlags & CONSOLE_SELECTION_IN_PROGRESS) &&
(Console->Selection.dwFlags & CONSOLE_SELECTION_NOT_EMPTY) ? MF_ENABLED : MF_GRAYED));
// FIXME: Following whether the active screen buffer is text-mode
// or graphics-mode, search for CF_UNICODETEXT or CF_BITMAP formats.
EnableMenuItem(hMenu, ID_SYSTEM_EDIT_PASTE, MF_BYCOMMAND |
(!(Console->Selection.dwFlags & CONSOLE_SELECTION_IN_PROGRESS) &&
IsClipboardFormatAvailable(CF_UNICODETEXT) ? MF_ENABLED : MF_GRAYED));

View file

@ -30,7 +30,8 @@ COLORREF RGBFromAttrib2(PCONSOLE Console, WORD Attribute)
}
VOID
GuiCopyFromTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer)
GuiCopyFromTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
PGUI_CONSOLE_DATA GuiData)
{
/*
* This function supposes that the system clipboard was opened.
@ -72,12 +73,16 @@ GuiCopyFromTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer)
size += 1; /* Null-termination */
size *= sizeof(WCHAR);
/* Allocate memory, it will be passed to the system and may not be freed here */
/* Allocate some memory area to be given to the clipboard, so it will not be freed here */
hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, size);
if (hData == NULL) return;
data = GlobalLock(hData);
if (data == NULL) return;
if (data == NULL)
{
GlobalFree(hData);
return;
}
DPRINT("Copying %dx%d selection\n", selWidth, selHeight);
dstPos = data;
@ -121,7 +126,8 @@ GuiCopyFromTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer)
}
VOID
GuiPasteToTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer)
GuiPasteToTextModeBuffer(PTEXTMODE_SCREEN_BUFFER Buffer,
PGUI_CONSOLE_DATA GuiData)
{
/*
* This function supposes that the system clipboard was opened.

View file

@ -436,7 +436,11 @@ ConSrvGetDefaultSettings(IN OUT PCONSOLE_INFO ConsoleInfo,
}
}
NTSTATUS NTAPI
ConDrvChangeScreenBufferAttributes(IN PCONSOLE Console,
IN PTEXTMODE_SCREEN_BUFFER Buffer,
IN USHORT NewScreenAttrib,
IN USHORT NewPopupAttrib);
/*
* NOTE: This function explicitely references Console->ActiveBuffer.
* It is possible that it should go into some frontend...
@ -455,26 +459,10 @@ ConSrvApplyUserSettings(IN PCONSOLE Console,
Console->QuickEdit = ConsoleInfo->QuickEdit;
Console->InsertMode = ConsoleInfo->InsertMode;
/*
* Apply foreground and background colors for both screen and popup
* and copy the new palette.
*/
if (GetType(ActiveBuffer) == TEXTMODE_BUFFER)
{
PTEXTMODE_SCREEN_BUFFER Buffer = (PTEXTMODE_SCREEN_BUFFER)ActiveBuffer;
Buffer->ScreenDefaultAttrib = ConsoleInfo->ScreenAttrib;
Buffer->PopupDefaultAttrib = ConsoleInfo->PopupAttrib;
}
else // if (Console->ActiveBuffer->Header.Type == GRAPHICS_BUFFER)
{
}
/* Copy the new console palette */
// FIXME: Possible buffer overflow if s_colors is bigger than pConInfo->Colors.
memcpy(Console->Colors, ConsoleInfo->Colors, sizeof(s_Colors));
// TODO: Really update the screen attributes as FillConsoleOutputAttribute does.
/* Apply cursor size */
ActiveBuffer->CursorInfo.bVisible = (ConsoleInfo->CursorSize != 0);
ActiveBuffer->CursorInfo.dwSize = min(max(ConsoleInfo->CursorSize, 0), 100);
@ -537,6 +525,12 @@ ConSrvApplyUserSettings(IN PCONSOLE Console,
if (SizeChanged) TermResizeTerminal(Console);
}
/* Apply foreground and background colors for both screen and popup */
ConDrvChangeScreenBufferAttributes(Console,
Buffer,
ConsoleInfo->ScreenAttrib,
ConsoleInfo->PopupAttrib);
}
else // if (GetType(ActiveBuffer) == GRAPHICS_BUFFER)
{