* Sync up to trunk head (r64894).

svn path=/branches/shell-experiments/; revision=64895
This commit is contained in:
Amine Khaldi 2014-10-22 17:07:43 +00:00
commit 06e986393a
111 changed files with 3765 additions and 1930 deletions

View file

@ -6,6 +6,11 @@ if(POLICY CMP0017)
cmake_policy(SET CMP0017 OLD)
endif()
if(POLICY CMP0026)
# Allow use of the LOCATION property
cmake_policy(SET CMP0026 OLD)
endif()
project(REACTOS)
# Versioning

View file

@ -16,6 +16,7 @@
#include <winbase.h>
#include <winuser.h>
#include <wincon.h>
#include <strsafe.h>
#include "help.h"
#include "resource.h"
@ -135,9 +136,8 @@ int wmain(int argc, WCHAR* argv[])
/*
* Run "<command> /?" in the current command processor.
*/
wcsncpy(CmdLine, argv[1], CMDLINE_LENGTH - wcslen(CmdLine));
wcsncat(CmdLine, L" /?" , CMDLINE_LENGTH - wcslen(CmdLine));
StringCbPrintfW(CmdLine, sizeof(CmdLine), L"%ls /?", argv[1]);
_flushall();
return _wsystem(CmdLine);
}

View file

@ -187,19 +187,16 @@ GetServices ( void )
return;
}
}
if (pServiceFailureActions->cActions)
{
if (pServiceFailureActions->lpsaActions[0].Type == SC_ACTION_REBOOT)
{
LoadString(hInst, IDS_SERVICES_YES, szStatus, 128);
item.pszText = szStatus;
item.iSubItem = 1;
SendMessage(hServicesListCtrl, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);
}
}
if (pServiceFailureActions != NULL)
{
if (pServiceFailureActions->cActions && pServiceFailureActions->lpsaActions[0].Type == SC_ACTION_REBOOT)
{
LoadString(hInst, IDS_SERVICES_YES, szStatus, 128);
item.pszText = szStatus;
item.iSubItem = 1;
SendMessage(hServicesListCtrl, LVM_SETITEMTEXT, item.iItem, (LPARAM) &item);
}
HeapFree(GetProcessHeap(), 0, pServiceFailureActions);
pServiceFailureActions = NULL;
}

View file

@ -97,7 +97,11 @@ GetDisabledAutostartEntriesFromRegistry (TCHAR * szBasePath)
if (Data == NULL)
break;
RegEnumKeyEx(hKey, Index, szValueName, &dwValueLength, NULL, NULL, NULL, NULL);
if(RegEnumKeyEx(hKey, Index, szValueName, &dwValueLength, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
{
HeapFree(GetProcessHeap(), 0, Data);
continue;
}
_stprintf(szSubPath, _T("%s\\%s"), szBasePath, szValueName);
memset(&item, 0, sizeof(LV_ITEM));
item.mask = LVIF_TEXT;

View file

@ -52,7 +52,7 @@ SaveServicesToFile(PMAIN_WND_INFO Info,
if(hFile != INVALID_HANDLE_VALUE)
{
TCHAR LVText[500];
TCHAR newl = _T('\n');
TCHAR newl[2] = {_T('\r'), _T('\n')};
TCHAR tab = _T('\t');
DWORD dwTextLength, dwWritten;
INT NumListedServ = 0;
@ -68,7 +68,7 @@ SaveServicesToFile(PMAIN_WND_INFO Info,
LVText,
i,
k);
if (LVText != NULL)
if (_tcslen(LVText))
{
WriteFile(hFile,
LVText,
@ -84,8 +84,8 @@ SaveServicesToFile(PMAIN_WND_INFO Info,
}
}
WriteFile(hFile,
&newl,
sizeof(TCHAR),
newl,
sizeof(newl),
&dwWritten,
NULL);
}

View file

@ -204,10 +204,11 @@ VOID SetMenuAndButtonStates(PMAIN_WND_INFO Info)
SendMessage(Info->hTool, TB_SETSTATE, ID_RESTART,
(LPARAM)MAKELONG(TBSTATE_ENABLED, 0));
}
HeapFree(GetProcessHeap(), 0, lpServiceConfig);
}
if(lpServiceConfig)
HeapFree(GetProcessHeap(), 0, lpServiceConfig);
if ( (Flags & SERVICE_ACCEPT_STOP) && (State == SERVICE_RUNNING) )
{
EnableMenuItem(hMainMenu, ID_STOP, MF_ENABLED);

View file

@ -167,9 +167,7 @@ CreateProgressDialog(HWND hParent,
0,
(LPARAM)lpProgStr);
HeapFree(GetProcessHeap(),
0,
lpProgStr);
LocalFree(lpProgStr);
}
/* Finally, show and update the progress dialog */

View file

@ -33,7 +33,6 @@ SetButtonStates(PSERVICEPROPSHEET dlgInfo,
{
hButton = GetDlgItem(hwndDlg, IDC_START);
EnableWindow (hButton, TRUE);
HeapFree(GetProcessHeap(), 0, lpServiceConfig);
}
else if ( (Flags & SERVICE_ACCEPT_STOP) && (State == SERVICE_RUNNING) )
{
@ -46,6 +45,9 @@ SetButtonStates(PSERVICEPROPSHEET dlgInfo,
EnableWindow (hButton, TRUE);
}
if(lpServiceConfig)
HeapFree(GetProcessHeap(), 0, lpServiceConfig);
hButton = GetDlgItem(hwndDlg, IDC_START_PARAM);
EnableWindow(hButton, (State == SERVICE_STOPPED));

View file

@ -270,6 +270,7 @@ GetServiceList(PMAIN_WND_INFO Info,
HeapFree(ProcessHeap,
0,
Info->pAllServices);
Info->pAllServices = NULL;
}
ScHandle = OpenSCManager(NULL,
@ -319,7 +320,7 @@ GetServiceList(PMAIN_WND_INFO Info,
if (ScHandle)
CloseServiceHandle(ScHandle);
if (!bRet)
if (!bRet && Info->pAllServices)
{
HeapFree(ProcessHeap,
0,

View file

@ -163,6 +163,8 @@ AddServiceNamesToStop(HWND hServiceListBox,
LB_ADDSTRING,
0,
(LPARAM)lpServiceConfig->lpDisplayName);
HeapFree(GetProcessHeap(), 0, lpServiceConfig);
}
/* Move onto the next string */

View file

@ -4,11 +4,12 @@ add_definitions(-D__USE_W32_SOCKETS)
list(APPEND SOURCE
main.c
cmdAccounts.c
cmdContinue.c
cmdHelpMsg.c
cmdLocalGroup.c
cmdPause.c
cmdStart.c
cmdStop.c
cmdHelpMsg.c
cmdPause.c
cmdContinue.c
help.c
net.h)

View file

@ -24,7 +24,9 @@ cmdAccounts(
ULONG value;
INT i;
BOOL Modified = FALSE;
// BOOL Domain = FALSE;
#if 0
BOOL Domain = FALSE;
#endif
NET_API_STATUS Status;
INT result = 0;
@ -44,12 +46,13 @@ cmdAccounts(
return 0;
}
/*
if (_wcsicmp(argv[i], L"/domain") == 0)
{
printf("The /DOMAIN option is not supported yet!\n");
#if 0
Domain = TRUE;
#endif
}
*/
}
Status = NetUserModalsGet(NULL, 0, (LPBYTE*)&Info0);

View file

@ -0,0 +1,282 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS net command
* FILE:
* PURPOSE:
*
* PROGRAMMERS: Eric Kohl
*/
#include "net.h"
static
int
CompareInfo(const void *a,
const void *b)
{
return _wcsicmp(((PLOCALGROUP_INFO_0)a)->lgrpi0_name,
((PLOCALGROUP_INFO_0)b)->lgrpi0_name);
}
static
NET_API_STATUS
EnumerateLocalGroups(VOID)
{
PLOCALGROUP_INFO_0 pBuffer = NULL;
PSERVER_INFO_100 pServer = NULL;
DWORD dwRead = 0, dwTotal = 0;
DWORD i;
DWORD_PTR ResumeHandle = 0;
NET_API_STATUS Status;
Status = NetServerGetInfo(NULL,
100,
(LPBYTE*)&pServer);
if (Status != NERR_Success)
return Status;
printf("\nAliases for \\\\%S\n\n", pServer->sv100_name);
printf("------------------------------------------\n");
NetApiBufferFree(pServer);
Status = NetLocalGroupEnum(NULL,
0,
(LPBYTE*)&pBuffer,
MAX_PREFERRED_LENGTH,
&dwRead,
&dwTotal,
&ResumeHandle);
if (Status != NERR_Success)
return Status;
qsort(pBuffer,
dwRead,
sizeof(PLOCALGROUP_INFO_0),
CompareInfo);
// printf("dwRead: %lu dwTotal: %lu\n", dwRead, dwTotal);
for (i = 0; i < dwRead; i++)
{
// printf("%p\n", pBuffer[i].lgrpi0_name);
if (pBuffer[i].lgrpi0_name)
printf("*%S\n", pBuffer[i].lgrpi0_name);
}
NetApiBufferFree(pBuffer);
return NERR_Success;
}
INT
cmdLocalGroup(
INT argc,
WCHAR **argv)
{
INT i, j;
INT result = 0;
ULONG dwMemberCount = 0;
BOOL bAdd = FALSE;
BOOL bDelete = FALSE;
#if 0
BOOL bDomain = FALSE;
#endif
LPWSTR lpGroupName = NULL;
LPWSTR lpComment = NULL;
LPLOCALGROUP_MEMBERS_INFO_3 lpMembers = NULL;
LOCALGROUP_INFO_0 Info0;
LOCALGROUP_INFO_1 Info1;
LOCALGROUP_INFO_1002 Info1002;
NET_API_STATUS Status;
if (argc == 2)
{
Status = EnumerateLocalGroups();
printf("Status: %lu\n", Status);
return 0;
}
i = 2;
if (argv[i][0] != L'/')
{
lpGroupName = argv[i];
i++;
}
for (j = i; j < argc; j++)
{
if (argv[j][0] == L'/')
break;
dwMemberCount++;
}
printf("Member count: %lu\n", dwMemberCount);
if (dwMemberCount > 0)
{
lpMembers = RtlAllocateHeap(RtlGetProcessHeap(),
HEAP_ZERO_MEMORY,
dwMemberCount * sizeof(LPLOCALGROUP_MEMBERS_INFO_3));
if (lpMembers == NULL)
return 0;
}
j = 0;
for (; i < argc; i++)
{
if (argv[i][0] == L'/')
break;
lpMembers[j].lgrmi3_domainandname = argv[i];
j++;
}
for (; i < argc; i++)
{
if (_wcsicmp(argv[i], L"/help") == 0)
{
PrintResourceString(IDS_LOCALGROUP_HELP);
return 0;
}
else if (_wcsicmp(argv[i], L"/add") == 0)
{
bAdd = TRUE;
}
else if (_wcsicmp(argv[i], L"/delete") == 0)
{
bDelete = TRUE;
}
else if (_wcsnicmp(argv[i], L"/comment:", 9) == 0)
{
lpComment = &argv[i][9];
}
else if (_wcsicmp(argv[i], L"/domain") == 0)
{
printf("The /DOMAIN option is not supported yet!\n");
#if 0
bDomain = TRUE;
#endif
}
else
{
result = 1;
goto done;
}
}
if (lpGroupName == NULL)
{
result = 1;
goto done;
}
if (bAdd && bDelete)
{
result = 1;
goto done;
}
#if 0
printf("Group:\n %S\n", lpGroupName);
if (lpMembers != NULL)
{
printf("\nMembers:\n");
for (i = 0; i < dwMemberCount; i++)
printf(" %S\n", lpMembers[i].lgrmi3_domainandname);
}
if (lpComment != NULL)
{
printf("\nComment:\n %S\n", lpComment);
}
#endif
if (lpMembers == NULL)
{
if (!bAdd && !bDelete && lpComment != NULL)
{
/* Set group comment */
Info1002.lgrpi1002_comment = lpComment;
Status = NetLocalGroupSetInfo(NULL,
lpGroupName,
1002,
(LPBYTE)&Info1002,
NULL);
printf("Status: %lu\n", Status);
}
else if (bAdd && !bDelete)
{
/* Add the group */
if (lpComment == NULL)
{
Info0.lgrpi0_name = lpGroupName;
}
else
{
Info1.lgrpi1_name = lpGroupName;
Info1.lgrpi1_comment = lpComment;
}
Status = NetLocalGroupAdd(NULL,
(lpComment == NULL) ? 0 : 1,
(lpComment == NULL) ? (LPBYTE)&Info0 : (LPBYTE)&Info1,
NULL);
printf("Status: %lu\n", Status);
}
else if (!bAdd && bDelete && lpComment == NULL)
{
/* Delete the group */
Status = NetLocalGroupDel(NULL,
lpGroupName);
printf("Status: %lu\n", Status);
}
else
{
result = 1;
}
}
else
{
if (bAdd && !bDelete && lpComment == NULL)
{
/* Add group members */
Status = NetLocalGroupAddMembers(NULL,
lpGroupName,
3,
(LPBYTE)lpMembers,
dwMemberCount);
printf("Status: %lu\n", Status);
}
else if (!bAdd && bDelete && lpComment == NULL)
{
/* Delete group members */
Status = NetLocalGroupDelMembers(NULL,
lpGroupName,
3,
(LPBYTE)lpMembers,
dwMemberCount);
printf("Status: %lu\n", Status);
}
else
{
result = 1;
}
}
done:
if (lpMembers != NULL)
RtlFreeHeap(RtlGetProcessHeap(), 0, lpMembers);
if (result != 0)
PrintResourceString(IDS_LOCALGROUP_SYNTAX);
return result;
}
/* EOF */

View file

@ -18,7 +18,9 @@ BEGIN
IDS_GROUP_HELP "GROUP\n..."
IDS_HELPMSG_SYNTAX "Usage:\nNET HELPMSG <Error Code>"
IDS_HELPMSG_HELP "HELPMSG\n..."
IDS_LOCALGROUP_SYNTAX "Usage:\nNET LOCALGROUP ..."
IDS_LOCALGROUP_SYNTAX "Usage:\nNET LOCALGROUP [groupname [/COMMENT:""text""]] [/DOMAIN]\n\
groupname {/ADD [/COMMENT:""text""] | /DELETE} [/DOMAIN]\n\
groupname name [...] {/ADD | /DELETE} [/DOMAIN]"
IDS_LOCALGROUP_HELP "LOCALGROUP\n..."
IDS_NAME_SYNTAX "Usage:\nNET NAME ..."
IDS_NAME_HELP "NAME\n..."

View file

@ -24,7 +24,9 @@ BEGIN
IDS_GROUP_HELP "GROUP\n..."
IDS_HELPMSG_SYNTAX "Utilizare:\nNET HELPMSG <Error Code>"
IDS_HELPMSG_HELP "HELPMSG\n..."
IDS_LOCALGROUP_SYNTAX "Utilizare:\nNET LOCALGROUP ..."
IDS_LOCALGROUP_SYNTAX "Utilizare:\nNET LOCALGROUP [groupname [/COMMENT:""text""]] [/DOMAIN]\n\
groupname {/ADD [/COMMENT:""text""] | /DELETE} [/DOMAIN]\n\
groupname name [...] {/ADD | /DELETE} [/DOMAIN]"
IDS_LOCALGROUP_HELP "LOCALGROUP\n..."
IDS_NAME_SYNTAX "Utilizare:\nNET NAME ..."
IDS_NAME_HELP "NAME\n..."

View file

@ -19,7 +19,9 @@ BEGIN
IDS_GROUP_HELP "GROUP\n..."
IDS_HELPMSG_SYNTAX "Использование:\nNET HELPMSG <Код ошибки>"
IDS_HELPMSG_HELP "HELPMSG\n..."
IDS_LOCALGROUP_SYNTAX "Использование:\nNET LOCALGROUP ..."
IDS_LOCALGROUP_SYNTAX "Использование:\nNET LOCALGROUP [groupname [/COMMENT:""text""]] [/DOMAIN]\n\
groupname {/ADD [/COMMENT:""text""] | /DELETE} [/DOMAIN]\n\
groupname name [...] {/ADD | /DELETE} [/DOMAIN]"
IDS_LOCALGROUP_HELP "LOCALGROUP\n..."
IDS_NAME_SYNTAX "Использование:\nNET NAME ..."
IDS_NAME_HELP "NAME\n..."

View file

@ -28,7 +28,7 @@ COMMAND cmds[] =
{L"group", unimplemented},
{L"help", cmdHelp},
{L"helpmsg", cmdHelpMsg},
{L"localgroup", unimplemented},
{L"localgroup", cmdLocalGroup},
{L"name", unimplemented},
{L"pause", cmdPause},
{L"print", unimplemented},

View file

@ -35,6 +35,7 @@ INT cmdAccounts(INT argc, WCHAR **argv);
INT cmdContinue(INT argc, WCHAR **argv);
INT cmdHelp(INT argc, WCHAR **argv);
INT cmdHelpMsg(INT argc, WCHAR **argv);
INT cmdLocalGroup(INT argc, WCHAR **argv);
INT cmdPause(INT argc, WCHAR **argv);
INT cmdStart(INT argc, WCHAR **argv);
INT cmdStop(INT argc, WCHAR **argv);

View file

@ -204,10 +204,13 @@ void UpdateColumnDataHints(void)
HDITEM hditem;
WCHAR text[260];
ULONG Index;
ULONG uItems;
WCHAR szTemp[256];
unsigned int i;
UINT i;
for (Index=0; Index<(ULONG)SendMessageW(hProcessPageHeaderCtrl, HDM_GETITEMCOUNT, 0, 0); Index++)
uItems = min(SendMessageW(hProcessPageHeaderCtrl, HDM_GETITEMCOUNT, 0, 0), COLUMN_NMAX);
for (Index=0; Index<uItems; Index++)
{
memset(&hditem, 0, sizeof(HDITEM));

View file

@ -120,17 +120,15 @@ void GraphCtrl_Dispose(TGraphCtrl* this)
if (this->m_brushBack != NULL) DeleteObject(this->m_brushBack);
}
BOOL GraphCtrl_Create(TGraphCtrl* this, HWND hWnd, HWND hParentWnd, UINT nID)
void GraphCtrl_Create(TGraphCtrl* this, HWND hWnd, HWND hParentWnd, UINT nID)
{
BOOL result = 0;
GraphCtrl_Init(this);
this->m_hParentWnd = hParentWnd;
this->m_hWnd = hWnd;
GraphCtrl_Resize(this);
if (result != 0)
GraphCtrl_InvalidateCtrl(this, FALSE);
return result;
return;
}
void GraphCtrl_SetRange(TGraphCtrl* this, double dLower, double dUpper, int nDecimalPlaces)

View file

@ -88,7 +88,7 @@ extern WNDPROC OldGraphCtrlWndProc;
double GraphCtrl_AppendPoint(TGraphCtrl* this,
double dNewPoint0, double dNewPoint1,
double dNewPoint2, double dNewPoint3);
BOOL GraphCtrl_Create(TGraphCtrl* this, HWND hWnd, HWND hParentWnd,
void GraphCtrl_Create(TGraphCtrl* this, HWND hWnd, HWND hParentWnd,
UINT nID);
void GraphCtrl_Dispose(TGraphCtrl* this);
void GraphCtrl_DrawPoint(TGraphCtrl* this);

View file

@ -152,15 +152,17 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
*/
/* Get a token for this process. */
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{
/* Get the LUID for the debug privilege. */
LookupPrivilegeValueW(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid);
if (LookupPrivilegeValueW(NULL, SE_DEBUG_NAME, &tkp.Privileges[0].Luid))
{
tkp.PrivilegeCount = 1; /* one privilege to set */
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
tkp.PrivilegeCount = 1; /* one privilege to set */
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
/* Get the debug privilege for this process. */
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
/* Get the debug privilege for this process. */
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
}
CloseHandle(hToken);
}
@ -168,7 +170,8 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
LoadSettings();
/* Initialize perf data */
if (!PerfDataInitialize()) {
if (!PerfDataInitialize())
{
return -1;
}

View file

@ -136,6 +136,7 @@ copy(TCHAR source[MAX_PATH],
_tcscat(TempSrc,_T(".decrypt"));
if (!CopyFileEx(source, TempSrc, NULL, NULL, FALSE, COPY_FILE_ALLOW_DECRYPTED_DESTINATION))
{
CloseHandle (hFileSrc);
nErrorLevel = 1;
return 0;
}
@ -766,6 +767,7 @@ INT cmd_copy(LPTSTR param)
/* Check Breaker */
if (CheckCtrlBreak(BREAK_INPUT))
{
FindClose(hFile);
freep(arg);
return 1;
}
@ -789,6 +791,7 @@ INT cmd_copy(LPTSTR param)
if (_tcscmp(tmpDestPath, _T("\\\\.\\")) &&
!IsExistingDirectory(tmpDestPath))
{
FindClose(hFile);
ConOutFormatMessage(GetLastError(), szSrcPath);
freep(arg);
nErrorLevel = 1;

View file

@ -382,7 +382,10 @@ BOOL DeleteFolder(LPTSTR FileName)
{
SetFileAttributes(TempFileName,FILE_ATTRIBUTE_NORMAL);
if (!DeleteFile(TempFileName))
{
FindClose (hFile);
return 0;
}
}
}while (FindNextFile (hFile, &f));

View file

@ -62,7 +62,7 @@ GetDateString(VOID)
INT len;
GetLocalTime(&t);
len = GetDateFormat(LOCALE_USER_DEFAULT, 0, &t, _T("ddd"), szDate, sizeof szDate);
len = GetDateFormat(LOCALE_USER_DEFAULT, 0, &t, _T("ddd"), szDate, sizeof(szDate) / sizeof(szDate[0]));
szDate[len - 1] = _T(' ');
FormatDate(&szDate[len], &t, TRUE);
return szDate;

View file

@ -100,7 +100,7 @@ INT cmd_move (LPTSTR param)
HANDLE hFile;
/* used only when source and destination directories are on different volume */
HANDLE hDestFile;
HANDLE hDestFile = NULL;
WIN32_FIND_DATA findDestBuffer;
TCHAR szMoveDest[MAX_PATH];
TCHAR szMoveSrc[MAX_PATH];
@ -505,6 +505,9 @@ INT cmd_move (LPTSTR param)
FindNextFile (hFile, &findBuffer));
FindClose (hFile);
if(hDestFile && hDestFile != INVALID_HANDLE_VALUE)
FindClose(hDestFile);
freep (arg);
return 0;
}

View file

@ -131,7 +131,10 @@ INT replace(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], DWORD dwFlags, BOOL *d
else
ConOutResPrintf(STRING_REPLACE_HELP10, dest);
if ( !FilePromptYNA (0))
{
CloseHandle (hFileSrc);
return 0;
}
}
/* Output depending on add flag */
@ -220,7 +223,7 @@ INT recReplace(DWORD dwFlags,
HANDLE hFile;
WIN32_FIND_DATA findBuffer;
/* Get file handel to the sourcefile(s) */
/* Get file handle to the sourcefile(s) */
hFile = FindFirstFile (szSrcPath, &findBuffer);
/*
@ -302,6 +305,8 @@ INT recReplace(DWORD dwFlags,
/* Take next sourcefile if any */
} while(FindNextFile (hFile, &findBuffer));
FindClose(hFile);
return filesReplaced;
}
@ -378,6 +383,8 @@ INT recFindSubDirs(DWORD dwFlags,
/* Get the next handle */
} while(FindNextFile (hFile, &findBuffer));
FindClose(hFile);
return filesReplaced;
}

View file

@ -110,7 +110,7 @@ public:
UINT cFiles = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0);
for(UINT i=0; i<cFiles; ++i) {
DragQueryFile(hDrop, i, szFileName, sizeof(szFileName));
DragQueryFile(hDrop, i, szFileName, sizeof(szFileName) / sizeof(szFileName[0]));
if (DROPEFFECT_COPY & *pdwEffect) {
// copy the file or dir

View file

@ -448,7 +448,6 @@ int WINAPI _tWinMain(
nRetValue = EXITCODE_FAILURE;
}
else {
FreeLibrary(hDll);
// DllInstall was not found, display an error message
lptMsgBuffer = (LPTSTR)malloc((_tcslen(MissingEntry) - 8 + _tcslen(tszDllInstall) * 2 + _tcslen(lptDllName) * 2 + 1) * sizeof(TCHAR));
_stprintf(lptMsgBuffer,MissingEntry,lptDllName,tszDllInstall,tszDllInstall,lptDllName);

View file

@ -77,6 +77,7 @@ if defined ROS_ARCH (
set CMAKE_GENERATOR="Visual Studio 11 Win64"
) else if "!ARCH!" == "arm" (
set CMAKE_GENERATOR="Visual Studio 11 ARM"
set CMAKE_GENERATOR_HOST="Visual Studio 11"
) else (
set CMAKE_GENERATOR="Visual Studio 11"
)
@ -85,6 +86,7 @@ if defined ROS_ARCH (
set CMAKE_GENERATOR="Visual Studio 12 Win64"
) else if "!ARCH!" == "arm" (
set CMAKE_GENERATOR="Visual Studio 12 ARM"
set CMAKE_GENERATOR_HOST="Visual Studio 12"
) else (
set CMAKE_GENERATOR="Visual Studio 12"
)
@ -116,6 +118,9 @@ if %USE_VSCMD% == 1 (
) else (
set CMAKE_GENERATOR="Ninja"
)
if "!ARCH!" == "arm" (
set CMAKE_GENERATOR_HOST=!CMAKE_GENERATOR!
)
)
:: Create directories
@ -146,7 +151,7 @@ set REACTOS_BUILD_TOOLS_DIR=%CD%
:: Use x86 for ARM host tools
if "%ARCH%" == "arm" (
:: Launch new script instance for x86 host tools configuration
start "Preparing host tools for ARM cross build..." /I /B /WAIT %~dp0configure.cmd arm_hosttools "%VSINSTALLDIR%VC\vcvarsall.bat" %CMAKE_GENERATOR%
start "Preparing host tools for ARM cross build..." /I /B /WAIT %~dp0configure.cmd arm_hosttools "%VSINSTALLDIR%VC\vcvarsall.bat" %CMAKE_GENERATOR_HOST%
) else (
cmake -G %CMAKE_GENERATOR% -DARCH:STRING=%ARCH% "%REACTOS_SOURCE_DIR%"
)

View file

@ -102,6 +102,10 @@ foreach(_keyboard_layout ${_keyboard_layouts})
add_target_link_flags(${_keyboard_layout} "-Wl,-T,${CMAKE_SOURCE_DIR}/kbdlayout.lds")
endif()
if (STACK_PROTECTOR)
target_link_libraries(${_keyboard_layout} gcc_ssp)
endif()
if(RUNTIME_CHECKS)
target_link_libraries(${_keyboard_layout} runtmchk)
endif()

View file

@ -586,7 +586,6 @@ DeviceProblemTextW(IN HMACHINE hMachine OPTIONAL,
&szProblem,
szInfo,
uProblemId);
LocalFree((HLOCAL)szInfo);
}
else
{

File diff suppressed because it is too large Load diff

View file

@ -3,7 +3,7 @@
#include <wine/unicode.h>
const WCHAR wine_casemap_lower[3802] =
const WCHAR wine_casemap_lower[3807] =
{
/* index */
0x01bf, 0x02bf, 0x03bf, 0x044f, 0x054f, 0x064f, 0x0100, 0x0100,
@ -26,7 +26,7 @@ const WCHAR wine_casemap_lower[3802] =
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0c1d, 0x0cfb,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0c22, 0x0d00,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
@ -37,7 +37,7 @@ const WCHAR wine_casemap_lower[3802] =
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0dda,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0ddf,
/* defaults */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@ -164,7 +164,7 @@ const WCHAR wine_casemap_lower[3802] =
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* 0x0370 .. 0x03ff */
0x0001, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0074,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0026, 0x0000,
0x0025, 0x0025, 0x0025, 0x0000, 0x0040, 0x0000, 0x003f, 0x003f,
0x0000, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020, 0x0020,
@ -219,8 +219,8 @@ const WCHAR wine_casemap_lower[3802] =
0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000,
0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000,
0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000,
0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000,
0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000,
0x0000, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030,
0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030,
0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030, 0x0030,
@ -252,8 +252,8 @@ const WCHAR wine_casemap_lower[3802] =
0x1c60, 0x1c60, 0x1c60, 0x1c60, 0x1c60, 0x1c60, 0x1c60, 0x1c60,
0x1c60, 0x1c60, 0x1c60, 0x1c60, 0x1c60, 0x1c60, 0x1c60, 0x1c60,
0x1c60, 0x1c60, 0x1c60, 0x1c60, 0x1c60, 0x1c60, 0x1c60, 0x1c60,
0x1c60, 0x1c60, 0x1c60, 0x1c60, 0x1c60, 0x1c60, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x1c60, 0x1c60, 0x1c60, 0x1c60, 0x1c60, 0x1c60, 0x0000, 0x1c60,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1c60, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@ -408,26 +408,27 @@ const WCHAR wine_casemap_lower[3802] =
0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000,
0x0001, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0000,
0x0000, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* 0xa612 .. 0xa6ff */
/* 0xa60d .. 0xa6ff */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000,
0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000,
0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000,
0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000,
0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000,
0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000,
0x0001, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000,
0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000,
0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000,
0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001,
0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001,
0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001,
0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001,
0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001,
0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001,
0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001,
0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001,
0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@ -440,7 +441,7 @@ const WCHAR wine_casemap_lower[3802] =
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000,
/* 0xa722 .. 0xa7ff */
0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000,
0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000,
@ -455,11 +456,11 @@ const WCHAR wine_casemap_lower[3802] =
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001,
0x0000, 0x0001, 0x0000, 0x75fc, 0x0001, 0x0000, 0x0001, 0x0000,
0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0000, 0x0000,
0x0000, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0001, 0x0000, 0x5ad8, 0x0000, 0x0000, 0x0001, 0x0000,
0x0001, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000,
0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000,
0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000, 0x0001, 0x0000,
0x5abc, 0x5ab1, 0x5ab5, 0x5abf, 0x0000, 0x0000, 0x5aee, 0x5ad6,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@ -634,15 +635,15 @@ const WCHAR wine_casemap_upper[3994] =
0x2a3f, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff,
0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
0x2a1f, 0x2a1c, 0x2a1e, 0xff2e, 0xff32, 0x0000, 0xff33, 0xff33,
0x0000, 0xff36, 0x0000, 0xff35, 0x0000, 0x0000, 0x0000, 0x0000,
0xff33, 0x0000, 0x0000, 0xff31, 0x0000, 0x0000, 0x0000, 0x0000,
0xff2f, 0xff2d, 0x0000, 0x29f7, 0x0000, 0x0000, 0x0000, 0xff2d,
0x0000, 0xff36, 0x0000, 0xff35, 0xa54f, 0x0000, 0x0000, 0x0000,
0xff33, 0xa54b, 0x0000, 0xff31, 0x0000, 0xa528, 0xa544, 0x0000,
0xff2f, 0xff2d, 0x0000, 0x29f7, 0xa541, 0x0000, 0x0000, 0xff2d,
0x0000, 0x29fd, 0xff2b, 0x0000, 0x0000, 0xff2a, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x29e7, 0x0000, 0x0000,
0xff26, 0x0000, 0x0000, 0xff26, 0x0000, 0x0000, 0x0000, 0x0000,
0xff26, 0x0000, 0x0000, 0xff26, 0x0000, 0x0000, 0x0000, 0xa52a,
0xff26, 0xffbb, 0xff27, 0xff27, 0xffb9, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0xff25, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa512, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@ -677,7 +678,7 @@ const WCHAR wine_casemap_upper[3994] =
0xffd1, 0xffca, 0xfff8, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000,
0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000,
0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000,
0xffff, 0x0000, 0xffff, 0xffaa, 0xffb0, 0x0007, 0x0000, 0x0000,
0xffff, 0x0000, 0xffff, 0xffaa, 0xffb0, 0x0007, 0xff8c, 0x0000,
0xffa0, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000, 0xffff, 0x0000,
0x0000, 0x0000, 0x0000,
/* 0x0404 .. 0x04ff */
@ -718,8 +719,8 @@ const WCHAR wine_casemap_upper[3994] =
0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@ -908,7 +909,7 @@ const WCHAR wine_casemap_upper[3994] =
0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff,
0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000,
0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000,
/* 0x2d00 .. 0x2dff */
@ -916,8 +917,8 @@ const WCHAR wine_casemap_upper[3994] =
0xe3a0, 0xe3a0, 0xe3a0, 0xe3a0, 0xe3a0, 0xe3a0, 0xe3a0, 0xe3a0,
0xe3a0, 0xe3a0, 0xe3a0, 0xe3a0, 0xe3a0, 0xe3a0, 0xe3a0, 0xe3a0,
0xe3a0, 0xe3a0, 0xe3a0, 0xe3a0, 0xe3a0, 0xe3a0, 0xe3a0, 0xe3a0,
0xe3a0, 0xe3a0, 0xe3a0, 0xe3a0, 0xe3a0, 0xe3a0, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0xe3a0, 0xe3a0, 0xe3a0, 0xe3a0, 0xe3a0, 0xe3a0, 0x0000, 0xe3a0,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xe3a0, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@ -949,14 +950,14 @@ const WCHAR wine_casemap_upper[3994] =
0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000,
0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000,
0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000,
0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000,
0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000,
0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000,
0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000,
0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@ -983,10 +984,10 @@ const WCHAR wine_casemap_upper[3994] =
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff,
0x0000, 0xffff, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000,
0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0x0000, 0x0000,
0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0xffff, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000,
0xffff, 0x0000, 0x0000, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000,
0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000,
0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000, 0xffff, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@ -1024,14 +1025,14 @@ const WCHAR wine_casemap_upper[3994] =
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
};
const WCHAR wine_digitmap[5837] =
const WCHAR wine_digitmap[5933] =
{
/* index */
0x01d0, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x028a, 0x0384,
0x0100, 0x044e, 0x053e, 0x062e, 0x071e, 0x080e, 0x08be, 0x099e,
0x0a5e, 0x0100, 0x0100, 0x0af8, 0x0100, 0x0100, 0x0100, 0x0b6a,
0x0c5a, 0x0d14, 0x0def, 0x0e9f, 0x0f5f, 0x0100, 0x0100, 0x0100,
0x0fef, 0x0100, 0x0100, 0x0100, 0x108f, 0x0100, 0x0100, 0x118f,
0x0100, 0x044e, 0x053e, 0x062e, 0x071e, 0x080e, 0x08fe, 0x09de,
0x0a9e, 0x0100, 0x0100, 0x0b38, 0x0100, 0x0100, 0x0100, 0x0baa,
0x0c9a, 0x0d54, 0x0e2f, 0x0edf, 0x0f9f, 0x0100, 0x0100, 0x0100,
0x102f, 0x0100, 0x0100, 0x0100, 0x10cf, 0x0100, 0x0100, 0x11cf,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
@ -1047,8 +1048,8 @@ const WCHAR wine_digitmap[5837] =
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x126f, 0x0100,
0x129f, 0x139f, 0x1479, 0x14d3, 0x0100, 0x0100, 0x0100, 0x0100,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x12af, 0x0100,
0x12df, 0x13df, 0x14d9, 0x1533, 0x0100, 0x0100, 0x0100, 0x0100,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
@ -1058,7 +1059,7 @@ const WCHAR wine_digitmap[5837] =
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x15cd,
0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x0100, 0x162d,
/* defaults */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@ -1324,11 +1325,19 @@ const WCHAR wine_digitmap[5837] =
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xf24a, 0xf24a,
0xf24a, 0xf24a, 0xf24a, 0xf24a, 0xf24a, 0xf24a, 0xf24a, 0xf24a,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* 0x0e10 .. 0x0eff */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* 0x0e50 .. 0x0eff */
0xf1e0, 0xf1e0, 0xf1e0, 0xf1e0, 0xf1e0, 0xf1e0, 0xf1e0, 0xf1e0,
0xf1e0, 0xf1e0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@ -1715,9 +1724,13 @@ const WCHAR wine_digitmap[5837] =
0x5660, 0x5660, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x5640, 0x5640, 0x5640, 0x5640, 0x5640, 0x5640, 0x5640, 0x5640,
0x5640, 0x5640, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* 0xaa06 .. 0xaaff */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
/* 0xaa26 .. 0xaaff */
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@ -1900,7 +1913,7 @@ const WCHAR wine_compatmap[1497] =
0x5e4a, 0x0000, 0x6c62, 0x0000, 0x0000, 0x57c9, 0x7914, 0x7cb3,
0x7f24, 0x7f45, 0x7f4b, 0x7f74, 0x9d3a, 0x82a1, 0x859f, 0x0000,
0x8bf2, 0x0000, 0x90d6, 0x0000, 0x0000, 0x9613, 0x96d7, 0x0000,
0x0000, 0x0000, 0x9ec5, 0x9ed1, 0x9efc, 0xa387, 0x0000, 0x0000,
0x0000, 0x0000, 0x9ec5, 0x9ed1, 0x9efc, 0xa387, 0x96b0, 0x9c88,
0x557e, 0x56b6, 0x571b, 0x5896, 0x58b0, 0x591c, 0x5b67, 0x5bcf,
0x5c30, 0x5e07, 0x5e6e, 0x6229, 0x6232, 0x6657, 0x672a, 0x674f,
0x67b2, 0x6b0e, 0x6ba0, 0x6c4e, 0x6e41, 0x7332, 0x73d4, 0x74db,

View file

@ -285,7 +285,7 @@ static void format_add_char(struct _format_message_data *fmd, WCHAR c)
LPWSTR notspace;
if (fmd->space) {
notspace = fmd->space;
while (*notspace == ' ' && notspace != fmd->t)
while (notspace != fmd->t && *notspace == ' ')
notspace++;
} else
notspace = fmd->space = fmd->t;

View file

@ -1855,29 +1855,6 @@ static HANDLE NLS_RegOpenKey(HANDLE hRootKey, LPCWSTR szKeyName)
return hkey;
}
static BOOL NLS_RegEnumSubKey(HANDLE hKey, UINT ulIndex, LPWSTR szKeyName,
ULONG keyNameSize)
{
BYTE buffer[80];
KEY_BASIC_INFORMATION *info = (KEY_BASIC_INFORMATION *)buffer;
DWORD dwLen;
if (NtEnumerateKey( hKey, ulIndex, KeyBasicInformation, buffer,
sizeof(buffer), &dwLen) != STATUS_SUCCESS ||
info->NameLength > keyNameSize)
{
return FALSE;
}
TRACE("info->Name %s info->NameLength %d\n", debugstr_w(info->Name), info->NameLength);
memcpy( szKeyName, info->Name, info->NameLength);
szKeyName[info->NameLength / sizeof(WCHAR)] = '\0';
TRACE("returning %s\n", debugstr_w(szKeyName));
return TRUE;
}
static BOOL NLS_RegEnumValue(HANDLE hKey, UINT ulIndex,
LPWSTR szValueName, ULONG valueNameSize,
LPWSTR szValueData, ULONG valueDataSize)
@ -2272,6 +2249,323 @@ static BOOL NLS_EnumLanguageGroupLocales(ENUMLANGUAGEGROUPLOCALE_CALLBACKS *lpPr
return TRUE;
}
enum locationkind {
LOCATION_NATION = 0,
LOCATION_REGION,
LOCATION_BOTH
};
struct geoinfo_t {
GEOID id;
WCHAR iso2W[3];
WCHAR iso3W[4];
GEOID parent;
INT uncode;
enum locationkind kind;
};
static const struct geoinfo_t geoinfodata[] = {
{ 2, {'A','G',0}, {'A','T','G',0}, 10039880, 28 }, /* Antigua and Barbuda */
{ 3, {'A','F',0}, {'A','F','G',0}, 47614, 4 }, /* Afghanistan */
{ 4, {'D','Z',0}, {'D','Z','A',0}, 42487, 12 }, /* Algeria */
{ 5, {'A','Z',0}, {'A','Z','E',0}, 47611, 31 }, /* Azerbaijan */
{ 6, {'A','L',0}, {'A','L','B',0}, 47610, 8 }, /* Albania */
{ 7, {'A','M',0}, {'A','R','M',0}, 47611, 51 }, /* Armenia */
{ 8, {'A','D',0}, {'A','N','D',0}, 47610, 20 }, /* Andorra */
{ 9, {'A','O',0}, {'A','G','O',0}, 42484, 24 }, /* Angola */
{ 10, {'A','S',0}, {'A','S','M',0}, 26286, 16 }, /* American Samoa */
{ 11, {'A','R',0}, {'A','R','G',0}, 31396, 32 }, /* Argentina */
{ 12, {'A','U',0}, {'A','U','S',0}, 10210825, 36 }, /* Australia */
{ 14, {'A','T',0}, {'A','U','T',0}, 10210824, 40 }, /* Austria */
{ 17, {'B','H',0}, {'B','H','R',0}, 47611, 48 }, /* Bahrain */
{ 18, {'B','B',0}, {'B','R','B',0}, 10039880, 52 }, /* Barbados */
{ 19, {'B','W',0}, {'B','W','A',0}, 10039883, 72 }, /* Botswana */
{ 20, {'B','M',0}, {'B','M','U',0}, 23581, 60 }, /* Bermuda */
{ 21, {'B','E',0}, {'B','E','L',0}, 10210824, 56 }, /* Belgium */
{ 22, {'B','S',0}, {'B','H','S',0}, 10039880, 44 }, /* Bahamas, The */
{ 23, {'B','D',0}, {'B','G','D',0}, 47614, 50 }, /* Bangladesh */
{ 24, {'B','Z',0}, {'B','L','Z',0}, 27082, 84 }, /* Belize */
{ 25, {'B','A',0}, {'B','I','H',0}, 47610, 70 }, /* Bosnia and Herzegovina */
{ 26, {'B','O',0}, {'B','O','L',0}, 31396, 68 }, /* Bolivia */
{ 27, {'M','M',0}, {'M','M','R',0}, 47599, 104 }, /* Myanmar */
{ 28, {'B','J',0}, {'B','E','N',0}, 42483, 204 }, /* Benin */
{ 29, {'B','Y',0}, {'B','L','R',0}, 47609, 112 }, /* Belarus */
{ 30, {'S','B',0}, {'S','L','B',0}, 20900, 90 }, /* Solomon Islands */
{ 32, {'B','R',0}, {'B','R','A',0}, 31396, 76 }, /* Brazil */
{ 34, {'B','T',0}, {'B','T','N',0}, 47614, 64 }, /* Bhutan */
{ 35, {'B','G',0}, {'B','G','R',0}, 47609, 100 }, /* Bulgaria */
{ 37, {'B','N',0}, {'B','R','N',0}, 47599, 96 }, /* Brunei */
{ 38, {'B','I',0}, {'B','D','I',0}, 47603, 108 }, /* Burundi */
{ 39, {'C','A',0}, {'C','A','N',0}, 23581, 124 }, /* Canada */
{ 40, {'K','H',0}, {'K','H','M',0}, 47599, 116 }, /* Cambodia */
{ 41, {'T','D',0}, {'T','C','D',0}, 42484, 148 }, /* Chad */
{ 42, {'L','K',0}, {'L','K','A',0}, 47614, 144 }, /* Sri Lanka */
{ 43, {'C','G',0}, {'C','O','G',0}, 42484, 178 }, /* Congo */
{ 44, {'C','D',0}, {'C','O','D',0}, 42484, 180 }, /* Congo (DRC) */
{ 45, {'C','N',0}, {'C','H','N',0}, 47600, 156 }, /* China */
{ 46, {'C','L',0}, {'C','H','L',0}, 31396, 152 }, /* Chile */
{ 49, {'C','M',0}, {'C','M','R',0}, 42484, 120 }, /* Cameroon */
{ 50, {'K','M',0}, {'C','O','M',0}, 47603, 174 }, /* Comoros */
{ 51, {'C','O',0}, {'C','O','L',0}, 31396, 170 }, /* Colombia */
{ 54, {'C','R',0}, {'C','R','I',0}, 27082, 188 }, /* Costa Rica */
{ 55, {'C','F',0}, {'C','A','F',0}, 42484, 140 }, /* Central African Republic */
{ 56, {'C','U',0}, {'C','U','B',0}, 10039880, 192 }, /* Cuba */
{ 57, {'C','V',0}, {'C','P','V',0}, 42483, 132 }, /* Cape Verde */
{ 59, {'C','Y',0}, {'C','Y','P',0}, 47611, 196 }, /* Cyprus */
{ 61, {'D','K',0}, {'D','N','K',0}, 10039882, 208 }, /* Denmark */
{ 62, {'D','J',0}, {'D','J','I',0}, 47603, 262 }, /* Djibouti */
{ 63, {'D','M',0}, {'D','M','A',0}, 10039880, 212 }, /* Dominica */
{ 65, {'D','O',0}, {'D','O','M',0}, 10039880, 214 }, /* Dominican Republic */
{ 66, {'E','C',0}, {'E','C','U',0}, 31396, 218 }, /* Ecuador */
{ 67, {'E','G',0}, {'E','G','Y',0}, 42487, 818 }, /* Egypt */
{ 68, {'I','E',0}, {'I','R','L',0}, 10039882, 372 }, /* Ireland */
{ 69, {'G','Q',0}, {'G','N','Q',0}, 42484, 226 }, /* Equatorial Guinea */
{ 70, {'E','E',0}, {'E','S','T',0}, 10039882, 233 }, /* Estonia */
{ 71, {'E','R',0}, {'E','R','I',0}, 47603, 232 }, /* Eritrea */
{ 72, {'S','V',0}, {'S','L','V',0}, 27082, 222 }, /* El Salvador */
{ 73, {'E','T',0}, {'E','T','H',0}, 47603, 231 }, /* Ethiopia */
{ 75, {'C','Z',0}, {'C','Z','E',0}, 47609, 203 }, /* Czech Republic */
{ 77, {'F','I',0}, {'F','I','N',0}, 10039882, 246 }, /* Finland */
{ 78, {'F','J',0}, {'F','J','I',0}, 20900, 242 }, /* Fiji Islands */
{ 80, {'F','M',0}, {'F','S','M',0}, 21206, 583 }, /* Micronesia */
{ 81, {'F','O',0}, {'F','R','O',0}, 10039882, 234 }, /* Faroe Islands */
{ 84, {'F','R',0}, {'F','R','A',0}, 10210824, 250 }, /* France */
{ 86, {'G','M',0}, {'G','M','B',0}, 42483, 270 }, /* Gambia, The */
{ 87, {'G','A',0}, {'G','A','B',0}, 42484, 266 }, /* Gabon */
{ 88, {'G','E',0}, {'G','E','O',0}, 47611, 268 }, /* Georgia */
{ 89, {'G','H',0}, {'G','H','A',0}, 42483, 288 }, /* Ghana */
{ 90, {'G','I',0}, {'G','I','B',0}, 47610, 292 }, /* Gibraltar */
{ 91, {'G','D',0}, {'G','R','D',0}, 10039880, 308 }, /* Grenada */
{ 93, {'G','L',0}, {'G','R','L',0}, 23581, 304 }, /* Greenland */
{ 94, {'D','E',0}, {'D','E','U',0}, 10210824, 276 }, /* Germany */
{ 98, {'G','R',0}, {'G','R','C',0}, 47610, 300 }, /* Greece */
{ 99, {'G','T',0}, {'G','T','M',0}, 27082, 320 }, /* Guatemala */
{ 100, {'G','N',0}, {'G','I','N',0}, 42483, 324 }, /* Guinea */
{ 101, {'G','Y',0}, {'G','U','Y',0}, 31396, 328 }, /* Guyana */
{ 103, {'H','T',0}, {'H','T','I',0}, 10039880, 332 }, /* Haiti */
{ 104, {'H','K',0}, {'H','K','G',0}, 47600, 344 }, /* Hong Kong S.A.R. */
{ 106, {'H','N',0}, {'H','N','D',0}, 27082, 340 }, /* Honduras */
{ 108, {'H','R',0}, {'H','R','V',0}, 47610, 191 }, /* Croatia */
{ 109, {'H','U',0}, {'H','U','N',0}, 47609, 348 }, /* Hungary */
{ 110, {'I','S',0}, {'I','S','L',0}, 10039882, 352 }, /* Iceland */
{ 111, {'I','D',0}, {'I','D','N',0}, 47599, 360 }, /* Indonesia */
{ 113, {'I','N',0}, {'I','N','D',0}, 47614, 356 }, /* India */
{ 114, {'I','O',0}, {'I','O','T',0}, 39070, 86 }, /* British Indian Ocean Territory */
{ 116, {'I','R',0}, {'I','R','N',0}, 47614, 364 }, /* Iran */
{ 117, {'I','L',0}, {'I','S','R',0}, 47611, 376 }, /* Israel */
{ 118, {'I','T',0}, {'I','T','A',0}, 47610, 380 }, /* Italy */
{ 119, {'C','I',0}, {'C','I','V',0}, 42483, 384 }, /* Côte d'Ivoire */
{ 121, {'I','Q',0}, {'I','R','Q',0}, 47611, 368 }, /* Iraq */
{ 122, {'J','P',0}, {'J','P','N',0}, 47600, 392 }, /* Japan */
{ 124, {'J','M',0}, {'J','A','M',0}, 10039880, 388 }, /* Jamaica */
{ 125, {'S','J',0}, {'S','J','M',0}, 10039882, 744 }, /* Jan Mayen */
{ 126, {'J','O',0}, {'J','O','R',0}, 47611, 400 }, /* Jordan */
{ 127, {'X','X',0}, {'X','X',0}, 161832256 }, /* Johnston Atoll */
{ 129, {'K','E',0}, {'K','E','N',0}, 47603, 404 }, /* Kenya */
{ 130, {'K','G',0}, {'K','G','Z',0}, 47590, 417 }, /* Kyrgyzstan */
{ 131, {'K','P',0}, {'P','R','K',0}, 47600, 408 }, /* North Korea */
{ 133, {'K','I',0}, {'K','I','R',0}, 21206, 296 }, /* Kiribati */
{ 134, {'K','R',0}, {'K','O','R',0}, 47600, 410 }, /* Korea */
{ 136, {'K','W',0}, {'K','W','T',0}, 47611, 414 }, /* Kuwait */
{ 137, {'K','Z',0}, {'K','A','Z',0}, 47590, 398 }, /* Kazakhstan */
{ 138, {'L','A',0}, {'L','A','O',0}, 47599, 418 }, /* Laos */
{ 139, {'L','B',0}, {'L','B','N',0}, 47611, 422 }, /* Lebanon */
{ 140, {'L','V',0}, {'L','V','A',0}, 10039882, 428 }, /* Latvia */
{ 141, {'L','T',0}, {'L','T','U',0}, 10039882, 440 }, /* Lithuania */
{ 142, {'L','R',0}, {'L','B','R',0}, 42483, 430 }, /* Liberia */
{ 143, {'S','K',0}, {'S','V','K',0}, 47609, 703 }, /* Slovakia */
{ 145, {'L','I',0}, {'L','I','E',0}, 10210824, 438 }, /* Liechtenstein */
{ 146, {'L','S',0}, {'L','S','O',0}, 10039883, 426 }, /* Lesotho */
{ 147, {'L','U',0}, {'L','U','X',0}, 10210824, 442 }, /* Luxembourg */
{ 148, {'L','Y',0}, {'L','B','Y',0}, 42487, 434 }, /* Libya */
{ 149, {'M','G',0}, {'M','D','G',0}, 47603, 450 }, /* Madagascar */
{ 151, {'M','O',0}, {'M','A','C',0}, 47600, 446 }, /* Macao S.A.R. */
{ 152, {'M','D',0}, {'M','D','A',0}, 47609, 498 }, /* Moldova */
{ 154, {'M','N',0}, {'M','N','G',0}, 47600, 496 }, /* Mongolia */
{ 156, {'M','W',0}, {'M','W','I',0}, 47603, 454 }, /* Malawi */
{ 157, {'M','L',0}, {'M','L','I',0}, 42483, 466 }, /* Mali */
{ 158, {'M','C',0}, {'M','C','O',0}, 10210824, 492 }, /* Monaco */
{ 159, {'M','A',0}, {'M','A','R',0}, 42487, 504 }, /* Morocco */
{ 160, {'M','U',0}, {'M','U','S',0}, 47603, 480 }, /* Mauritius */
{ 162, {'M','R',0}, {'M','R','T',0}, 42483, 478 }, /* Mauritania */
{ 163, {'M','T',0}, {'M','L','T',0}, 47610, 470 }, /* Malta */
{ 164, {'O','M',0}, {'O','M','N',0}, 47611, 512 }, /* Oman */
{ 165, {'M','V',0}, {'M','D','V',0}, 47614, 462 }, /* Maldives */
{ 166, {'M','X',0}, {'M','E','X',0}, 27082, 484 }, /* Mexico */
{ 167, {'M','Y',0}, {'M','Y','S',0}, 47599, 458 }, /* Malaysia */
{ 168, {'M','Z',0}, {'M','O','Z',0}, 47603, 508 }, /* Mozambique */
{ 173, {'N','E',0}, {'N','E','R',0}, 42483, 562 }, /* Niger */
{ 174, {'V','U',0}, {'V','U','T',0}, 20900, 548 }, /* Vanuatu */
{ 175, {'N','G',0}, {'N','G','A',0}, 42483, 566 }, /* Nigeria */
{ 176, {'N','L',0}, {'N','L','D',0}, 10210824, 528 }, /* Netherlands */
{ 177, {'N','O',0}, {'N','O','R',0}, 10039882, 578 }, /* Norway */
{ 178, {'N','P',0}, {'N','P','L',0}, 47614, 524 }, /* Nepal */
{ 180, {'N','R',0}, {'N','R','U',0}, 21206, 520 }, /* Nauru */
{ 181, {'S','R',0}, {'S','U','R',0}, 31396, 740 }, /* Suriname */
{ 182, {'N','I',0}, {'N','I','C',0}, 27082, 558 }, /* Nicaragua */
{ 183, {'N','Z',0}, {'N','Z','L',0}, 10210825, 554 }, /* New Zealand */
{ 184, {'P','S',0}, {'P','S','E',0}, 47611, 275 }, /* Palestinian Authority */
{ 185, {'P','Y',0}, {'P','R','Y',0}, 31396, 600 }, /* Paraguay */
{ 187, {'P','E',0}, {'P','E','R',0}, 31396, 604 }, /* Peru */
{ 190, {'P','K',0}, {'P','A','K',0}, 47614, 586 }, /* Pakistan */
{ 191, {'P','L',0}, {'P','O','L',0}, 47609, 616 }, /* Poland */
{ 192, {'P','A',0}, {'P','A','N',0}, 27082, 591 }, /* Panama */
{ 193, {'P','T',0}, {'P','R','T',0}, 47610, 620 }, /* Portugal */
{ 194, {'P','G',0}, {'P','N','G',0}, 20900, 598 }, /* Papua New Guinea */
{ 195, {'P','W',0}, {'P','L','W',0}, 21206, 585 }, /* Palau */
{ 196, {'G','W',0}, {'G','N','B',0}, 42483, 624 }, /* Guinea-Bissau */
{ 197, {'Q','A',0}, {'Q','A','T',0}, 47611, 634 }, /* Qatar */
{ 198, {'R','E',0}, {'R','E','U',0}, 47603, 638 }, /* Reunion */
{ 199, {'M','H',0}, {'M','H','L',0}, 21206, 584 }, /* Marshall Islands */
{ 200, {'R','O',0}, {'R','O','U',0}, 47609, 642 }, /* Romania */
{ 201, {'P','H',0}, {'P','H','L',0}, 47599, 608 }, /* Philippines */
{ 202, {'P','R',0}, {'P','R','I',0}, 10039880, 630 }, /* Puerto Rico */
{ 203, {'R','U',0}, {'R','U','S',0}, 47609, 643 }, /* Russia */
{ 204, {'R','W',0}, {'R','W','A',0}, 47603, 646 }, /* Rwanda */
{ 205, {'S','A',0}, {'S','A','U',0}, 47611, 682 }, /* Saudi Arabia */
{ 206, {'P','M',0}, {'S','P','M',0}, 23581, 666 }, /* St. Pierre and Miquelon */
{ 207, {'K','N',0}, {'K','N','A',0}, 10039880, 659 }, /* St. Kitts and Nevis */
{ 208, {'S','C',0}, {'S','Y','C',0}, 47603, 690 }, /* Seychelles */
{ 209, {'Z','A',0}, {'Z','A','F',0}, 10039883, 710 }, /* South Africa */
{ 210, {'S','N',0}, {'S','E','N',0}, 42483, 686 }, /* Senegal */
{ 212, {'S','I',0}, {'S','V','N',0}, 47610, 705 }, /* Slovenia */
{ 213, {'S','L',0}, {'S','L','E',0}, 42483, 694 }, /* Sierra Leone */
{ 214, {'S','M',0}, {'S','M','R',0}, 47610, 674 }, /* San Marino */
{ 215, {'S','G',0}, {'S','G','P',0}, 47599, 702 }, /* Singapore */
{ 216, {'S','O',0}, {'S','O','M',0}, 47603, 706 }, /* Somalia */
{ 217, {'E','S',0}, {'E','S','P',0}, 47610, 724 }, /* Spain */
{ 218, {'L','C',0}, {'L','C','A',0}, 10039880, 662 }, /* St. Lucia */
{ 219, {'S','D',0}, {'S','D','N',0}, 42487, 736 }, /* Sudan */
{ 220, {'S','J',0}, {'S','J','M',0}, 10039882, 744 }, /* Svalbard */
{ 221, {'S','E',0}, {'S','W','E',0}, 10039882, 752 }, /* Sweden */
{ 222, {'S','Y',0}, {'S','Y','R',0}, 47611, 760 }, /* Syria */
{ 223, {'C','H',0}, {'C','H','E',0}, 10210824, 756 }, /* Switzerland */
{ 224, {'A','E',0}, {'A','R','E',0}, 47611, 784 }, /* United Arab Emirates */
{ 225, {'T','T',0}, {'T','T','O',0}, 10039880, 780 }, /* Trinidad and Tobago */
{ 227, {'T','H',0}, {'T','H','A',0}, 47599, 764 }, /* Thailand */
{ 228, {'T','J',0}, {'T','J','K',0}, 47590, 762 }, /* Tajikistan */
{ 231, {'T','O',0}, {'T','O','N',0}, 26286, 776 }, /* Tonga */
{ 232, {'T','G',0}, {'T','G','O',0}, 42483, 768 }, /* Togo */
{ 233, {'S','T',0}, {'S','T','P',0}, 42484, 678 }, /* São Tomé and Príncipe */
{ 234, {'T','N',0}, {'T','U','N',0}, 42487, 788 }, /* Tunisia */
{ 235, {'T','R',0}, {'T','U','R',0}, 47611, 792 }, /* Turkey */
{ 236, {'T','V',0}, {'T','U','V',0}, 26286, 798 }, /* Tuvalu */
{ 237, {'T','W',0}, {'T','W','N',0}, 47600, 158 }, /* Taiwan */
{ 238, {'T','M',0}, {'T','K','M',0}, 47590, 795 }, /* Turkmenistan */
{ 239, {'T','Z',0}, {'T','Z','A',0}, 47603, 834 }, /* Tanzania */
{ 240, {'U','G',0}, {'U','G','A',0}, 47603, 800 }, /* Uganda */
{ 241, {'U','A',0}, {'U','K','R',0}, 47609, 804 }, /* Ukraine */
{ 242, {'G','B',0}, {'G','B','R',0}, 10039882, 826 }, /* United Kingdom */
{ 244, {'U','S',0}, {'U','S','A',0}, 23581, 840 }, /* United States */
{ 245, {'B','F',0}, {'B','F','A',0}, 42483, 854 }, /* Burkina Faso */
{ 246, {'U','Y',0}, {'U','R','Y',0}, 31396, 858 }, /* Uruguay */
{ 247, {'U','Z',0}, {'U','Z','B',0}, 47590, 860 }, /* Uzbekistan */
{ 248, {'V','C',0}, {'V','C','T',0}, 10039880, 670 }, /* St. Vincent and the Grenadines */
{ 249, {'V','E',0}, {'V','E','N',0}, 31396, 862 }, /* Bolivarian Republic of Venezuela */
{ 251, {'V','N',0}, {'V','N','M',0}, 47599, 704 }, /* Vietnam */
{ 252, {'V','I',0}, {'V','I','R',0}, 10039880, 850 }, /* Virgin Islands */
{ 253, {'V','A',0}, {'V','A','T',0}, 47610, 336 }, /* Vatican City */
{ 254, {'N','A',0}, {'N','A','M',0}, 10039883, 516 }, /* Namibia */
{ 257, {'E','H',0}, {'E','S','H',0}, 42487, 732 }, /* Western Sahara (disputed) */
{ 258, {'X','X',0}, {'X','X',0}, 161832256 }, /* Wake Island */
{ 259, {'W','S',0}, {'W','S','M',0}, 26286, 882 }, /* Samoa */
{ 260, {'S','Z',0}, {'S','W','Z',0}, 10039883, 748 }, /* Swaziland */
{ 261, {'Y','E',0}, {'Y','E','M',0}, 47611, 887 }, /* Yemen */
{ 263, {'Z','M',0}, {'Z','M','B',0}, 47603, 894 }, /* Zambia */
{ 264, {'Z','W',0}, {'Z','W','E',0}, 47603, 716 }, /* Zimbabwe */
{ 269, {'C','S',0}, {'S','C','G',0}, 47610, 891 }, /* Serbia and Montenegro (Former) */
{ 270, {'M','E',0}, {'M','N','E',0}, 47610, 499 }, /* Montenegro */
{ 271, {'R','S',0}, {'S','R','B',0}, 47610, 688 }, /* Serbia */
{ 273, {'C','W',0}, {'C','U','W',0}, 10039880, 531 }, /* Curaçao */
{ 276, {'S','S',0}, {'S','S','D',0}, 42487, 728 }, /* South Sudan */
{ 300, {'A','I',0}, {'A','I','A',0}, 10039880, 660 }, /* Anguilla */
{ 301, {'A','Q',0}, {'A','T','A',0}, 39070, 10 }, /* Antarctica */
{ 302, {'A','W',0}, {'A','B','W',0}, 10039880, 533 }, /* Aruba */
{ 303, {'X','X',0}, {'X','X',0}, 39070 }, /* Ascension Island */
{ 304, {'X','X',0}, {'X','X',0}, 10210825 }, /* Ashmore and Cartier Islands */
{ 305, {'X','X',0}, {'X','X',0}, 161832256 }, /* Baker Island */
{ 306, {'B','V',0}, {'B','V','T',0}, 39070, 74 }, /* Bouvet Island */
{ 307, {'K','Y',0}, {'C','Y','M',0}, 10039880, 136 }, /* Cayman Islands */
{ 308, {'X','X',0}, {'X','X',0}, 10210824, 0, LOCATION_BOTH }, /* Channel Islands */
{ 309, {'C','X',0}, {'C','X','R',0}, 12, 162 }, /* Christmas Island */
{ 310, {'X','X',0}, {'X','X',0}, 27114 }, /* Clipperton Island */
{ 311, {'C','C',0}, {'C','C','K',0}, 10210825, 166 }, /* Cocos (Keeling) Islands */
{ 312, {'C','K',0}, {'C','O','K',0}, 26286, 184 }, /* Cook Islands */
{ 313, {'X','X',0}, {'X','X',0}, 10210825 }, /* Coral Sea Islands */
{ 314, {'X','X',0}, {'X','X',0}, 114 }, /* Diego Garcia */
{ 315, {'F','K',0}, {'F','L','K',0}, 31396, 238 }, /* Falkland Islands (Islas Malvinas) */
{ 317, {'G','F',0}, {'G','U','F',0}, 31396, 254 }, /* French Guiana */
{ 318, {'P','F',0}, {'P','Y','F',0}, 26286, 258 }, /* French Polynesia */
{ 319, {'T','F',0}, {'A','T','F',0}, 39070, 260 }, /* French Southern and Antarctic Lands */
{ 321, {'G','P',0}, {'G','L','P',0}, 10039880, 312 }, /* Guadeloupe */
{ 322, {'G','U',0}, {'G','U','M',0}, 21206, 316 }, /* Guam */
{ 323, {'X','X',0}, {'X','X',0}, 39070 }, /* Guantanamo Bay */
{ 324, {'G','G',0}, {'G','G','Y',0}, 308, 831 }, /* Guernsey */
{ 325, {'H','M',0}, {'H','M','D',0}, 39070, 334 }, /* Heard Island and McDonald Islands */
{ 326, {'X','X',0}, {'X','X',0}, 161832256 }, /* Howland Island */
{ 327, {'X','X',0}, {'X','X',0}, 161832256 }, /* Jarvis Island */
{ 328, {'J','E',0}, {'J','E','Y',0}, 308, 832 }, /* Jersey */
{ 329, {'X','X',0}, {'X','X',0}, 161832256 }, /* Kingman Reef */
{ 330, {'M','Q',0}, {'M','T','Q',0}, 10039880, 474 }, /* Martinique */
{ 331, {'Y','T',0}, {'M','Y','T',0}, 47603, 175 }, /* Mayotte */
{ 332, {'M','S',0}, {'M','S','R',0}, 10039880, 500 }, /* Montserrat */
{ 333, {'A','N',0}, {'A','N','T',0}, 10039880, 530, LOCATION_BOTH }, /* Netherlands Antilles (Former) */
{ 334, {'N','C',0}, {'N','C','L',0}, 20900, 540 }, /* New Caledonia */
{ 335, {'N','U',0}, {'N','I','U',0}, 26286, 570 }, /* Niue */
{ 336, {'N','F',0}, {'N','F','K',0}, 10210825, 574 }, /* Norfolk Island */
{ 337, {'M','P',0}, {'M','N','P',0}, 21206, 580 }, /* Northern Mariana Islands */
{ 338, {'X','X',0}, {'X','X',0}, 161832256 }, /* Palmyra Atoll */
{ 339, {'P','N',0}, {'P','C','N',0}, 26286, 612 }, /* Pitcairn Islands */
{ 340, {'X','X',0}, {'X','X',0}, 337 }, /* Rota Island */
{ 341, {'X','X',0}, {'X','X',0}, 337 }, /* Saipan */
{ 342, {'G','S',0}, {'S','G','S',0}, 39070, 239 }, /* South Georgia and the South Sandwich Islands */
{ 343, {'S','H',0}, {'S','H','N',0}, 42483, 654 }, /* St. Helena */
{ 346, {'X','X',0}, {'X','X',0}, 337 }, /* Tinian Island */
{ 347, {'T','K',0}, {'T','K','L',0}, 26286, 772 }, /* Tokelau */
{ 348, {'X','X',0}, {'X','X',0}, 39070 }, /* Tristan da Cunha */
{ 349, {'T','C',0}, {'T','C','A',0}, 10039880, 796 }, /* Turks and Caicos Islands */
{ 351, {'V','G',0}, {'V','G','B',0}, 10039880, 92 }, /* Virgin Islands, British */
{ 352, {'W','F',0}, {'W','L','F',0}, 26286, 876 }, /* Wallis and Futuna */
{ 742, {'X','X',0}, {'X','X',0}, 39070, 0, LOCATION_REGION }, /* Africa */
{ 2129, {'X','X',0}, {'X','X',0}, 39070, 0, LOCATION_REGION }, /* Asia */
{ 10541, {'X','X',0}, {'X','X',0}, 39070, 0, LOCATION_REGION }, /* Europe */
{ 15126, {'I','M',0}, {'I','M','N',0}, 10039882, 833 }, /* Man, Isle of */
{ 19618, {'M','K',0}, {'M','K','D',0}, 47610, 807 }, /* Macedonia, Former Yugoslav Republic of */
{ 20900, {'X','X',0}, {'X','X',0}, 27114, 0, LOCATION_REGION }, /* Melanesia */
{ 21206, {'X','X',0}, {'X','X',0}, 27114, 0, LOCATION_REGION }, /* Micronesia */
{ 21242, {'X','X',0}, {'X','X',0}, 161832256 }, /* Midway Islands */
{ 23581, {'X','X',0}, {'X','X',0}, 10026358, 0, LOCATION_REGION }, /* Northern America */
{ 26286, {'X','X',0}, {'X','X',0}, 27114, 0, LOCATION_REGION }, /* Polynesia */
{ 27082, {'X','X',0}, {'X','X',0}, 161832257, 0, LOCATION_REGION }, /* Central America */
{ 27114, {'X','X',0}, {'X','X',0}, 39070, 0, LOCATION_REGION }, /* Oceania */
{ 30967, {'S','X',0}, {'S','X','M',0}, 10039880, 534 }, /* Sint Maarten (Dutch part) */
{ 31396, {'X','X',0}, {'X','X',0}, 161832257, 0, LOCATION_REGION }, /* South America */
{ 31706, {'M','F',0}, {'M','A','F',0}, 10039880, 663 }, /* Saint Martin (French part) */
{ 39070, {'X','X',0}, {'X','X',0}, 39070, 0, LOCATION_REGION }, /* World */
{ 42483, {'X','X',0}, {'X','X',0}, 742, 0, LOCATION_REGION }, /* Western Africa */
{ 42484, {'X','X',0}, {'X','X',0}, 742, 0, LOCATION_REGION }, /* Middle Africa */
{ 42487, {'X','X',0}, {'X','X',0}, 742, 0, LOCATION_REGION }, /* Northern Africa */
{ 47590, {'X','X',0}, {'X','X',0}, 2129, 0, LOCATION_REGION }, /* Central Asia */
{ 47599, {'X','X',0}, {'X','X',0}, 2129, 0, LOCATION_REGION }, /* South-Eastern Asia */
{ 47600, {'X','X',0}, {'X','X',0}, 2129, 0, LOCATION_REGION }, /* Eastern Asia */
{ 47603, {'X','X',0}, {'X','X',0}, 742, 0, LOCATION_REGION }, /* Eastern Africa */
{ 47609, {'X','X',0}, {'X','X',0}, 10541, 0, LOCATION_REGION }, /* Eastern Europe */
{ 47610, {'X','X',0}, {'X','X',0}, 10541, 0, LOCATION_REGION }, /* Southern Europe */
{ 47611, {'X','X',0}, {'X','X',0}, 2129, 0, LOCATION_REGION }, /* Middle East */
{ 47614, {'X','X',0}, {'X','X',0}, 2129, 0, LOCATION_REGION }, /* Southern Asia */
{ 7299303, {'T','L',0}, {'T','L','S',0}, 47599, 626 }, /* Democratic Republic of Timor-Leste */
{ 10026358, {'X','X',0}, {'X','X',0}, 39070, 0, LOCATION_REGION }, /* Americas */
{ 10028789, {'A','X',0}, {'A','L','A',0}, 10039882, 248 }, /* Åland Islands */
{ 10039880, {'X','X',0}, {'X','X',0}, 161832257, 0, LOCATION_REGION }, /* Caribbean */
{ 10039882, {'X','X',0}, {'X','X',0}, 10541, 0, LOCATION_REGION }, /* Northern Europe */
{ 10039883, {'X','X',0}, {'X','X',0}, 742, 0, LOCATION_REGION }, /* Southern Africa */
{ 10210824, {'X','X',0}, {'X','X',0}, 10541, 0, LOCATION_REGION }, /* Western Europe */
{ 10210825, {'X','X',0}, {'X','X',0}, 27114, 0, LOCATION_REGION }, /* Australia and New Zealand */
{ 161832015, {'B','L',0}, {'B','L','M',0}, 10039880, 652 }, /* Saint Barthélemy */
{ 161832256, {'U','M',0}, {'U','M','I',0}, 27114, 581 }, /* U.S. Minor Outlying Islands */
{ 161832257, {'X','X',0}, {'X','X',0}, 10026358, 0, LOCATION_REGION }, /* Latin America and the Caribbean */
};
/******************************************************************************
* EnumLanguageGroupLocalesA (KERNEL32.@)
*
@ -2440,66 +2734,52 @@ EnumSystemCodePagesA (
return NLS_EnumSystemCodePages(lpCodePageEnumProc ? &procs : NULL);
}
/******************************************************************************
* EnumSystemGeoID (KERNEL32.@)
*
* Call a users function for every location available on the system.
*
* PARAMS
* geoclass [I] Type of information desired (SYSGEOTYPE enum from "winnls.h")
* reserved [I] Reserved, set to 0
* pGeoEnumProc [I] Callback function to call for each location
* geoclass [I] Type of information desired (SYSGEOTYPE enum from "winnls.h")
* parent [I] GEOID for the parent
* enumproc [I] Callback function to call for each location
*
* RETURNS
* Success: TRUE.
* Failure: FALSE. Use GetLastError() to determine the cause.
*/
BOOL WINAPI EnumSystemGeoID(GEOCLASS geoclass, GEOID reserved, GEO_ENUMPROC pGeoEnumProc)
BOOL WINAPI EnumSystemGeoID(GEOCLASS geoclass, GEOID parent, GEO_ENUMPROC enumproc)
{
static const WCHAR szCountryCodeValueName[] = {
'C','o','u','n','t','r','y','C','o','d','e','\0'
};
WCHAR szNumber[10];
HANDLE hKey;
ULONG ulIndex = 0;
INT i;
TRACE("(0x%08X,0x%08X,%p)\n", geoclass, reserved, pGeoEnumProc);
TRACE("(%d, %d, %p)\n", geoclass, parent, enumproc);
if (geoclass != GEOCLASS_NATION || reserved || !pGeoEnumProc)
{
if (!enumproc) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
hKey = NLS_RegOpenKey( 0, szCountryListName );
while (NLS_RegEnumSubKey( hKey, ulIndex, szNumber, sizeof(szNumber) ))
{
BOOL bContinue = TRUE;
DWORD dwGeoId;
HANDLE hSubKey = NLS_RegOpenKey( hKey, szNumber );
if (hSubKey)
{
if (NLS_RegGetDword( hSubKey, szCountryCodeValueName, &dwGeoId ))
{
TRACE("Got geoid %d\n", dwGeoId);
if (!pGeoEnumProc( dwGeoId ))
bContinue = FALSE;
}
NtClose( hSubKey );
}
if (!bContinue)
break;
ulIndex++;
if (geoclass != GEOCLASS_NATION && geoclass != GEOCLASS_REGION) {
SetLastError(ERROR_INVALID_FLAGS);
return FALSE;
}
if (hKey)
NtClose( hKey );
for (i = 0; i < sizeof(geoinfodata)/sizeof(struct geoinfo_t); i++) {
const struct geoinfo_t *ptr = &geoinfodata[i];
if (geoclass == GEOCLASS_NATION && (ptr->kind == LOCATION_REGION))
continue;
if (geoclass == GEOCLASS_REGION && (ptr->kind == LOCATION_NATION))
continue;
if (parent && ptr->parent != parent)
continue;
if (!enumproc(ptr->id))
return TRUE;
}
return TRUE;
}
@ -2762,73 +3042,130 @@ NLS_GetGeoFriendlyName(GEOID Location, LPWSTR szFriendlyName, int cchData)
return Ret;
}
/*
* @implemented
*/
INT WINAPI GetGeoInfoW(GEOID GeoId, GEOTYPE GeoType, LPWSTR lpGeoData,
int cchData, LANGID LangId)
static const struct geoinfo_t *get_geoinfo_dataptr(GEOID geoid)
{
TRACE("%d %d %p %d %d\n", GeoId, GeoType, lpGeoData, cchData, LangId);
int min, max;
switch (GeoType)
{
case GEO_FRIENDLYNAME:
{
return NLS_GetGeoFriendlyName(GeoId, lpGeoData, cchData);
}
case GEO_TIMEZONES:
case GEO_NATION:
case GEO_LATITUDE:
case GEO_LONGITUDE:
case GEO_ISO2:
case GEO_ISO3:
case GEO_RFC1766:
case GEO_LCID:
case GEO_OFFICIALNAME:
case GEO_OFFICIALLANGUAGES:
FIXME("%d %d %p %d %d\n", GeoId, GeoType, lpGeoData, cchData, LangId);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
break;
min = 0;
max = sizeof(geoinfodata)/sizeof(struct geoinfo_t)-1;
while (min <= max) {
const struct geoinfo_t *ptr;
int n = (min+max)/2;
ptr = &geoinfodata[n];
if (geoid == ptr->id)
/* we don't need empty entry */
return *ptr->iso2W ? ptr : NULL;
if (ptr->id > geoid)
max = n-1;
else
min = n+1;
}
return 0;
return NULL;
}
/*
* @implemented
/******************************************************************************
* GetGeoInfoW (KERNEL32.@)
*/
INT WINAPI GetGeoInfoA(GEOID GeoId, GEOTYPE GeoType, LPSTR lpGeoData,
int cchData, LANGID LangId)
INT WINAPI GetGeoInfoW(GEOID geoid, GEOTYPE geotype, LPWSTR data, int data_len, LANGID lang)
{
WCHAR szBuffer[MAX_PATH];
char szBufferA[sizeof(szBuffer)/sizeof(WCHAR)];
int Ret;
const struct geoinfo_t *ptr;
const WCHAR *str = NULL;
WCHAR buffW[12];
LONG val = 0;
INT len;
TRACE("%d %d %p %d %d\n", GeoId, GeoType, lpGeoData, cchData, LangId);
TRACE("%d %d %p %d %d\n", geoid, geotype, data, data_len, lang);
switch (GeoType)
{
case GEO_FRIENDLYNAME:
{
Ret = NLS_GetGeoFriendlyName(GeoId, szBuffer, cchData);
WideCharToMultiByte(CP_ACP, 0, szBuffer, -1, szBufferA, sizeof(szBufferA), 0, 0);
strcpy(lpGeoData, szBufferA);
return Ret;
}
case GEO_TIMEZONES:
case GEO_NATION:
case GEO_LATITUDE:
case GEO_LONGITUDE:
case GEO_ISO2:
case GEO_ISO3:
case GEO_RFC1766:
case GEO_LCID:
case GEO_OFFICIALNAME:
case GEO_OFFICIALLANGUAGES:
FIXME("%d %d %p %d %d\n", GeoId, GeoType, lpGeoData, cchData, LangId);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
break;
if (!(ptr = get_geoinfo_dataptr(geoid))) {
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
return 0;
switch (geotype) {
case GEO_FRIENDLYNAME:
{
return NLS_GetGeoFriendlyName(geoid, data, data_len);
}
case GEO_NATION:
val = geoid;
break;
case GEO_ISO_UN_NUMBER:
val = ptr->uncode;
break;
case GEO_PARENT:
val = ptr->parent;
break;
case GEO_ISO2:
case GEO_ISO3:
{
str = geotype == GEO_ISO2 ? ptr->iso2W : ptr->iso3W;
break;
}
case GEO_RFC1766:
case GEO_LCID:
case GEO_OFFICIALNAME:
case GEO_TIMEZONES:
case GEO_OFFICIALLANGUAGES:
case GEO_LATITUDE:
case GEO_LONGITUDE:
FIXME("type %d is not supported\n", geotype);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
default:
WARN("unrecognized type %d\n", geotype);
SetLastError(ERROR_INVALID_FLAGS);
return 0;
}
if (val) {
static const WCHAR fmtW[] = {'%','d',0};
sprintfW(buffW, fmtW, val);
str = buffW;
}
len = strlenW(str) + 1;
if (!data || !data_len)
return len;
memcpy(data, str, min(len, data_len)*sizeof(WCHAR));
if (data_len < len)
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return data_len < len ? 0 : len;
}
/******************************************************************************
* GetGeoInfoA (KERNEL32.@)
*/
INT WINAPI GetGeoInfoA(GEOID geoid, GEOTYPE geotype, LPSTR data, int data_len, LANGID lang)
{
WCHAR *buffW;
INT len;
TRACE("%d %d %p %d %d\n", geoid, geotype, data, data_len, lang);
len = GetGeoInfoW(geoid, geotype, NULL, 0, lang);
if (!len)
return 0;
buffW = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
if (!buffW)
return 0;
GetGeoInfoW(geoid, geotype, buffW, len, lang);
len = WideCharToMultiByte(CP_ACP, 0, buffW, -1, NULL, 0, NULL, NULL);
if (!data || !data_len) {
HeapFree(GetProcessHeap(), 0, buffW);
return len;
}
len = WideCharToMultiByte(CP_ACP, 0, buffW, -1, data, data_len, NULL, NULL);
HeapFree(GetProcessHeap(), 0, buffW);
if (data_len < len)
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return data_len < len ? 0 : len;
}

View file

@ -22,6 +22,7 @@
#include "setupapi_private.h"
#include <wingdi.h>
#include <shellapi.h>
/* Unicode constants */
static const WCHAR BackSlash[] = {'\\',0};
@ -76,6 +77,7 @@ static const INSTALL_PARAMS_DATA InstallParamsData[] = {
};
#undef ADD_PARAM_HANDLER
#define UNKNOWN_ICON_INDEX 18
/***********************************************************************
* SetupDiDestroyClassImageList(SETUPAPI.@)
@ -330,9 +332,6 @@ cleanup:
return rc;
}
/***********************************************************************
* SetupDiGetClassImageIndex (SETUPAPI.@)
*/
static BOOL
SETUP_GetIconIndex(
IN HKEY hClassKey,
@ -378,6 +377,9 @@ cleanup:
return ret;
}
/***********************************************************************
* SetupDiGetClassImageIndex (SETUPAPI.@)
*/
BOOL WINAPI
SetupDiGetClassImageIndex(
IN PSP_CLASSIMAGELIST_DATA ClassImageListData,
@ -458,6 +460,102 @@ SetupDiGetClassImageListExA(
return ret;
}
static BOOL WINAPI
SETUP_GetClassIconInfo(IN CONST GUID *ClassGuid, OUT PINT OutIndex, OUT LPWSTR *OutDllName)
{
LPWSTR Buffer = NULL;
INT iconIndex = -UNKNOWN_ICON_INDEX;
HKEY hKey = INVALID_HANDLE_VALUE;
BOOL ret = FALSE;
if (ClassGuid)
{
hKey = SetupDiOpenClassRegKey(ClassGuid, KEY_QUERY_VALUE);
if (hKey != INVALID_HANDLE_VALUE)
{
SETUP_GetIconIndex(hKey, &iconIndex);
}
}
if (iconIndex > 0)
{
/* Look up icon in dll specified by Installer32 or EnumPropPages32 key */
PWCHAR Comma;
LONG rc;
DWORD dwRegType, dwLength;
rc = RegQueryValueExW(hKey, REGSTR_VAL_INSTALLER_32, NULL, &dwRegType, NULL, &dwLength);
if (rc == ERROR_SUCCESS && dwRegType == REG_SZ)
{
Buffer = MyMalloc(dwLength + sizeof(WCHAR));
if (Buffer == NULL)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto cleanup;
}
rc = RegQueryValueExW(hKey, REGSTR_VAL_INSTALLER_32, NULL, NULL, (LPBYTE)Buffer, &dwLength);
if (rc != ERROR_SUCCESS)
{
SetLastError(rc);
goto cleanup;
}
/* make sure the returned buffer is NULL-terminated */
Buffer[dwLength / sizeof(WCHAR)] = 0;
}
else if
(ERROR_SUCCESS == (rc = RegQueryValueExW(hKey, REGSTR_VAL_ENUMPROPPAGES_32, NULL, &dwRegType, NULL, &dwLength))
&& dwRegType == REG_SZ)
{
Buffer = MyMalloc(dwLength + sizeof(WCHAR));
if (Buffer == NULL)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto cleanup;
}
rc = RegQueryValueExW(hKey, REGSTR_VAL_ENUMPROPPAGES_32, NULL, NULL, (LPBYTE)Buffer, &dwLength);
if (rc != ERROR_SUCCESS)
{
SetLastError(rc);
goto cleanup;
}
/* make sure the returned buffer is NULL-terminated */
Buffer[dwLength / sizeof(WCHAR)] = 0;
}
else
{
/* Unable to find where to load the icon */
SetLastError(ERROR_FILE_NOT_FOUND);
goto cleanup;
}
Comma = strchrW(Buffer, ',');
if (!Comma)
{
SetLastError(ERROR_GEN_FAILURE);
goto cleanup;
}
*Comma = '\0';
*OutDllName = Buffer;
}
else
{
/* Look up icon in setupapi.dll */
iconIndex = -iconIndex;
*OutDllName = NULL;
}
*OutIndex = iconIndex;
ret = TRUE;
TRACE("Icon index %d, dll name %s\n", iconIndex, debugstr_w(*OutDllName ? *OutDllName : SetupapiDll));
cleanup:
if (hKey != INVALID_HANDLE_VALUE)
RegCloseKey(hKey);
return ret;
}
/***********************************************************************
* SetupDiGetClassImageListExW(SETUPAPI.@)
*/
@ -570,24 +668,32 @@ SetupDiGetClassImageListExW(
for (i = 0; i < list->NumberOfGuids; i++)
{
INT miniIconIndex;
LPWSTR DllName = NULL;
ret = SetupDiLoadClassIcon(
&list->Guids[i],
NULL,
&miniIconIndex);
if (ret)
if (SETUP_GetClassIconInfo(&list->Guids[i], &miniIconIndex, &DllName))
{
hIcon = LoadImage(hInstance, MAKEINTRESOURCE(miniIconIndex), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
if (hIcon)
if (DllName && ExtractIconExW(DllName, -miniIconIndex, NULL, &hIcon, 1) == 1)
{
list->IconIndexes[i] = ImageList_AddIcon(ClassImageListData->ImageList, hIcon);
DestroyIcon(hIcon);
}
else if(!DllName)
{
hIcon = LoadImage(hInstance, MAKEINTRESOURCE(miniIconIndex), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
list->IconIndexes[i] = ImageList_AddIcon(ClassImageListData->ImageList, hIcon);
}
if(hIcon)
DestroyIcon(hIcon);
else
list->IconIndexes[i] = -1;
if(DllName)
MyFree(DllName);
}
else
{
list->IconIndexes[i] = -1; /* Special value to indicate that the icon is unavailable */
}
}
/* Finally, add the overlay icons to the image list */
@ -660,105 +766,43 @@ SetupDiLoadClassIcon(
OUT HICON *LargeIcon OPTIONAL,
OUT PINT MiniIconIndex OPTIONAL)
{
LPWSTR Buffer = NULL;
LPCWSTR DllName;
INT iconIndex = -18;
HKEY hKey = INVALID_HANDLE_VALUE;
INT iconIndex = 0;
LPWSTR DllName = NULL;
BOOL ret = FALSE;
HICON hIcon = NULL;
if (ClassGuid)
if (LargeIcon)
{
hKey = SetupDiOpenClassRegKey(ClassGuid, KEY_QUERY_VALUE);
if (hKey != INVALID_HANDLE_VALUE)
SETUP_GetIconIndex(hKey, &iconIndex);
}
if(!SETUP_GetClassIconInfo(ClassGuid, &iconIndex, &DllName))
return FALSE;
if (iconIndex > 0)
{
/* Look up icon in dll specified by Installer32 or EnumPropPages32 key */
PWCHAR Comma;
LONG rc;
DWORD dwRegType, dwLength;
rc = RegQueryValueExW(hKey, REGSTR_VAL_INSTALLER_32, NULL, &dwRegType, NULL, &dwLength);
if (rc == ERROR_SUCCESS && dwRegType == REG_SZ)
if (DllName && ExtractIconExW(DllName, -iconIndex, &hIcon, NULL, 1) == 1 && hIcon != NULL)
{
Buffer = MyMalloc(dwLength + sizeof(WCHAR));
if (Buffer == NULL)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto cleanup;
}
rc = RegQueryValueExW(hKey, REGSTR_VAL_INSTALLER_32, NULL, NULL, (LPBYTE)Buffer, &dwLength);
if (rc != ERROR_SUCCESS)
{
SetLastError(rc);
goto cleanup;
}
/* make sure the returned buffer is NULL-terminated */
Buffer[dwLength / sizeof(WCHAR)] = 0;
}
else if
(ERROR_SUCCESS == (rc = RegQueryValueExW(hKey, REGSTR_VAL_ENUMPROPPAGES_32, NULL, &dwRegType, NULL, &dwLength))
&& dwRegType == REG_SZ)
{
Buffer = MyMalloc(dwLength + sizeof(WCHAR));
if (Buffer == NULL)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
goto cleanup;
}
rc = RegQueryValueExW(hKey, REGSTR_VAL_ENUMPROPPAGES_32, NULL, NULL, (LPBYTE)Buffer, &dwLength);
if (rc != ERROR_SUCCESS)
{
SetLastError(rc);
goto cleanup;
}
/* make sure the returned buffer is NULL-terminated */
Buffer[dwLength / sizeof(WCHAR)] = 0;
ret = TRUE;
}
else
{
/* Unable to find where to load the icon */
SetLastError(ERROR_FILE_NOT_FOUND);
goto cleanup;
/* load the default unknown device icon if ExtractIcon failed */
if(DllName)
iconIndex = UNKNOWN_ICON_INDEX;
hIcon = LoadImage(hInstance, MAKEINTRESOURCE(iconIndex), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
if(!LargeIcon)
goto cleanup;
}
Comma = strchrW(Buffer, ',');
if (!Comma)
{
SetLastError(ERROR_GEN_FAILURE);
goto cleanup;
}
*Comma = '\0';
DllName = Buffer;
}
else
{
/* Look up icon in setupapi.dll */
DllName = SetupapiDll;
iconIndex = -iconIndex;
}
TRACE("Icon index %d, dll name %s\n", iconIndex, debugstr_w(DllName));
if (LargeIcon)
{
*LargeIcon = LoadImage(hInstance, MAKEINTRESOURCE(iconIndex), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
if (!*LargeIcon)
{
SetLastError(ERROR_INVALID_INDEX);
goto cleanup;
}
}
if (MiniIconIndex)
*MiniIconIndex = iconIndex;
ret = TRUE;
*LargeIcon = hIcon;
cleanup:
if (hKey != INVALID_HANDLE_VALUE)
RegCloseKey(hKey);
if (Buffer != NULL)
MyFree(Buffer);
if(DllName)
MyFree(DllName);
TRACE("Returning %d\n", ret);
return ret;

View file

@ -918,7 +918,7 @@ getnameinfo(const struct sockaddr FAR *sa,
WCHAR ServiceBuffer[17];
DWORD HostLength = 0, ServLength = 0;
PWCHAR ServiceString = NULL, HostString = NULL;
DPRINT("getaddrinfo: %p, %p, %p, %lx\n", host, serv, sa, salen);
DPRINT("getnameinfo: %p, %p, %p, %lx\n", host, serv, sa, salen);
/* Check for WSAStartup */
if ((ErrorCode = WsQuickProlog()) != ERROR_SUCCESS) return ErrorCode;

View file

@ -1,7 +1,7 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/fs/vfat/close.c
* FILE: drivers/filesystems/fastfat/close.c
* PURPOSE: VFAT Filesystem
* PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
*/
@ -51,7 +51,7 @@ VfatCloseFile(
{
if (pFcb->Flags & FCB_DELETE_PENDING)
{
VfatDelEntry(DeviceExt, pFcb);
VfatDelEntry(DeviceExt, pFcb, NULL);
FsRtlNotifyFullReportChange(DeviceExt->NotifySync,
&(DeviceExt->NotifyList),

View file

@ -18,9 +18,10 @@
*/
/*
* PROJECT: ReactOS kernel
* FILE: drivers/fs/vfat/create.c
* FILE: drivers/filesystems/fastfat/create.c
* PURPOSE: VFAT Filesystem
* PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
* Pierre Schweitzer (pierre@reactos.org)
*/
/* INCLUDES *****************************************************************/
@ -352,7 +353,6 @@ VfatOpenFile(
PUNICODE_STRING PathNameU,
PFILE_OBJECT FileObject,
ULONG RequestedDisposition,
BOOLEAN OpenTargetDir,
PVFATFCB *ParentFcb)
{
PVFATFCB Fcb;
@ -404,13 +404,6 @@ VfatOpenFile(
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);
@ -462,11 +455,8 @@ 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;
@ -558,14 +548,22 @@ VfatCreateFile(
}
/* Try opening the file. */
Status = VfatOpenFile(DeviceExt, &PathNameU, FileObject, RequestedDisposition, OpenTargetDir, &ParentFcb);
if (OpenTargetDir)
if (!OpenTargetDir)
{
Status = VfatOpenFile(DeviceExt, &PathNameU, FileObject, RequestedDisposition, &ParentFcb);
}
else
{
PVFATFCB TargetFcb;
LONG idx, FileNameLen;
if (Status == STATUS_OBJECT_NAME_COLLISION)
ParentFcb = (FileObject->RelatedFileObject != NULL) ? FileObject->RelatedFileObject->FsContext : NULL;
Status = vfatGetFCBForFile(DeviceExt, &ParentFcb, &TargetFcb, &PathNameU);
if (Status == STATUS_SUCCESS)
{
ParentFcb->RefCount++;
vfatReleaseFCB(DeviceExt, TargetFcb);
Irp->IoStatus.Information = FILE_EXISTS;
}
else
@ -593,10 +591,6 @@ VfatCreateFile(
/* 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;
@ -608,34 +602,49 @@ VfatCreateFile(
/* 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);
ASSERT(FileObject->RelatedFileObject != NULL);
/* No need to modify the FO, it already has the name */
}
/* We're done with opening! */
if (ParentFcb != NULL)
{
Status = vfatAttachFCBToFileObject(DeviceExt, ParentFcb, FileObject);
}
if (NT_SUCCESS(Status))
{
pFcb = FileObject->FsContext;
if (pFcb->OpenHandleCount == 0)
{
IoSetShareAccess(Stack->Parameters.Create.SecurityContext->DesiredAccess,
Stack->Parameters.Create.ShareAccess,
FileObject,
&pFcb->FCBShareAccess);
}
else
{
Status = IoCheckShareAccess(Stack->Parameters.Create.SecurityContext->DesiredAccess,
Stack->Parameters.Create.ShareAccess,
FileObject,
&pFcb->FCBShareAccess,
FALSE);
if (!NT_SUCCESS(Status))
{
VfatCloseFile(DeviceExt, FileObject);
return Status;
}
}
pFcb->OpenHandleCount++;
}
else if (ParentFcb != NULL)
{
vfatReleaseFCB(DeviceExt, ParentFcb);
}
return Status;
}
@ -673,7 +682,7 @@ VfatCreateFile(
Attributes |= FILE_ATTRIBUTE_ARCHIVE;
vfatSplitPathName(&PathNameU, NULL, &FileNameU);
Status = VfatAddEntry(DeviceExt, &FileNameU, &pFcb, ParentFcb, RequestedOptions,
(UCHAR)(Attributes & FILE_ATTRIBUTE_VALID_FLAGS));
(UCHAR)(Attributes & FILE_ATTRIBUTE_VALID_FLAGS), NULL);
vfatReleaseFCB(DeviceExt, ParentFcb);
if (NT_SUCCESS(Status))
{

View file

@ -1,8 +1,11 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/fs/vfat/dirwr.c
* FILE: drivers/filesystems/fastfat/dirwr.c
* PURPOSE: VFAT Filesystem : write in directory
* PROGRAMMER: Rex Jolliff (rex@lvcablemodem.com)
* Herve Poussineau (reactos@poussine.freesurf.fr)
* Pierre Schweitzer (pierre@reactos.org)
*
*/
@ -66,6 +69,70 @@ VfatUpdateEntry(
}
}
/*
* rename an existing FAT entry
*/
NTSTATUS
vfatRenameEntry(
IN PDEVICE_EXTENSION DeviceExt,
IN PVFATFCB pFcb,
IN PUNICODE_STRING FileName,
IN BOOLEAN CaseChangeOnly)
{
OEM_STRING NameA;
ULONG StartIndex;
PVOID Context = NULL;
LARGE_INTEGER Offset;
PFATX_DIR_ENTRY pDirEntry;
UNICODE_STRING ShortName;
NTSTATUS Status;
DPRINT("vfatRenameEntry(%p, %p, %wZ, %d)\n", DeviceExt, pFcb, FileName, CaseChangeOnly);
if (pFcb->Flags & FCB_IS_FATX_ENTRY)
{
/* Open associated dir entry */
StartIndex = pFcb->startIndex;
Offset.u.HighPart = 0;
Offset.u.LowPart = (StartIndex * sizeof(FATX_DIR_ENTRY) / PAGE_SIZE) * PAGE_SIZE;
if (!CcPinRead(pFcb->parentFcb->FileObject, &Offset, sizeof(FATX_DIR_ENTRY), TRUE,
&Context, (PVOID*)&pDirEntry))
{
DPRINT1("CcPinRead(Offset %x:%x, Length %d) failed\n", Offset.u.HighPart, Offset.u.LowPart, PAGE_SIZE);
return STATUS_UNSUCCESSFUL;
}
pDirEntry = &pDirEntry[StartIndex % (PAGE_SIZE / sizeof(FATX_DIR_ENTRY))];
/* Set file name */
NameA.Buffer = (PCHAR)pDirEntry->Filename;
NameA.Length = 0;
NameA.MaximumLength = 42;
RtlUnicodeStringToOemString(&NameA, FileName, FALSE);
pDirEntry->FilenameLength = (unsigned char)NameA.Length;
CcSetDirtyPinnedData(Context, NULL);
CcUnpinData(Context);
/* Update FCB */
ShortName.Length = 0;
ShortName.MaximumLength = 0;
ShortName.Buffer = NULL;
Status = vfatUpdateFCB(DeviceExt, pFcb, FileName, &ShortName, pFcb->parentFcb);
if (NT_SUCCESS(Status))
{
CcPurgeCacheSection(&pFcb->parentFcb->SectionObjectPointers, NULL, 0, FALSE);
}
return Status;
}
else
{
/* This we cannot handle properly, move file - would likely need love */
return VfatMoveEntry(DeviceExt, pFcb, FileName, pFcb->parentFcb);
}
}
/*
* try to find contiguous entries frees in directory,
* extend a directory if is neccesary
@ -200,7 +267,8 @@ FATAddEntry(
IN PVFATFCB* Fcb,
IN PVFATFCB ParentFcb,
IN ULONG RequestedOptions,
IN UCHAR ReqAttr)
IN UCHAR ReqAttr,
IN PVFAT_MOVE_CONTEXT MoveContext)
{
PVOID Context = NULL;
PFAT_DIR_ENTRY pFatEntry;
@ -385,6 +453,13 @@ FATAddEntry(
DirContext.DirEntry.Fat.UpdateDate = DirContext.DirEntry.Fat.CreationDate;
DirContext.DirEntry.Fat.UpdateTime = DirContext.DirEntry.Fat.CreationTime;
DirContext.DirEntry.Fat.AccessDate = DirContext.DirEntry.Fat.CreationDate;
/* If it's moving, preserve creation time and file size */
if (MoveContext != NULL)
{
DirContext.DirEntry.Fat.CreationDate = MoveContext->CreationDate;
DirContext.DirEntry.Fat.CreationTime = MoveContext->CreationTime;
DirContext.DirEntry.Fat.FileSize = MoveContext->FileSize;
}
if (needLong)
{
@ -423,17 +498,36 @@ FATAddEntry(
DirContext.DirIndex = DirContext.StartIndex + nbSlots - 1;
if (RequestedOptions & FILE_DIRECTORY_FILE)
{
CurrentCluster = 0;
Status = NextCluster(DeviceExt, 0, &CurrentCluster, TRUE);
if (CurrentCluster == 0xffffffff || !NT_SUCCESS(Status))
/* If we aren't moving, use next */
if (MoveContext == NULL)
{
ExFreePoolWithTag(Buffer, TAG_VFAT);
if (!NT_SUCCESS(Status))
CurrentCluster = 0;
Status = NextCluster(DeviceExt, 0, &CurrentCluster, TRUE);
if (CurrentCluster == 0xffffffff || !NT_SUCCESS(Status))
{
return Status;
ExFreePoolWithTag(Buffer, TAG_VFAT);
if (!NT_SUCCESS(Status))
{
return Status;
}
return STATUS_DISK_FULL;
}
return STATUS_DISK_FULL;
}
else
{
CurrentCluster = MoveContext->FirstCluster;
}
if (DeviceExt->FatInfo.FatType == FAT32)
{
DirContext.DirEntry.Fat.FirstClusterHigh = (unsigned short)(CurrentCluster >> 16);
}
DirContext.DirEntry.Fat.FirstCluster = (unsigned short)CurrentCluster;
}
else if (MoveContext != NULL)
{
CurrentCluster = MoveContext->FirstCluster;
if (DeviceExt->FatInfo.FatType == FAT32)
{
DirContext.DirEntry.Fat.FirstClusterHigh = (unsigned short)(CurrentCluster >> 16);
@ -491,7 +585,17 @@ FATAddEntry(
CcSetDirtyPinnedData(Context, NULL);
CcUnpinData(Context);
Status = vfatMakeFCBFromDirEntry(DeviceExt, ParentFcb, &DirContext, Fcb);
if (MoveContext != NULL)
{
/* We're modifying an existing FCB - likely rename/move */
Status = vfatUpdateFCB(DeviceExt, *Fcb, &DirContext.LongNameU, &DirContext.ShortNameU, ParentFcb);
(*Fcb)->dirIndex = DirContext.DirIndex;
(*Fcb)->startIndex = DirContext.StartIndex;
}
else
{
Status = vfatMakeFCBFromDirEntry(DeviceExt, ParentFcb, &DirContext, Fcb);
}
if (!NT_SUCCESS(Status))
{
ExFreePoolWithTag(Buffer, TAG_VFAT);
@ -510,13 +614,17 @@ FATAddEntry(
ExFreePoolWithTag(Buffer, TAG_VFAT);
return STATUS_UNSUCCESSFUL;
}
/* clear the new directory cluster */
RtlZeroMemory(pFatEntry, DeviceExt->FatInfo.BytesPerCluster);
/* create '.' and '..' */
RtlCopyMemory(&pFatEntry[0].Attrib, &DirContext.DirEntry.Fat.Attrib, sizeof(FAT_DIR_ENTRY) - 11);
RtlCopyMemory(pFatEntry[0].ShortName, ". ", 11);
RtlCopyMemory(&pFatEntry[1].Attrib, &DirContext.DirEntry.Fat.Attrib, sizeof(FAT_DIR_ENTRY) - 11);
RtlCopyMemory(pFatEntry[1].ShortName, ".. ", 11);
/* clear the new directory cluster if not moving */
if (MoveContext == NULL)
{
RtlZeroMemory(pFatEntry, DeviceExt->FatInfo.BytesPerCluster);
/* create '.' and '..' */
RtlCopyMemory(&pFatEntry[0].Attrib, &DirContext.DirEntry.Fat.Attrib, sizeof(FAT_DIR_ENTRY) - 11);
RtlCopyMemory(pFatEntry[0].ShortName, ". ", 11);
RtlCopyMemory(&pFatEntry[1].Attrib, &DirContext.DirEntry.Fat.Attrib, sizeof(FAT_DIR_ENTRY) - 11);
RtlCopyMemory(pFatEntry[1].ShortName, ".. ", 11);
}
pFatEntry[1].FirstCluster = ParentFcb->entry.Fat.FirstCluster;
pFatEntry[1].FirstClusterHigh = ParentFcb->entry.Fat.FirstClusterHigh;
if (vfatFCBIsRoot(ParentFcb))
@ -542,7 +650,8 @@ FATXAddEntry(
IN PVFATFCB* Fcb,
IN PVFATFCB ParentFcb,
IN ULONG RequestedOptions,
IN UCHAR ReqAttr)
IN UCHAR ReqAttr,
IN PVFAT_MOVE_CONTEXT MoveContext)
{
PVOID Context = NULL;
LARGE_INTEGER SystemTime, FileOffset;
@ -578,7 +687,15 @@ FATXAddEntry(
DirContext.ShortNameU.MaximumLength = 0;
RtlZeroMemory(&DirContext.DirEntry.FatX, sizeof(FATX_DIR_ENTRY));
memset(DirContext.DirEntry.FatX.Filename, 0xff, 42);
DirContext.DirEntry.FatX.FirstCluster = 0;
/* Use cluster, if moving */
if (MoveContext != NULL)
{
DirContext.DirEntry.FatX.FirstCluster = MoveContext->FirstCluster;
}
else
{
DirContext.DirEntry.FatX.FirstCluster = 0;
}
DirContext.DirEntry.FatX.FileSize = 0;
/* set file name */
@ -603,6 +720,13 @@ FATXAddEntry(
DirContext.DirEntry.FatX.UpdateTime = DirContext.DirEntry.FatX.CreationTime;
DirContext.DirEntry.FatX.AccessDate = DirContext.DirEntry.FatX.CreationDate;
DirContext.DirEntry.FatX.AccessTime = DirContext.DirEntry.FatX.CreationTime;
/* If it's moving, preserve creation time and file size */
if (MoveContext != NULL)
{
DirContext.DirEntry.FatX.CreationDate = MoveContext->CreationDate;
DirContext.DirEntry.FatX.CreationTime = MoveContext->CreationTime;
DirContext.DirEntry.FatX.FileSize = MoveContext->FileSize;
}
/* add entry into parent directory */
FileOffset.u.HighPart = 0;
@ -616,8 +740,19 @@ FATXAddEntry(
CcSetDirtyPinnedData(Context, NULL);
CcUnpinData(Context);
/* FIXME: check status */
vfatMakeFCBFromDirEntry(DeviceExt, ParentFcb, &DirContext, Fcb);
if (MoveContext != NULL)
{
/* We're modifying an existing FCB - likely rename/move */
/* FIXME: check status */
vfatUpdateFCB(DeviceExt, *Fcb, &DirContext.LongNameU, &DirContext.ShortNameU, ParentFcb);
(*Fcb)->dirIndex = DirContext.DirIndex;
(*Fcb)->startIndex = DirContext.StartIndex;
}
else
{
/* FIXME: check status */
vfatMakeFCBFromDirEntry(DeviceExt, ParentFcb, &DirContext, Fcb);
}
DPRINT("addentry ok\n");
return STATUS_SUCCESS;
@ -630,12 +765,13 @@ VfatAddEntry(
IN PVFATFCB *Fcb,
IN PVFATFCB ParentFcb,
IN ULONG RequestedOptions,
IN UCHAR ReqAttr)
IN UCHAR ReqAttr,
IN PVFAT_MOVE_CONTEXT MoveContext)
{
if (DeviceExt->Flags & VCB_IS_FATX)
return FATXAddEntry(DeviceExt, NameU, Fcb, ParentFcb, RequestedOptions, ReqAttr);
return FATXAddEntry(DeviceExt, NameU, Fcb, ParentFcb, RequestedOptions, ReqAttr, MoveContext);
else
return FATAddEntry(DeviceExt, NameU, Fcb, ParentFcb, RequestedOptions, ReqAttr);
return FATAddEntry(DeviceExt, NameU, Fcb, ParentFcb, RequestedOptions, ReqAttr, MoveContext);
}
/*
@ -644,7 +780,8 @@ VfatAddEntry(
static NTSTATUS
FATDelEntry(
IN PDEVICE_EXTENSION DeviceExt,
IN PVFATFCB pFcb)
IN PVFATFCB pFcb,
OUT PVFAT_MOVE_CONTEXT MoveContext)
{
ULONG CurrentCluster = 0, NextCluster, i;
PVOID Context = NULL;
@ -687,13 +824,26 @@ FATDelEntry(
CcUnpinData(Context);
}
while (CurrentCluster && CurrentCluster != 0xffffffff)
/* In case of moving, don't delete data */
if (MoveContext != NULL)
{
GetNextCluster(DeviceExt, CurrentCluster, &NextCluster);
/* FIXME: check status */
WriteCluster(DeviceExt, CurrentCluster, 0);
CurrentCluster = NextCluster;
pDirEntry = &pDirEntry[pFcb->dirIndex % (PAGE_SIZE / sizeof(FAT_DIR_ENTRY))];
MoveContext->FirstCluster = CurrentCluster;
MoveContext->FileSize = pDirEntry->FileSize;
MoveContext->CreationTime = pDirEntry->CreationTime;
MoveContext->CreationDate = pDirEntry->CreationDate;
}
else
{
while (CurrentCluster && CurrentCluster != 0xffffffff)
{
GetNextCluster(DeviceExt, CurrentCluster, &NextCluster);
/* FIXME: check status */
WriteCluster(DeviceExt, CurrentCluster, 0);
CurrentCluster = NextCluster;
}
}
return STATUS_SUCCESS;
}
@ -703,7 +853,8 @@ FATDelEntry(
static NTSTATUS
FATXDelEntry(
IN PDEVICE_EXTENSION DeviceExt,
IN PVFATFCB pFcb)
IN PVFATFCB pFcb,
OUT PVFAT_MOVE_CONTEXT MoveContext)
{
ULONG CurrentCluster = 0, NextCluster;
PVOID Context = NULL;
@ -734,25 +885,78 @@ FATXDelEntry(
CcSetDirtyPinnedData(Context, NULL);
CcUnpinData(Context);
while (CurrentCluster && CurrentCluster != 0xffffffff)
/* In case of moving, don't delete data */
if (MoveContext != NULL)
{
GetNextCluster(DeviceExt, CurrentCluster, &NextCluster);
/* FIXME: check status */
WriteCluster(DeviceExt, CurrentCluster, 0);
CurrentCluster = NextCluster;
MoveContext->FirstCluster = CurrentCluster;
MoveContext->FileSize = pDirEntry->FileSize;
MoveContext->CreationTime = pDirEntry->CreationTime;
MoveContext->CreationDate = pDirEntry->CreationDate;
}
else
{
while (CurrentCluster && CurrentCluster != 0xffffffff)
{
GetNextCluster(DeviceExt, CurrentCluster, &NextCluster);
/* FIXME: check status */
WriteCluster(DeviceExt, CurrentCluster, 0);
CurrentCluster = NextCluster;
}
}
return STATUS_SUCCESS;
}
NTSTATUS
VfatDelEntry(
IN PDEVICE_EXTENSION DeviceExt,
IN PVFATFCB pFcb)
IN PVFATFCB pFcb,
OUT PVFAT_MOVE_CONTEXT MoveContext)
{
if (DeviceExt->Flags & VCB_IS_FATX)
return FATXDelEntry(DeviceExt, pFcb);
return FATXDelEntry(DeviceExt, pFcb, MoveContext);
else
return FATDelEntry(DeviceExt, pFcb);
return FATDelEntry(DeviceExt, pFcb, MoveContext);
}
/*
* move an existing FAT entry
*/
NTSTATUS
VfatMoveEntry(
IN PDEVICE_EXTENSION DeviceExt,
IN PVFATFCB pFcb,
IN PUNICODE_STRING FileName,
IN PVFATFCB ParentFcb)
{
NTSTATUS Status;
PVFATFCB OldParent;
VFAT_MOVE_CONTEXT MoveContext;
DPRINT("VfatMoveEntry(%p, %p, %wZ, %p)\n", DeviceExt, pFcb, FileName, ParentFcb);
/* Delete old entry while keeping data */
Status = VfatDelEntry(DeviceExt, pFcb, &MoveContext);
if (!NT_SUCCESS(Status))
{
return Status;
}
OldParent = pFcb->parentFcb;
CcPurgeCacheSection(&OldParent->SectionObjectPointers, NULL, 0, FALSE);
/* Add our new entry with our cluster */
Status = VfatAddEntry(DeviceExt,
FileName,
&pFcb,
ParentFcb,
(vfatFCBIsDirectory(pFcb) ? FILE_DIRECTORY_FILE : 0),
*pFcb->Attributes,
&MoveContext);
CcPurgeCacheSection(&pFcb->parentFcb->SectionObjectPointers, NULL, 0, FALSE);
return Status;
}
/* EOF */

View file

@ -1,11 +1,12 @@
/*
* FILE: drivers/fs/vfat/fcb.c
* FILE: drivers/filesystems/fastfat/fcb.c
* PURPOSE: Routines to manipulate FCBs.
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
* Rex Jolliff (rex@lvcablemodem.com)
* Herve Poussineau (reactos@poussine.freesurf.fr)
* Pierre Schweitzer (pierre@reactos.org)
*/
/* ------------------------------------------------------- INCLUDES */
@ -156,6 +157,100 @@ vfatNewFCB(
return rcFCB;
}
static
VOID
vfatDelFCBFromTable(
PDEVICE_EXTENSION pVCB,
PVFATFCB pFCB)
{
ULONG Index;
ULONG ShortIndex;
HASHENTRY* entry;
Index = pFCB->Hash.Hash % pVCB->HashTableSize;
ShortIndex = pFCB->ShortHash.Hash % pVCB->HashTableSize;
if (pFCB->Hash.Hash != pFCB->ShortHash.Hash)
{
entry = pVCB->FcbHashTable[ShortIndex];
if (entry->self == pFCB)
{
pVCB->FcbHashTable[ShortIndex] = entry->next;
}
else
{
while (entry->next->self != pFCB)
{
entry = entry->next;
}
entry->next = pFCB->ShortHash.next;
}
}
entry = pVCB->FcbHashTable[Index];
if (entry->self == pFCB)
{
pVCB->FcbHashTable[Index] = entry->next;
}
else
{
while (entry->next->self != pFCB)
{
entry = entry->next;
}
entry->next = pFCB->Hash.next;
}
RemoveEntryList(&pFCB->FcbListEntry);
}
static
NTSTATUS
vfatMakeFullName(
PVFATFCB directoryFCB,
PUNICODE_STRING LongNameU,
PUNICODE_STRING ShortNameU,
PUNICODE_STRING NameU)
{
PWCHAR PathNameBuffer;
USHORT PathNameLength;
PathNameLength = directoryFCB->PathNameU.Length + max(LongNameU->Length, ShortNameU->Length);
if (!vfatFCBIsRoot(directoryFCB))
{
PathNameLength += sizeof(WCHAR);
}
if (PathNameLength > LONGNAME_MAX_LENGTH * sizeof(WCHAR))
{
return STATUS_OBJECT_NAME_INVALID;
}
PathNameBuffer = ExAllocatePoolWithTag(NonPagedPool, PathNameLength + sizeof(WCHAR), TAG_FCB);
if (!PathNameBuffer)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
NameU->Buffer = PathNameBuffer;
NameU->Length = 0;
NameU->MaximumLength = PathNameLength;
RtlCopyUnicodeString(NameU, &directoryFCB->PathNameU);
if (!vfatFCBIsRoot(directoryFCB))
{
RtlAppendUnicodeToString(NameU, L"\\");
}
if (LongNameU->Length > 0)
{
RtlAppendUnicodeStringToString(NameU, LongNameU);
}
else
{
RtlAppendUnicodeStringToString(NameU, ShortNameU);
}
NameU->Buffer[NameU->Length / sizeof(WCHAR)] = 0;
return STATUS_SUCCESS;
}
VOID
vfatDestroyCCB(
PVFATCCB pCcb)
@ -182,7 +277,7 @@ BOOLEAN
vfatFCBIsDirectory(
PVFATFCB FCB)
{
return *FCB->Attributes & FILE_ATTRIBUTE_DIRECTORY;
return ((*FCB->Attributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
}
BOOLEAN
@ -197,9 +292,6 @@ vfatReleaseFCB(
PDEVICE_EXTENSION pVCB,
PVFATFCB pFCB)
{
HASHENTRY* entry;
ULONG Index;
ULONG ShortIndex;
PVFATFCB tmpFcb;
DPRINT("releasing FCB at %p: %wZ, refCount:%d\n",
@ -207,42 +299,12 @@ vfatReleaseFCB(
while (pFCB)
{
Index = pFCB->Hash.Hash % pVCB->HashTableSize;
ShortIndex = pFCB->ShortHash.Hash % pVCB->HashTableSize;
pFCB->RefCount--;
if (pFCB->RefCount == 0)
{
ASSERT(pFCB->OpenHandleCount == 0);
tmpFcb = pFCB->parentFcb;
RemoveEntryList (&pFCB->FcbListEntry);
if (pFCB->Hash.Hash != pFCB->ShortHash.Hash)
{
entry = pVCB->FcbHashTable[ShortIndex];
if (entry->self == pFCB)
{
pVCB->FcbHashTable[ShortIndex] = entry->next;
}
else
{
while (entry->next->self != pFCB)
{
entry = entry->next;
}
entry->next = pFCB->ShortHash.next;
}
}
entry = pVCB->FcbHashTable[Index];
if (entry->self == pFCB)
{
pVCB->FcbHashTable[Index] = entry->next;
}
else
{
while (entry->next->self != pFCB)
{
entry = entry->next;
}
entry->next = pFCB->Hash.next;
}
vfatDelFCBFromTable(pVCB, pFCB);
vfatDestroyFCB(pFCB);
}
else
@ -253,6 +315,7 @@ vfatReleaseFCB(
}
}
static
VOID
vfatAddFCBToTable(
PDEVICE_EXTENSION pVCB,
@ -279,6 +342,76 @@ vfatAddFCBToTable(
}
}
NTSTATUS
vfatUpdateFCB(
PDEVICE_EXTENSION pVCB,
PVFATFCB Fcb,
PUNICODE_STRING LongName,
PUNICODE_STRING ShortName,
PVFATFCB ParentFcb)
{
NTSTATUS Status;
PVFATFCB OldParent;
DPRINT("vfatUpdateFCB(%p, %p, %wZ, %wZ, %p)\n", pVCB, Fcb, LongName, ShortName, ParentFcb);
/* Delete old name */
if (Fcb->PathNameBuffer)
{
ExFreePoolWithTag(Fcb->PathNameBuffer, TAG_FCB);
}
/* Delete from table */
vfatDelFCBFromTable(pVCB, Fcb);
/* Get full path name */
Status = vfatMakeFullName(ParentFcb, LongName, ShortName, &Fcb->PathNameU);
if (!NT_SUCCESS(Status))
{
return Status;
}
/* Split it properly */
Fcb->PathNameBuffer = Fcb->PathNameU.Buffer;
Fcb->DirNameU.Buffer = Fcb->PathNameU.Buffer;
vfatSplitPathName(&Fcb->PathNameU, &Fcb->DirNameU, &Fcb->LongNameU);
/* Copy short name */
RtlCopyUnicodeString(&Fcb->ShortNameU, ShortName);
/* Recompute hashes */
Fcb->Hash.Hash = vfatNameHash(0, &Fcb->PathNameU);
if (pVCB->Flags & VCB_IS_FATX)
{
Fcb->ShortHash.Hash = Fcb->Hash.Hash;
}
else
{
Fcb->ShortHash.Hash = vfatNameHash(0, &Fcb->DirNameU);
Fcb->ShortHash.Hash = vfatNameHash(Fcb->ShortHash.Hash, &Fcb->ShortNameU);
}
/* Set parent */
OldParent = Fcb->parentFcb;
Fcb->parentFcb = ParentFcb;
/* Add to the table */
vfatAddFCBToTable(pVCB, Fcb);
/* If we moved accross directories, dereferenced our old parent
* We also derefence in case we're just renaming since AddFCBToTable references it
*/
vfatReleaseFCB(pVCB, OldParent);
/* In case we were moving accross directories, reset caching on old parent */
//if (OldParent != ParentFcb)
//{
// CcUninitializeCacheMap(OldParent->FileObject, NULL, NULL);
//}
return STATUS_SUCCESS;
}
PVFATFCB
vfatGrabFCBFromTable(
PDEVICE_EXTENSION pVCB,
@ -460,48 +593,16 @@ vfatMakeFCBFromDirEntry(
PVFATFCB *fileFCB)
{
PVFATFCB rcFCB;
PWCHAR PathNameBuffer;
USHORT PathNameLength;
ULONG Size;
ULONG hash;
UNICODE_STRING NameU;
NTSTATUS Status;
PathNameLength = directoryFCB->PathNameU.Length + max(DirContext->LongNameU.Length, DirContext->ShortNameU.Length);
if (!vfatFCBIsRoot (directoryFCB))
Status = vfatMakeFullName(directoryFCB, &DirContext->LongNameU, &DirContext->ShortNameU, &NameU);
if (!NT_SUCCESS(Status))
{
PathNameLength += sizeof(WCHAR);
return Status;
}
if (PathNameLength > LONGNAME_MAX_LENGTH * sizeof(WCHAR))
{
return STATUS_OBJECT_NAME_INVALID;
}
PathNameBuffer = ExAllocatePoolWithTag(NonPagedPool, PathNameLength + sizeof(WCHAR), TAG_FCB);
if (!PathNameBuffer)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
NameU.Buffer = PathNameBuffer;
NameU.Length = 0;
NameU.MaximumLength = PathNameLength;
RtlCopyUnicodeString(&NameU, &directoryFCB->PathNameU);
if (!vfatFCBIsRoot(directoryFCB))
{
RtlAppendUnicodeToString(&NameU, L"\\");
}
hash = vfatNameHash(0, &NameU);
if (DirContext->LongNameU.Length > 0)
{
RtlAppendUnicodeStringToString(&NameU, &DirContext->LongNameU);
}
else
{
RtlAppendUnicodeStringToString(&NameU, &DirContext->ShortNameU);
}
NameU.Buffer[NameU.Length / sizeof(WCHAR)] = 0;
rcFCB = vfatNewFCB(vcb, &NameU);
RtlCopyMemory(&rcFCB->entry, &DirContext->DirEntry, sizeof (DIR_ENTRY));
RtlCopyUnicodeString(&rcFCB->ShortNameU, &DirContext->ShortNameU);
@ -511,7 +612,8 @@ vfatMakeFCBFromDirEntry(
}
else
{
rcFCB->ShortHash.Hash = vfatNameHash(hash, &rcFCB->ShortNameU);
rcFCB->ShortHash.Hash = vfatNameHash(0, &rcFCB->DirNameU);
rcFCB->ShortHash.Hash = vfatNameHash(rcFCB->ShortHash.Hash, &rcFCB->ShortNameU);
}
if (vfatFCBIsDirectory(rcFCB))
@ -562,7 +664,7 @@ vfatMakeFCBFromDirEntry(
vfatAddFCBToTable(vcb, rcFCB);
*fileFCB = rcFCB;
ExFreePool(PathNameBuffer);
ExFreePool(NameU.Buffer);
return STATUS_SUCCESS;
}

View file

@ -1,10 +1,11 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/fs/vfat/finfo.c
* FILE: drivers/filesystems/fastfat/finfo.c
* PURPOSE: VFAT Filesystem
* PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
* Herve Poussineau (reactos@poussine.freesurf.fr)
* Pierre Schweitzer (pierre@reactos.org)
*
*/
@ -373,6 +374,467 @@ VfatSetDispositionInformation(
return STATUS_SUCCESS;
}
static NTSTATUS
vfatPrepareTargetForRename(
IN PDEVICE_EXTENSION DeviceExt,
IN PVFATFCB * ParentFCB,
IN PUNICODE_STRING NewName,
IN BOOLEAN ReplaceIfExists,
IN PUNICODE_STRING ParentName,
OUT PBOOLEAN Deleted)
{
NTSTATUS Status;
PVFATFCB TargetFcb;
DPRINT("vfatPrepareTargetForRename(%p, %p, %wZ, %d, %wZ, %p)\n", DeviceExt, ParentFCB, NewName, ReplaceIfExists, ParentName);
*Deleted = FALSE;
/* Try to open target */
Status = vfatGetFCBForFile(DeviceExt, ParentFCB, &TargetFcb, NewName);
/* If it exists */
if (NT_SUCCESS(Status))
{
/* Check whether we are allowed to replace */
if (ReplaceIfExists)
{
/* If that's a directory or a read-only file, we're not allowed */
if (vfatFCBIsDirectory(TargetFcb) || ((*TargetFcb->Attributes & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY));
{
*ParentFCB = NULL;
vfatReleaseFCB(DeviceExt, TargetFcb);
return STATUS_OBJECT_NAME_COLLISION;
}
/* Attempt to flush (might close the file) */
if (!MmFlushImageSection(TargetFcb->FileObject->SectionObjectPointer, MmFlushForDelete))
{
*ParentFCB = NULL;
vfatReleaseFCB(DeviceExt, TargetFcb);
return STATUS_ACCESS_DENIED;
}
/* If we are, ensure the file isn't open by anyone! */
if (TargetFcb->OpenHandleCount != 0)
{
*ParentFCB = NULL;
vfatReleaseFCB(DeviceExt, TargetFcb);
return STATUS_ACCESS_DENIED;
}
/* Effectively delete old file to allow renaming */
VfatDelEntry(DeviceExt, TargetFcb, NULL);
(*ParentFCB)->RefCount++;
vfatReleaseFCB(DeviceExt, TargetFcb);
*Deleted = TRUE;
}
else
{
*ParentFCB = NULL;
vfatReleaseFCB(DeviceExt, TargetFcb);
return STATUS_OBJECT_NAME_COLLISION;
}
}
else if (*ParentFCB != NULL)
{
return STATUS_SUCCESS;
}
/* Failure */
return Status;
}
/*
* FUNCTION: Set the file name information
*/
static
NTSTATUS
VfatSetRenameInformation(
PFILE_OBJECT FileObject,
PVFATFCB FCB,
PDEVICE_EXTENSION DeviceObject,
PFILE_RENAME_INFORMATION RenameInfo,
PFILE_OBJECT TargetFileObject)
{
NTSTATUS Status;
UNICODE_STRING NewName;
UNICODE_STRING SourcePath;
UNICODE_STRING SourceFile;
UNICODE_STRING NewPath;
UNICODE_STRING NewFile;
PFILE_OBJECT RootFileObject;
PVFATFCB RootFCB;
UNICODE_STRING RenameInfoString;
PVFATFCB ParentFCB;
IO_STATUS_BLOCK IoStatusBlock;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE TargetHandle;
BOOLEAN DeletedTarget;
DPRINT("VfatSetRenameInfo(%p, %p, %p, %p, %p)\n", FileObject, FCB, DeviceObject, RenameInfo, TargetFileObject);
/* Disallow renaming root */
if (vfatFCBIsRoot(FCB))
{
return STATUS_INVALID_PARAMETER;
}
/* If we are performing relative opening for rename, get FO for getting FCB and path name */
if (RenameInfo->RootDirectory != NULL)
{
/* We cannot tolerate relative opening with a full path */
if (RenameInfo->FileName[0] == L'\\')
{
return STATUS_OBJECT_NAME_INVALID;
}
Status = ObReferenceObjectByHandle(RenameInfo->RootDirectory,
FILE_READ_DATA,
*IoFileObjectType,
ExGetPreviousMode(),
(PVOID *)&RootFileObject,
NULL);
if (!NT_SUCCESS(Status))
{
return Status;
}
RootFCB = RootFileObject->FsContext;
}
ParentFCB = NULL;
if (TargetFileObject == NULL)
{
/* If we don't have target file object, construct paths thanks to relative FCB, if any, and with
* information supplied by the user
*/
/* First, setup a string we'll work on */
RenameInfoString.Length = RenameInfo->FileNameLength;
RenameInfoString.MaximumLength = RenameInfo->FileNameLength;
RenameInfoString.Buffer = RenameInfo->FileName;
/* Check whether we have FQN */
if (RenameInfoString.Length > 6 * sizeof(WCHAR))
{
if (RenameInfoString.Buffer[0] == L'\\' && RenameInfoString.Buffer[1] == L'?' &&
RenameInfoString.Buffer[2] == L'?' && RenameInfoString.Buffer[3] == L'\\' &&
RenameInfoString.Buffer[5] == L':' && (RenameInfoString.Buffer[4] >= L'A' &&
RenameInfoString.Buffer[4] <= L'Z'))
{
/* If so, open its target directory */
InitializeObjectAttributes(&ObjectAttributes,
&RenameInfoString,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL, NULL);
Status = IoCreateFile(&TargetHandle,
FILE_WRITE_DATA | 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);
if (!NT_SUCCESS(Status))
{
goto Cleanup;
}
/* Get its FO to get the FCB */
Status = ObReferenceObjectByHandle(TargetHandle,
FILE_WRITE_DATA,
*IoFileObjectType,
KernelMode,
(PVOID *)&TargetFileObject,
NULL);
if (!NT_SUCCESS(Status))
{
ZwClose(TargetHandle);
goto Cleanup;
}
/* Are we working on the same volume? */
if (IoGetRelatedDeviceObject(TargetFileObject) != IoGetRelatedDeviceObject(FileObject))
{
ObDereferenceObject(TargetFileObject);
ZwClose(TargetHandle);
TargetFileObject = NULL;
Status = STATUS_NOT_SAME_DEVICE;
goto Cleanup;
}
}
}
NewName.Length = 0;
NewName.MaximumLength = RenameInfo->FileNameLength;
if (RenameInfo->RootDirectory != NULL)
{
NewName.MaximumLength += sizeof(WCHAR) + RootFCB->PathNameU.Length;
}
else if (RenameInfo->FileName[0] != L'\\')
{
/* We don't have full path, and we don't have root directory:
* => we move inside the same directory
*/
NewName.MaximumLength += sizeof(WCHAR) + FCB->DirNameU.Length;
}
else if (TargetFileObject != NULL)
{
/* We had a FQN:
* => we need to use its correct path
*/
NewName.MaximumLength += sizeof(WCHAR) + ((PVFATFCB)TargetFileObject->FsContext)->PathNameU.Length;
}
NewName.Buffer = ExAllocatePoolWithTag(NonPagedPool, NewName.MaximumLength, TAG_VFAT);
if (NewName.Buffer == NULL)
{
if (TargetFileObject != NULL)
{
ObDereferenceObject(TargetFileObject);
ZwClose(TargetHandle);
TargetFileObject = NULL;
}
Status = STATUS_INSUFFICIENT_RESOURCES;
goto Cleanup;
}
if (RenameInfo->RootDirectory != NULL)
{
/* Here, copy first absolute and then append relative */
RtlCopyUnicodeString(&NewName, &RootFCB->PathNameU);
NewName.Buffer[NewName.Length / sizeof(WCHAR)] = L'\\';
NewName.Length += sizeof(WCHAR);
RtlAppendUnicodeStringToString(&NewName, &RenameInfoString);
}
else if (RenameInfo->FileName[0] != L'\\')
{
/* Here, copy first work directory and then append filename */
RtlCopyUnicodeString(&NewName, &FCB->DirNameU);
NewName.Buffer[NewName.Length / sizeof(WCHAR)] = L'\\';
NewName.Length += sizeof(WCHAR);
RtlAppendUnicodeStringToString(&NewName, &RenameInfoString);
}
else if (TargetFileObject != NULL)
{
/* Here, copy first path name and then append filename */
RtlCopyUnicodeString(&NewName, &((PVFATFCB)TargetFileObject->FsContext)->PathNameU);
NewName.Buffer[NewName.Length / sizeof(WCHAR)] = L'\\';
NewName.Length += sizeof(WCHAR);
RtlAppendUnicodeStringToString(&NewName, &RenameInfoString);
}
else
{
/* Here we should have full path, so simply copy it */
RtlCopyUnicodeString(&NewName, &RenameInfoString);
}
/* Do we have to cleanup some stuff? */
if (TargetFileObject != NULL)
{
ObDereferenceObject(TargetFileObject);
ZwClose(TargetHandle);
TargetFileObject = NULL;
}
}
else
{
/* At that point, we shouldn't care about whether we are relative opening
* Target FO FCB should already have full path
*/
/* Before constructing string, just make a sanity check (just to be sure!) */
if (IoGetRelatedDeviceObject(TargetFileObject) != IoGetRelatedDeviceObject(FileObject))
{
Status = STATUS_NOT_SAME_DEVICE;
goto Cleanup;
}
NewName.Length = 0;
NewName.MaximumLength = TargetFileObject->FileName.Length + ((PVFATFCB)TargetFileObject->FsContext)->PathNameU.Length + sizeof(WCHAR);
NewName.Buffer = ExAllocatePoolWithTag(NonPagedPool, NewName.MaximumLength, TAG_VFAT);
if (NewName.Buffer == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto Cleanup;
}
RtlCopyUnicodeString(&NewName, &((PVFATFCB)TargetFileObject->FsContext)->PathNameU);
NewName.Buffer[NewName.Length / sizeof(WCHAR)] = L'\\';
NewName.Length += sizeof(WCHAR);
RtlAppendUnicodeStringToString(&NewName, &TargetFileObject->FileName);
}
/* Explode our paths to get path & filename */
vfatSplitPathName(&FCB->PathNameU, &SourcePath, &SourceFile);
DPRINT("Old dir: %wZ, Old file: %wZ\n", &SourcePath, &SourceFile);
vfatSplitPathName(&NewName, &NewPath, &NewFile);
DPRINT("New dir: %wZ, New file: %wZ\n", &NewPath, &NewFile);
/* Are we working in place? */
if (FsRtlAreNamesEqual(&SourcePath, &NewPath, TRUE, NULL))
{
if (FsRtlAreNamesEqual(&SourceFile, &NewFile, FALSE, NULL))
{
Status = STATUS_SUCCESS;
goto Cleanup;
}
if (FsRtlAreNamesEqual(&SourceFile, &NewFile, TRUE, NULL))
{
FsRtlNotifyFullReportChange(DeviceObject->NotifySync,
&(DeviceObject->NotifyList),
(PSTRING)&FCB->PathNameU,
FCB->PathNameU.Length - FCB->LongNameU.Length,
NULL,
NULL,
((*FCB->Attributes & FILE_ATTRIBUTE_DIRECTORY) ?
FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME),
FILE_ACTION_RENAMED_OLD_NAME,
NULL);
Status = vfatRenameEntry(DeviceObject, FCB, &NewFile, TRUE);
if (NT_SUCCESS(Status))
{
FsRtlNotifyFullReportChange(DeviceObject->NotifySync,
&(DeviceObject->NotifyList),
(PSTRING)&FCB->PathNameU,
FCB->PathNameU.Length - FCB->LongNameU.Length,
NULL,
NULL,
((*FCB->Attributes & FILE_ATTRIBUTE_DIRECTORY) ?
FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME),
FILE_ACTION_RENAMED_NEW_NAME,
NULL);
}
}
else
{
/* Try to find target */
ParentFCB = FCB->parentFcb;
ParentFCB->RefCount++;
Status = vfatPrepareTargetForRename(DeviceObject,
&ParentFCB,
&NewFile,
RenameInfo->ReplaceIfExists,
&NewPath,
&DeletedTarget);
if (!NT_SUCCESS(Status))
{
goto Cleanup;
}
FsRtlNotifyFullReportChange(DeviceObject->NotifySync,
&(DeviceObject->NotifyList),
(PSTRING)&FCB->PathNameU,
FCB->PathNameU.Length - FCB->LongNameU.Length,
NULL,
NULL,
((*FCB->Attributes & FILE_ATTRIBUTE_DIRECTORY) ?
FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME),
(DeletedTarget ? FILE_ACTION_REMOVED : FILE_ACTION_RENAMED_OLD_NAME),
NULL);
Status = vfatRenameEntry(DeviceObject, FCB, &NewFile, FALSE);
if (NT_SUCCESS(Status))
{
if (DeletedTarget)
{
FsRtlNotifyFullReportChange(DeviceObject->NotifySync,
&(DeviceObject->NotifyList),
(PSTRING)&FCB->PathNameU,
FCB->PathNameU.Length - FCB->LongNameU.Length,
NULL,
NULL,
FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE
| FILE_NOTIFY_CHANGE_LAST_ACCESS | FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_EA,
FILE_ACTION_MODIFIED,
NULL);
}
else
{
FsRtlNotifyFullReportChange(DeviceObject->NotifySync,
&(DeviceObject->NotifyList),
(PSTRING)&FCB->PathNameU,
FCB->PathNameU.Length - FCB->LongNameU.Length,
NULL,
NULL,
((*FCB->Attributes & FILE_ATTRIBUTE_DIRECTORY) ?
FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME),
FILE_ACTION_RENAMED_NEW_NAME,
NULL);
}
}
}
}
else
{
/* Try to find target */
ParentFCB = NULL;
Status = vfatPrepareTargetForRename(DeviceObject,
&ParentFCB,
&NewName,
RenameInfo->ReplaceIfExists,
&NewPath,
&DeletedTarget);
if (!NT_SUCCESS(Status))
{
goto Cleanup;
}
FsRtlNotifyFullReportChange(DeviceObject->NotifySync,
&(DeviceObject->NotifyList),
(PSTRING)&FCB->PathNameU,
FCB->PathNameU.Length - FCB->LongNameU.Length,
NULL,
NULL,
((*FCB->Attributes & FILE_ATTRIBUTE_DIRECTORY) ?
FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME),
FILE_ACTION_REMOVED,
NULL);
Status = VfatMoveEntry(DeviceObject, FCB, &NewFile, ParentFCB);
if (NT_SUCCESS(Status))
{
if (DeletedTarget)
{
FsRtlNotifyFullReportChange(DeviceObject->NotifySync,
&(DeviceObject->NotifyList),
(PSTRING)&FCB->PathNameU,
FCB->PathNameU.Length - FCB->LongNameU.Length,
NULL,
NULL,
FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE
| FILE_NOTIFY_CHANGE_LAST_ACCESS | FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_EA,
FILE_ACTION_MODIFIED,
NULL);
}
else
{
FsRtlNotifyFullReportChange(DeviceObject->NotifySync,
&(DeviceObject->NotifyList),
(PSTRING)&FCB->PathNameU,
FCB->PathNameU.Length - FCB->LongNameU.Length,
NULL,
NULL,
((*FCB->Attributes & FILE_ATTRIBUTE_DIRECTORY) ?
FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME),
FILE_ACTION_ADDED,
NULL);
}
}
}
Cleanup:
if (ParentFCB != NULL) vfatReleaseFCB(DeviceObject, ParentFCB);
if (NewName.Buffer != NULL) ExFreePoolWithTag(NewName.Buffer, TAG_VFAT);
if (RenameInfo->RootDirectory != NULL) ObDereferenceObject(RootFileObject);
return Status;
}
/*
* FUNCTION: Retrieve the file name information
*/
@ -1005,11 +1467,24 @@ VfatSetInformation(
DPRINT("Can set file size\n");
}
if (FileInformationClass == FileRenameInformation)
{
if (!ExAcquireResourceExclusiveLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource,
(BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
{
return VfatQueueRequest(IrpContext);
}
}
if (!(FCB->Flags & FCB_IS_PAGE_FILE))
{
if (!ExAcquireResourceExclusiveLite(&FCB->MainResource,
(BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
{
if (FileInformationClass == FileRenameInformation)
{
ExReleaseResourceLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource);
}
return VfatQueueRequest(IrpContext);
}
}
@ -1044,7 +1519,11 @@ VfatSetInformation(
break;
case FileRenameInformation:
Status = STATUS_NOT_IMPLEMENTED;
Status = VfatSetRenameInformation(IrpContext->FileObject,
FCB,
IrpContext->DeviceExt,
SystemBuffer,
IrpContext->Stack->Parameters.SetFile.FileObject);
break;
default:
@ -1056,6 +1535,11 @@ VfatSetInformation(
ExReleaseResourceLite(&FCB->MainResource);
}
if (FileInformationClass == FileRenameInformation)
{
ExReleaseResourceLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource);
}
IrpContext->Irp->IoStatus.Status = Status;
IrpContext->Irp->IoStatus.Information = 0;
IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);

View file

@ -460,6 +460,13 @@ typedef struct _VFAT_DIRENTRY_CONTEXT
UNICODE_STRING ShortNameU;
} VFAT_DIRENTRY_CONTEXT, *PVFAT_DIRENTRY_CONTEXT;
typedef struct _VFAT_MOVE_CONTEXT
{
ULONG FirstCluster;
ULONG FileSize;
USHORT CreationDate;
USHORT CreationTime;
} VFAT_MOVE_CONTEXT, *PVFAT_MOVE_CONTEXT;
/* blockdev.c */
@ -594,7 +601,8 @@ VfatAddEntry(
PVFATFCB* Fcb,
PVFATFCB ParentFcb,
ULONG RequestedOptions,
UCHAR ReqAttr);
UCHAR ReqAttr,
PVFAT_MOVE_CONTEXT MoveContext);
NTSTATUS
VfatUpdateEntry(
@ -603,7 +611,8 @@ VfatUpdateEntry(
NTSTATUS
VfatDelEntry(
PDEVICE_EXTENSION,
PVFATFCB);
PVFATFCB,
PVFAT_MOVE_CONTEXT);
BOOLEAN
vfatFindDirSpace(
@ -612,6 +621,20 @@ vfatFindDirSpace(
ULONG nbSlots,
PULONG start);
NTSTATUS
vfatRenameEntry(
IN PDEVICE_EXTENSION DeviceExt,
IN PVFATFCB pFcb,
IN PUNICODE_STRING FileName,
IN BOOLEAN CaseChangeOnly);
NTSTATUS
VfatMoveEntry(
IN PDEVICE_EXTENSION DeviceExt,
IN PVFATFCB pFcb,
IN PUNICODE_STRING FileName,
IN PVFATFCB ParentFcb);
/* ea.h */
NTSTATUS
@ -747,6 +770,14 @@ vfatNewFCB(
PDEVICE_EXTENSION pVCB,
PUNICODE_STRING pFileNameU);
NTSTATUS
vfatUpdateFCB(
PDEVICE_EXTENSION pVCB,
PVFATFCB Fcb,
PUNICODE_STRING LongName,
PUNICODE_STRING ShortName,
PVFATFCB ParentFcb);
VOID
vfatDestroyFCB(
PVFATFCB pFCB);
@ -765,11 +796,6 @@ vfatReleaseFCB(
PDEVICE_EXTENSION pVCB,
PVFATFCB pFCB);
VOID
vfatAddFCBToTable(
PDEVICE_EXTENSION pVCB,
PVFATFCB pFCB);
PVFATFCB
vfatGrabFCBFromTable(
PDEVICE_EXTENSION pDeviceExt,

View file

@ -736,12 +736,12 @@ NpCreateNewNamedPipe(IN PNP_DCB Dcb,
}
SecurityContext = &AccessState->SubjectSecurityContext;
SeLockSubjectContext(&AccessState->SubjectSecurityContext);
SeLockSubjectContext(SecurityContext);
Status = SeAssignSecurity(0,
Status = SeAssignSecurity(NULL,
AccessState->SecurityDescriptor,
&SecurityDescriptor,
0,
FALSE,
SecurityContext,
IoGetFileObjectGenericMapping(),
PagedPool);
@ -756,7 +756,7 @@ NpCreateNewNamedPipe(IN PNP_DCB Dcb,
Status = ObLogSecurityDescriptor(SecurityDescriptor,
&CachedSecurityDescriptor,
1);
ExFreePool(SecurityDescriptor);
ExFreePoolWithTag(SecurityDescriptor, 0);
if (!NT_SUCCESS(Status))
{

View file

@ -108,15 +108,19 @@ NpInitializeSecurity(IN PNP_CCB Ccb,
return Status;
}
ClientContext = ExAllocatePoolWithTag(PagedPool, sizeof(*ClientContext), NPFS_CLIENT_SEC_CTX_TAG);
ClientContext = ExAllocatePoolWithQuotaTag(PagedPool | POOL_QUOTA_FAIL_INSTEAD_OF_RAISE,
sizeof(*ClientContext),
NPFS_CLIENT_SEC_CTX_TAG);
Ccb->ClientContext = ClientContext;
if (!ClientContext) return STATUS_INSUFFICIENT_RESOURCES;
Status = SeCreateClientSecurity(Thread, &Ccb->ClientQos, 0, ClientContext);
if (!NT_SUCCESS(Status)) return Status;
if (!NT_SUCCESS(Status))
{
ExFreePool(Ccb->ClientContext);
Ccb->ClientContext = NULL;
}
ExFreePool(Ccb->ClientContext);
Ccb->ClientContext = NULL;
return Status;
}

View file

@ -85,7 +85,8 @@ NpCommonSetSecurityInfo(IN PDEVICE_OBJECT DeviceObject,
if (!NT_SUCCESS(Status)) return Status;
Status = ObLogSecurityDescriptor(TempSecurityDescriptor, &NewSecurityDescriptor, 1);
ExFreePool(TempSecurityDescriptor);
ASSERT(TempSecurityDescriptor != OldSecurityDescriptor);
ExFreePoolWithTag(TempSecurityDescriptor, 0);
if (!NT_SUCCESS(Status)) return Status;

View file

@ -175,17 +175,16 @@ NtfsGetDirectoryInformation(PDEVICE_EXTENSION DeviceExt,
ROUND_UP(sizeof(FILE_DIRECTORY_INFORMATION) + Length, sizeof(ULONG));
RtlCopyMemory(Info->FileName, FileName->Name, Length);
/* Convert file times */
NtfsDateTimeToFileTime(FileName->CreationTime, &Info->CreationTime);
NtfsDateTimeToFileTime(FileName->LastAccessTime, &Info->LastAccessTime);
NtfsDateTimeToFileTime(FileName->LastWriteTime, &Info->LastWriteTime);
NtfsDateTimeToFileTime(FileName->ChangeTime, &Info->ChangeTime);
Info->CreationTime.QuadPart = FileName->CreationTime;
Info->LastAccessTime.QuadPart = FileName->LastAccessTime;
Info->LastWriteTime.QuadPart = FileName->LastWriteTime;
Info->ChangeTime.QuadPart = FileName->ChangeTime;
/* Convert file flags */
NtfsFileFlagsToAttributes(FileName->FileAttributes, &Info->FileAttributes);
Info->EndOfFile.QuadPart = FileName->DataSize;
Info->AllocationSize.QuadPart = FileName->AllocatedSize;
Info->EndOfFile.QuadPart = FileName->AllocatedSize;
Info->AllocationSize.QuadPart = ROUND_UP(FileName->AllocatedSize, DeviceExt->NtfsInfo.BytesPerCluster);
// Info->FileIndex=;
@ -217,17 +216,16 @@ NtfsGetFullDirectoryInformation(PDEVICE_EXTENSION DeviceExt,
ROUND_UP(sizeof(FILE_FULL_DIRECTORY_INFORMATION) + Length, sizeof(ULONG));
RtlCopyMemory(Info->FileName, FileName->Name, Length);
/* Convert file times */
NtfsDateTimeToFileTime(FileName->CreationTime, &Info->CreationTime);
NtfsDateTimeToFileTime(FileName->LastAccessTime, &Info->LastAccessTime);
NtfsDateTimeToFileTime(FileName->LastWriteTime, &Info->LastWriteTime);
NtfsDateTimeToFileTime(FileName->ChangeTime, &Info->ChangeTime);
Info->CreationTime.QuadPart = FileName->CreationTime;
Info->LastAccessTime.QuadPart = FileName->LastAccessTime;
Info->LastWriteTime.QuadPart = FileName->LastWriteTime;
Info->ChangeTime.QuadPart = FileName->ChangeTime;
/* Convert file flags */
NtfsFileFlagsToAttributes(FileName->FileAttributes, &Info->FileAttributes);
Info->EndOfFile.QuadPart = FileName->DataSize;
Info->AllocationSize.QuadPart = FileName->AllocatedSize;
Info->EndOfFile.QuadPart = FileName->AllocatedSize;
Info->AllocationSize.QuadPart = ROUND_UP(FileName->AllocatedSize, DeviceExt->NtfsInfo.BytesPerCluster);
// Info->FileIndex=;
Info->EaSize = 0;
@ -260,17 +258,16 @@ NtfsGetBothDirectoryInformation(PDEVICE_EXTENSION DeviceExt,
ROUND_UP(sizeof(FILE_BOTH_DIR_INFORMATION) + Length, sizeof(ULONG));
RtlCopyMemory(Info->FileName, FileName->Name, Length);
/* Convert file times */
NtfsDateTimeToFileTime(FileName->CreationTime, &Info->CreationTime);
NtfsDateTimeToFileTime(FileName->LastAccessTime, &Info->LastAccessTime);
NtfsDateTimeToFileTime(FileName->LastWriteTime, &Info->LastWriteTime);
NtfsDateTimeToFileTime(FileName->ChangeTime, &Info->ChangeTime);
Info->CreationTime.QuadPart = FileName->CreationTime;
Info->LastAccessTime.QuadPart = FileName->LastAccessTime;
Info->LastWriteTime.QuadPart = FileName->LastWriteTime;
Info->ChangeTime.QuadPart = FileName->ChangeTime;
/* Convert file flags */
NtfsFileFlagsToAttributes(FileName->FileAttributes, &Info->FileAttributes);
Info->EndOfFile.QuadPart = FileName->DataSize;
Info->AllocationSize.QuadPart = FileName->AllocatedSize;
Info->EndOfFile.QuadPart = FileName->AllocatedSize;
Info->AllocationSize.QuadPart = ROUND_UP(FileName->AllocatedSize, DeviceExt->NtfsInfo.BytesPerCluster);
// Info->FileIndex=;
Info->EaSize = 0;

View file

@ -97,18 +97,6 @@ NtfsAllocateIrpContext(PDEVICE_OBJECT DeviceObject,
return IrpContext;
}
/* See:
-> http://msdn.microsoft.com/en-us/library/ms724228
-> http://bos.asmhackers.net/docs/filesystems/ntfs/standard.html#layout
*/
VOID
NtfsDateTimeToFileTime(ULONGLONG NtfsTime,
PLARGE_INTEGER SystemTime)
{
SystemTime->QuadPart = NtfsTime + 116444736000000000;
}
VOID
NtfsFileFlagsToAttributes(ULONG NtfsAttributes,
PULONG FileAttributes)

View file

@ -692,10 +692,6 @@ CdfsSwapString(PWCHAR Out,
ULONG Count);
#endif
VOID
NtfsDateTimeToFileTime(ULONGLONG NtfsTime,
PLARGE_INTEGER SystemTime);
VOID
NtfsFileFlagsToAttributes(ULONG NtfsAttributes,
PULONG FileAttributes);

View file

@ -56,7 +56,6 @@ NTSTATUS WarmSocketForBind( PAFD_FCB FCB, ULONG ShareType ) {
FCB->Recv.Window,
FCB->Recv.Size,
FCB->AddressFrom,
&FCB->ReceiveIrp.Iosb,
PacketSocketRecvComplete,
FCB);

View file

@ -286,7 +286,6 @@ MakeSocketIntoConnection(PAFD_FCB FCB) {
TDI_RECEIVE_NORMAL,
FCB->Recv.Window,
FCB->Recv.Size,
&FCB->ReceiveIrp.Iosb,
ReceiveComplete,
FCB );
@ -518,7 +517,6 @@ AfdStreamSocketConnect(PDEVICE_OBJECT DeviceObject, PIRP Irp,
FCB->Connection.Object,
FCB->ConnectCallInfo,
FCB->ConnectReturnInfo,
&FCB->ConnectIrp.Iosb,
StreamSocketConnectComplete,
FCB );
}

View file

@ -191,7 +191,6 @@ static NTSTATUS NTAPI ListenComplete( PDEVICE_OBJECT DeviceObject,
FCB->Connection.Object,
&FCB->ListenIrp.ConnectionCallInfo,
&FCB->ListenIrp.ConnectionReturnInfo,
&FCB->ListenIrp.Iosb,
ListenComplete,
FCB );
@ -268,7 +267,6 @@ NTSTATUS AfdListenSocket( PDEVICE_OBJECT DeviceObject, PIRP Irp,
FCB->Connection.Object,
&FCB->ListenIrp.ConnectionCallInfo,
&FCB->ListenIrp.ConnectionReturnInfo,
&FCB->ListenIrp.Iosb,
ListenComplete,
FCB );

View file

@ -662,7 +662,6 @@ DoDisconnect(PAFD_FCB FCB)
FCB->Connection.Object,
&FCB->DisconnectTimeout,
FCB->DisconnectFlags,
&FCB->DisconnectIrp.Iosb,
DisconnectComplete,
FCB,
FCB->ConnectCallInfo,

View file

@ -46,7 +46,6 @@ static VOID RefillSocketBuffer( PAFD_FCB FCB )
TDI_RECEIVE_NORMAL,
FCB->Recv.Window + FCB->Recv.Content,
FCB->Recv.Size - FCB->Recv.Content,
&FCB->ReceiveIrp.Iosb,
ReceiveComplete,
FCB );
}
@ -691,7 +690,6 @@ PacketSocketRecvComplete(
FCB->Recv.Window,
FCB->Recv.Size,
FCB->AddressFrom,
&FCB->ReceiveIrp.Iosb,
PacketSocketRecvComplete,
FCB );
}

View file

@ -329,7 +329,6 @@ NTSTATUS TdiConnect(
PFILE_OBJECT ConnectionObject,
PTDI_CONNECTION_INFORMATION ConnectionCallInfo,
PTDI_CONNECTION_INFORMATION ConnectionReturnInfo,
PIO_STATUS_BLOCK Iosb,
PIO_COMPLETION_ROUTINE CompletionRoutine,
PVOID CompletionContext)
/*
@ -362,7 +361,7 @@ NTSTATUS TdiConnect(
DeviceObject, /* Device object */
ConnectionObject, /* File object */
NULL, /* Event */
Iosb); /* Status */
NULL); /* Status */
if (!*Irp) {
return STATUS_INSUFFICIENT_RESOURCES;
}
@ -376,7 +375,7 @@ NTSTATUS TdiConnect(
ConnectionCallInfo, /* Request connection information */
ConnectionReturnInfo); /* Return connection information */
TdiCall(*Irp, DeviceObject, NULL, Iosb);
TdiCall(*Irp, DeviceObject, NULL, NULL);
return STATUS_PENDING;
}
@ -485,7 +484,6 @@ NTSTATUS TdiListen(
PFILE_OBJECT ConnectionObject,
PTDI_CONNECTION_INFORMATION *RequestConnectionInfo,
PTDI_CONNECTION_INFORMATION *ReturnConnectionInfo,
PIO_STATUS_BLOCK Iosb,
PIO_COMPLETION_ROUTINE CompletionRoutine,
PVOID CompletionContext)
/*
@ -519,7 +517,7 @@ NTSTATUS TdiListen(
DeviceObject, /* Device object */
ConnectionObject, /* File object */
NULL, /* Event */
Iosb); /* Status */
NULL); /* Status */
if (*Irp == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
@ -532,7 +530,7 @@ NTSTATUS TdiListen(
*RequestConnectionInfo, /* Request connection information */
*ReturnConnectionInfo); /* Return connection information */
TdiCall(*Irp, DeviceObject, NULL /* Don't wait for completion */, Iosb);
TdiCall(*Irp, DeviceObject, NULL /* Don't wait for completion */, NULL);
return STATUS_PENDING;
}
@ -892,7 +890,6 @@ NTSTATUS TdiSend(
USHORT Flags,
PCHAR Buffer,
UINT BufferLength,
PIO_STATUS_BLOCK Iosb,
PIO_COMPLETION_ROUTINE CompletionRoutine,
PVOID CompletionContext)
{
@ -916,7 +913,7 @@ NTSTATUS TdiSend(
DeviceObject, /* Device object */
TransportObject, /* File object */
NULL, /* Event */
Iosb); /* Status */
NULL); /* Status */
if (!*Irp) {
AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
@ -958,7 +955,7 @@ NTSTATUS TdiSend(
Flags, /* Flags */
BufferLength); /* Length of data */
TdiCall(*Irp, DeviceObject, NULL, Iosb);
TdiCall(*Irp, DeviceObject, NULL, NULL);
/* Does not block... The MDL is deleted in the receive completion
routine. */
@ -971,7 +968,6 @@ NTSTATUS TdiReceive(
USHORT Flags,
PCHAR Buffer,
UINT BufferLength,
PIO_STATUS_BLOCK Iosb,
PIO_COMPLETION_ROUTINE CompletionRoutine,
PVOID CompletionContext)
{
@ -995,7 +991,7 @@ NTSTATUS TdiReceive(
DeviceObject, /* Device object */
TransportObject, /* File object */
NULL, /* Event */
Iosb); /* Status */
NULL); /* Status */
if (!*Irp) {
AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
@ -1040,7 +1036,7 @@ NTSTATUS TdiReceive(
BufferLength); /* Length of data */
TdiCall(*Irp, DeviceObject, NULL, Iosb);
TdiCall(*Irp, DeviceObject, NULL, NULL);
/* Does not block... The MDL is deleted in the receive completion
routine. */
@ -1055,7 +1051,6 @@ NTSTATUS TdiReceiveDatagram(
PCHAR Buffer,
UINT BufferLength,
PTDI_CONNECTION_INFORMATION Addr,
PIO_STATUS_BLOCK Iosb,
PIO_COMPLETION_ROUTINE CompletionRoutine,
PVOID CompletionContext)
/*
@ -1090,7 +1085,7 @@ NTSTATUS TdiReceiveDatagram(
DeviceObject, /* Device object */
TransportObject, /* File object */
NULL, /* Event */
Iosb); /* Status */
NULL); /* Status */
if (!*Irp) {
AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
@ -1134,7 +1129,7 @@ NTSTATUS TdiReceiveDatagram(
Addr,
Flags); /* Length of data */
TdiCall(*Irp, DeviceObject, NULL, Iosb);
TdiCall(*Irp, DeviceObject, NULL, NULL);
/* Does not block... The MDL is deleted in the receive completion
routine. */
@ -1148,7 +1143,6 @@ NTSTATUS TdiSendDatagram(
PCHAR Buffer,
UINT BufferLength,
PTDI_CONNECTION_INFORMATION Addr,
PIO_STATUS_BLOCK Iosb,
PIO_COMPLETION_ROUTINE CompletionRoutine,
PVOID CompletionContext)
/*
@ -1185,7 +1179,7 @@ NTSTATUS TdiSendDatagram(
DeviceObject, /* Device object */
TransportObject, /* File object */
NULL, /* Event */
Iosb); /* Status */
NULL); /* Status */
if (!*Irp) {
AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
@ -1228,7 +1222,7 @@ NTSTATUS TdiSendDatagram(
BufferLength, /* Bytes to send */
Addr); /* Address */
TdiCall(*Irp, DeviceObject, NULL, Iosb);
TdiCall(*Irp, DeviceObject, NULL, NULL);
/* Does not block... The MDL is deleted in the send completion
routine. */
@ -1240,7 +1234,6 @@ NTSTATUS TdiDisconnect(
PFILE_OBJECT TransportObject,
PLARGE_INTEGER Time,
USHORT Flags,
PIO_STATUS_BLOCK Iosb,
PIO_COMPLETION_ROUTINE CompletionRoutine,
PVOID CompletionContext,
PTDI_CONNECTION_INFORMATION RequestConnectionInfo,
@ -1264,7 +1257,7 @@ NTSTATUS TdiDisconnect(
DeviceObject, /* Device object */
TransportObject, /* File object */
NULL, /* Event */
Iosb); /* Status */
NULL); /* Status */
if (!*Irp) {
AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
@ -1281,7 +1274,7 @@ NTSTATUS TdiDisconnect(
RequestConnectionInfo, /* Indication of who to disconnect */
ReturnConnectionInfo); /* Indication of who disconnected */
TdiCall(*Irp, DeviceObject, NULL, Iosb);
TdiCall(*Irp, DeviceObject, NULL, NULL);
return STATUS_PENDING;
}

View file

@ -243,7 +243,6 @@ static NTSTATUS NTAPI SendComplete
0,
FCB->Send.Window,
FCB->Send.BytesUsed,
&FCB->SendIrp.Iosb,
SendComplete,
FCB );
}
@ -385,7 +384,6 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
SendReq->BufferArray[0].buf,
SendReq->BufferArray[0].len,
TargetAddress,
&FCB->SendIrp.Iosb,
PacketSocketSendComplete,
FCB);
}
@ -549,7 +547,6 @@ AfdConnectedSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
0,
FCB->Send.Window,
FCB->Send.BytesUsed,
&FCB->SendIrp.Iosb,
SendComplete,
FCB);
}
@ -645,7 +642,6 @@ AfdPacketSocketWriteData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
SendReq->BufferArray[0].buf,
SendReq->BufferArray[0].len,
TargetAddress,
&FCB->SendIrp.Iosb,
PacketSocketSendComplete,
FCB);
}

View file

@ -152,7 +152,6 @@ typedef struct _AFD_TDI_OBJECT_QELT {
typedef struct _AFD_IN_FLIGHT_REQUEST {
PIRP InFlightRequest;
IO_STATUS_BLOCK Iosb;
PTDI_CONNECTION_INFORMATION ConnectionCallInfo;
PTDI_CONNECTION_INFORMATION ConnectionReturnInfo;
} AFD_IN_FLIGHT_REQUEST, *PAFD_IN_FLIGHT_REQUEST;
@ -369,7 +368,6 @@ NTSTATUS TdiListen
PFILE_OBJECT ConnectionObject,
PTDI_CONNECTION_INFORMATION *RequestConnectionInfo,
PTDI_CONNECTION_INFORMATION *ReturnConnectionInfo,
PIO_STATUS_BLOCK Iosb,
PIO_COMPLETION_ROUTINE CompletionRoutine,
PVOID CompletionContext);
@ -379,7 +377,6 @@ NTSTATUS TdiReceive
USHORT Flags,
PCHAR Buffer,
UINT BufferLength,
PIO_STATUS_BLOCK Iosb,
PIO_COMPLETION_ROUTINE CompletionRoutine,
PVOID CompletionContext);
@ -389,7 +386,6 @@ NTSTATUS TdiSend
USHORT Flags,
PCHAR Buffer,
UINT BufferLength,
PIO_STATUS_BLOCK Iosb,
PIO_COMPLETION_ROUTINE CompletionRoutine,
PVOID CompletionContext);
@ -400,7 +396,6 @@ NTSTATUS TdiReceiveDatagram(
PCHAR Buffer,
UINT BufferLength,
PTDI_CONNECTION_INFORMATION From,
PIO_STATUS_BLOCK Iosb,
PIO_COMPLETION_ROUTINE CompletionRoutine,
PVOID CompletionContext);
@ -410,7 +405,6 @@ NTSTATUS TdiSendDatagram(
PCHAR Buffer,
UINT BufferLength,
PTDI_CONNECTION_INFORMATION To,
PIO_STATUS_BLOCK Iosb,
PIO_COMPLETION_ROUTINE CompletionRoutine,
PVOID CompletionContext);

View file

@ -4,7 +4,6 @@ NTSTATUS TdiConnect( PIRP *PendingIrp,
PFILE_OBJECT ConnectionObject,
PTDI_CONNECTION_INFORMATION ConnectionCallInfo,
PTDI_CONNECTION_INFORMATION ConnectionReturnInfo,
PIO_STATUS_BLOCK Iosb,
PIO_COMPLETION_ROUTINE CompletionRoutine,
PVOID CompletionContext );
@ -20,7 +19,6 @@ NTSTATUS TdiDisconnect
PFILE_OBJECT TransportObject,
PLARGE_INTEGER Time,
USHORT Flags,
PIO_STATUS_BLOCK Iosb,
PIO_COMPLETION_ROUTINE CompletionRoutine,
PVOID CompletionContext,
PTDI_CONNECTION_INFORMATION RequestConnectionInfo,

View file

@ -1692,7 +1692,7 @@ IssueIdentify(
deviceExtension->FullIdentifyData.NVCache_Version
));
KdPrint2((PRINT_PREFIX "R-rate %#x\n",
KdPrint2((PRINT_PREFIX "R-rate %d\n",
deviceExtension->FullIdentifyData.NominalMediaRotationRate
));
@ -5071,9 +5071,9 @@ continue_err:
if(AtaReq->retry < MAX_RETRIES) {
//fallback_pio:
if(!(deviceExtension->HwFlags & UNIATA_AHCI)) {
AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
//AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
// Downrate will happen in AtapiDmaReinit(), try UDMA-2 for HDD only
AtaReq->Flags |= REQ_FLAG_FORCE_DOWNRATE;
// LunExt->DeviceFlags |= DFLAGS_FORCE_DOWNRATE;
}
AtaReq->ReqState = REQ_STATE_QUEUED;
goto reenqueue_req;
@ -5093,6 +5093,7 @@ continue_err:
((error >> 4) == SCSI_SENSE_HARDWARE_ERROR)) {
if(AtaReq->retry < MAX_RETRIES) {
//fallback_pio:
// Downrate will happen in AtapiDmaReinit(), use PIO immediately for ATAPI
AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
AtaReq->Flags |= REQ_FLAG_FORCE_DOWNRATE;
// LunExt->DeviceFlags |= DFLAGS_FORCE_DOWNRATE;
@ -5449,6 +5450,7 @@ IntrPrepareResetController:
chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION;
goto CompleteRequest;
}
continue_read_drq:
// Ensure that this is a read command.
if (srb->SrbFlags & SRB_FLAGS_DATA_IN) {
@ -5489,7 +5491,6 @@ IntrPrepareResetController:
}
}
}
} else {
KdPrint2((PRINT_PREFIX
"IdeIntr: Read %#x Dwords\n", wordCount/2));
@ -5581,6 +5582,12 @@ IntrPrepareResetController:
status = SRB_STATUS_SUCCESS;
goto CompleteRequest;
}
} else {
if(!atapiDev && !DataOverrun && (srb->SrbFlags & SRB_FLAGS_DATA_IN) &&
(statusByte == (IDE_STATUS_IDLE | IDE_STATUS_DRQ))) {
KdPrint2((PRINT_PREFIX " HDD read data ready \n"));
goto continue_read_drq;
}
}
}
@ -6689,6 +6696,7 @@ IdeReadWrite(
// Adjust buffer address and words left count.
AtaReq->WordsLeft -= wordCount;
AtaReq->DataBuffer += wordCount;
AtaReq->WordsTransfered += wordCount;
// Wait for interrupt.
return SRB_STATUS_PENDING;

View file

@ -587,10 +587,8 @@ AtapiDmaStart(
case ATA_PROMISE_ID:
if(ChipType == PRNEW) {
ULONG Channel = deviceExtension->Channel + lChannel;
if(chan->ChannelCtrlFlags & CTRFLAGS_LBA48) {
AtapiWritePortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11,
AtapiReadPortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11) |
(Channel ? 0x08 : 0x02));
AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),(Channel ? 0x24 : 0x20),
((Srb->SrbFlags & SRB_FLAGS_DATA_IN) ? 0x05000000 : 0x06000000) | (Srb->DataTransferLength >> 1)
);
@ -659,10 +657,12 @@ AtapiDmaDone(
case ATA_PROMISE_ID:
if(ChipType == PRNEW) {
ULONG Channel = deviceExtension->Channel + lChannel;
/*
AtapiWritePortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11,
AtapiReadPortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11) &
~(Channel ? 0x08 : 0x02));
*/
if(chan->ChannelCtrlFlags & CTRFLAGS_LBA48) {
AtapiWritePortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11,
AtapiReadPortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11) &
~(Channel ? 0x08 : 0x02));
AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),(Channel ? 0x24 : 0x20),
0
);
@ -1555,10 +1555,13 @@ set_new_acard:
return;
break; }
case ATA_PROMISE_ID:
case ATA_PROMISE_ID: {
/***********/
/* Promise */
/***********/
UCHAR sel66 = Channel ? 0x08: 0x02;
if(ChipType < PRTX) {
if (isAtapi) {
udmamode =
@ -1566,12 +1569,29 @@ set_new_acard:
}
}
for(i=udmamode; i>=0; i--) {
if(ChipType == PRNEW) {
if(i>2) {
AtapiWritePortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11,
AtapiReadPortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11) |
sel66);
} else {
AtapiWritePortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11,
AtapiReadPortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11) &
~sel66);
}
}
if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_UDMA0 + i)) {
promise_timing(deviceExtension, dev, (UCHAR)(ATA_UDMA + i)); // ???
return;
}
}
if(ChipType == PRNEW) {
AtapiWritePortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11,
AtapiReadPortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x11) &
~sel66);
}
for(i=wdmamode; i>=0; i--) {
if(AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_WDMA0 + i)) {
promise_timing(deviceExtension, dev, (UCHAR)(ATA_WDMA0+i));
@ -1587,7 +1607,7 @@ set_new_acard:
AtaSetTransferMode(deviceExtension, DeviceNumber, lChannel, LunExt, ATA_PIO0 + apiomode);
promise_timing(deviceExtension, dev, ATA_PIO0 + apiomode);
return;
break;
break; }
case ATA_ATI_ID:
KdPrint2((PRINT_PREFIX "ATI\n"));

View file

@ -968,6 +968,12 @@ UniataAhciDetect(
KdPrint2((PRINT_PREFIX "\n"));
/* get the number of HW channels */
/* CAP.NOP sometimes indicate the index of the last enabled
* port, at other times, that of the last possible port, so
* determining the maximum port number requires looking at
* both CAP.NOP and PI.
*/
PI = UniataAhciReadHostPort4(deviceExtension, IDX_AHCI_PI);
deviceExtension->AHCI_PI = PI;
KdPrint2((PRINT_PREFIX " AHCI PI %#x\n", PI));

View file

@ -1,10 +1,10 @@
#define UNIATA_VER_STR "45a8"
#define UNIATA_VER_DOT 0.45.1.8
#define UNIATA_VER_STR "45b1"
#define UNIATA_VER_DOT 0.45.2.1
#define UNIATA_VER_MJ 0
#define UNIATA_VER_MN 45
#define UNIATA_VER_SUB_MJ 1
#define UNIATA_VER_SUB_MN 8
#define UNIATA_VER_DOT_COMMA 0,45,1,8
#define UNIATA_VER_DOT_STR "0.45.1.8"
#define UNIATA_VER_SUB_MJ 2
#define UNIATA_VER_SUB_MN 1
#define UNIATA_VER_DOT_COMMA 0,45,2,1
#define UNIATA_VER_DOT_STR "0.45.2.1"
#define UNIATA_VER_YEAR 2014
#define UNIATA_VER_YEAR_STR "2014"

View file

@ -1374,6 +1374,22 @@ Language=English
DRIVER_LEFT_LOCKED_PAGES_IN_PROCESS
.
MessageId=0xCC
Severity=Success
Facility=System
SymbolicName=PAGE_FAULT_IN_FREED_SPECIAL_POOL
Language=English
PAGE_FAULT_IN_FREED_SPECIAL_POOL
.
MessageId=0xCD
Severity=Success
Facility=System
SymbolicName=PAGE_FAULT_BEYOND_END_OF_ALLOCATION
Language=English
PAGE_FAULT_BEYOND_END_OF_ALLOCATION
.
MessageId=0xCE
Severity=Success
Facility=System
@ -1406,6 +1422,22 @@ Language=English
The driver mistakenly marked a part of its image pageable instead of non-pageable.
.
MessageId=0xD5
Severity=Success
Facility=System
SymbolicName=DRIVER_PAGE_FAULT_IN_FREED_SPECIAL_POOL
Language=English
DRIVER_PAGE_FAULT_IN_FREED_SPECIAL_POOL
.
MessageId=0xD6
Severity=Success
Facility=System
SymbolicName=DRIVER_PAGE_FAULT_BEYOND_END_OF_ALLOCATION
Language=English
DRIVER_PAGE_FAULT_BEYOND_END_OF_ALLOCATION
.
MessageId=0xD7
Severity=Success
Facility=System

View file

@ -21,8 +21,6 @@
#include "strmbase_private.h"
static const IPinVtbl InputPin_Vtbl;
static const IPinVtbl OutputPin_Vtbl;
static const IMemInputPinVtbl MemInputPin_Vtbl;
typedef HRESULT (*SendPinFunc)( IPin *to, LPVOID arg );
@ -545,28 +543,6 @@ HRESULT WINAPI BaseOutputPinImpl_EndFlush(IPin * iface)
return E_UNEXPECTED;
}
static const IPinVtbl OutputPin_Vtbl =
{
BaseOutputPinImpl_QueryInterface,
BasePinImpl_AddRef,
BaseOutputPinImpl_Release,
BaseOutputPinImpl_Connect,
BaseOutputPinImpl_ReceiveConnection,
BaseOutputPinImpl_Disconnect,
BasePinImpl_ConnectedTo,
BasePinImpl_ConnectionMediaType,
BasePinImpl_QueryPinInfo,
BasePinImpl_QueryDirection,
BasePinImpl_QueryId,
BasePinImpl_QueryAccept,
BasePinImpl_EnumMediaTypes,
BasePinImpl_QueryInternalConnections,
BaseOutputPinImpl_EndOfStream,
BaseOutputPinImpl_BeginFlush,
BaseOutputPinImpl_EndFlush,
BasePinImpl_NewSegment
};
HRESULT WINAPI BaseOutputPinImpl_GetDeliveryBuffer(BaseOutputPin *This, IMediaSample ** ppSample, REFERENCE_TIME * tStart, REFERENCE_TIME * tStop, DWORD dwFlags)
{
HRESULT hr;
@ -851,11 +827,6 @@ static inline BaseInputPin *impl_BaseInputPin_from_IPin( IPin *iface )
return CONTAINING_RECORD(iface, BaseInputPin, pin.IPin_iface);
}
static inline BaseInputPin *impl_BaseInputPin_from_BasePin( BasePin *iface )
{
return CONTAINING_RECORD(iface, BaseInputPin, pin);
}
HRESULT WINAPI BaseInputPinImpl_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv)
{
BaseInputPin *This = impl_BaseInputPin_from_IPin(iface);
@ -1050,28 +1021,6 @@ HRESULT WINAPI BaseInputPinImpl_NewSegment(IPin * iface, REFERENCE_TIME tStart,
return SendFurther( iface, deliver_newsegment, &args, NULL );
}
static const IPinVtbl InputPin_Vtbl =
{
BaseInputPinImpl_QueryInterface,
BasePinImpl_AddRef,
BaseInputPinImpl_Release,
BaseInputPinImpl_Connect,
BaseInputPinImpl_ReceiveConnection,
BasePinImpl_Disconnect,
BasePinImpl_ConnectedTo,
BasePinImpl_ConnectionMediaType,
BasePinImpl_QueryPinInfo,
BasePinImpl_QueryDirection,
BasePinImpl_QueryId,
BaseInputPinImpl_QueryAccept,
BasePinImpl_EnumMediaTypes,
BasePinImpl_QueryInternalConnections,
BaseInputPinImpl_EndOfStream,
BaseInputPinImpl_BeginFlush,
BaseInputPinImpl_EndFlush,
BaseInputPinImpl_NewSegment
};
/*** IMemInputPin implementation ***/
static inline BaseInputPin *impl_from_IMemInputPin( IMemInputPin *iface )

View file

@ -24,7 +24,6 @@
static const WCHAR wcsInputPinName[] = {'i','n','p','u','t',' ','p','i','n',0};
static const WCHAR wcsOutputPinName[] = {'o','u','t','p','u','t',' ','p','i','n',0};
static const IBaseFilterVtbl TransformFilter_Vtbl;
static const IPinVtbl TransformFilter_InputPin_Vtbl;
static const IPinVtbl TransformFilter_OutputPin_Vtbl;
static const IQualityControlVtbl TransformFilter_QualityControl_Vtbl;
@ -421,25 +420,6 @@ HRESULT WINAPI TransformFilterImpl_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin
return E_NOTIMPL;
}
static const IBaseFilterVtbl TransformFilter_Vtbl =
{
TransformFilterImpl_QueryInterface,
BaseFilterImpl_AddRef,
TransformFilterImpl_Release,
BaseFilterImpl_GetClassID,
TransformFilterImpl_Stop,
TransformFilterImpl_Pause,
TransformFilterImpl_Run,
BaseFilterImpl_GetState,
BaseFilterImpl_SetSyncSource,
BaseFilterImpl_GetSyncSource,
BaseFilterImpl_EnumPins,
TransformFilterImpl_FindPin,
BaseFilterImpl_QueryFilterInfo,
BaseFilterImpl_JoinFilterGraph,
BaseFilterImpl_QueryVendorInfo
};
static HRESULT WINAPI TransformFilter_InputPin_EndOfStream(IPin * iface)
{
BaseInputPin* This = impl_BaseInputPin_from_IPin(iface);

View file

@ -16,20 +16,6 @@
#include "rosip.h"
static const char * const tcp_state_str[] = {
"CLOSED",
"LISTEN",
"SYN_SENT",
"SYN_RCVD",
"ESTABLISHED",
"FIN_WAIT_1",
"FIN_WAIT_2",
"CLOSE_WAIT",
"CLOSING",
"LAST_ACK",
"TIME_WAIT"
};
extern NPAGED_LOOKASIDE_LIST TdiBucketLookasideList;
static

View file

@ -1644,7 +1644,7 @@ MMixerSetupFilter(
IN LPMIXER_DATA MixerData,
IN PULONG DeviceCount)
{
MIXER_STATUS Status;
MIXER_STATUS Status = MM_STATUS_SUCCESS;
PTOPOLOGY Topology;
ULONG NodeIndex;
LPMIXER_INFO MixerInfo = NULL;

View file

@ -72,7 +72,7 @@ MMixerAddMidiPin(
MidiInfo->PinId = PinId;
/* sanity check */
ASSERT(wcslen(DeviceName) + 1 < MAXPNAMELEN);
ASSERT(!DeviceName || (wcslen(DeviceName) + 1 < MAXPNAMELEN));
/* copy device name */
if (bInput && DeviceName)

View file

@ -328,7 +328,7 @@ MMixerGetLineControls(
if (MixerLineControls->cbmxctrl != sizeof(MIXERCONTROLW))
{
DPRINT1("Invalid MixerLineControls cbmxctrl passed %lu expected %lu\n", MixerLineControls->cbStruct, sizeof(MIXERLINECONTROLSW));
DPRINT1("Invalid MixerLineControls cbmxctrl passed %lu expected %lu\n", MixerLineControls->cbmxctrl, sizeof(MIXERCONTROLW));
/* invalid parameter */
return MM_STATUS_INVALID_PARAMETER;
}

View file

@ -55,7 +55,7 @@ Fast486ReadMemory(PFAST486_STATE State,
}
/* Check for protected mode */
if (State->ControlRegisters[0] & FAST486_CR0_PE)
if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)
{
/* Privilege checks */
@ -122,7 +122,7 @@ Fast486WriteMemory(PFAST486_STATE State,
}
/* Check for protected mode */
if (State->ControlRegisters[0] & FAST486_CR0_PE)
if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)
{
/* Privilege checks */

View file

@ -762,7 +762,7 @@ Fast486ParseModRegRm(PFAST486_STATE State,
ModRegRm->Register = (ModRmByte >> 3) & 0x07;
/* Check the mode */
if ((ModRmByte >> 6) == 3)
if (Mode == 3)
{
/* The second operand is also a register */
ModRegRm->Memory = FALSE;
@ -886,7 +886,6 @@ Fast486ParseModRegRm(PFAST486_STATE State,
/* [BX + SI] */
ModRegRm->MemoryAddress = State->GeneralRegs[FAST486_REG_EBX].LowWord
+ State->GeneralRegs[FAST486_REG_ESI].LowWord;
break;
}
@ -895,7 +894,6 @@ Fast486ParseModRegRm(PFAST486_STATE State,
/* [BX + DI] */
ModRegRm->MemoryAddress = State->GeneralRegs[FAST486_REG_EBX].LowWord
+ State->GeneralRegs[FAST486_REG_EDI].LowWord;
break;
}
@ -904,7 +902,6 @@ Fast486ParseModRegRm(PFAST486_STATE State,
/* SS:[BP + SI] */
ModRegRm->MemoryAddress = State->GeneralRegs[FAST486_REG_EBP].LowWord
+ State->GeneralRegs[FAST486_REG_ESI].LowWord;
break;
}
@ -913,7 +910,6 @@ Fast486ParseModRegRm(PFAST486_STATE State,
/* SS:[BP + DI] */
ModRegRm->MemoryAddress = State->GeneralRegs[FAST486_REG_EBP].LowWord
+ State->GeneralRegs[FAST486_REG_EDI].LowWord;
break;
}
@ -921,7 +917,6 @@ Fast486ParseModRegRm(PFAST486_STATE State,
{
/* [SI] */
ModRegRm->MemoryAddress = State->GeneralRegs[FAST486_REG_ESI].LowWord;
break;
}
@ -929,7 +924,6 @@ Fast486ParseModRegRm(PFAST486_STATE State,
{
/* [DI] */
ModRegRm->MemoryAddress = State->GeneralRegs[FAST486_REG_EDI].LowWord;
break;
}
@ -953,7 +947,6 @@ Fast486ParseModRegRm(PFAST486_STATE State,
{
/* [BX] */
ModRegRm->MemoryAddress = State->GeneralRegs[FAST486_REG_EBX].LowWord;
break;
}
}

View file

@ -137,7 +137,7 @@ Fast486DumpState(PFAST486_STATE State)
{
DbgPrint("\nFast486DumpState -->\n");
DbgPrint("\nCPU currently executing in %s mode at %04X:%08X\n",
(State->ControlRegisters[0] & FAST486_CR0_PE) ? "protected" : "real",
(State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE) ? "protected" : "real",
State->SegmentRegs[FAST486_REG_CS].Selector,
State->InstPtr.Long);
DbgPrint("\nGeneral purpose registers:\n"

View file

@ -37,8 +37,8 @@
FAST486_OPCODE_HANDLER_PROC
Fast486ExtendedHandlers[FAST486_NUM_OPCODE_HANDLERS] =
{
Fast486OpcodeGroup0F00, /* 0x00 - 0x01 */
Fast486OpcodeGroup0F01,
Fast486ExtOpcodeGroup0F00, /* 0x00 - 0x01 */
Fast486ExtOpcodeGroup0F01,
Fast486ExtOpcodeLar, /* 0x02 */
Fast486ExtOpcodeLsl, /* 0x03 */
Fast486ExtOpcodeInvalid, /* 0x04 - 0x05 */ // Invalid
@ -222,8 +222,8 @@ Fast486ExtendedHandlers[FAST486_NUM_OPCODE_HANDLERS] =
Fast486ExtOpcodeMovzxByte, /* 0xB6 - 0xB7 */
Fast486ExtOpcodeMovzxWord,
Fast486ExtOpcodeInvalid, /* 0xB8 */ // Invalid
Fast486OpcodeGroup0FB9, /* 0xB9 */
Fast486OpcodeGroup0FBA, /* 0xBA */
Fast486ExtOpcodeGroup0FB9, /* 0xB9 */
Fast486ExtOpcodeGroup0FBA, /* 0xBA */
Fast486ExtOpcodeBtc, /* 0xBB */
Fast486ExtOpcodeBsf, /* 0xBC */
Fast486ExtOpcodeBsr, /* 0xBD */

View file

@ -54,9 +54,9 @@ Fast486ExecutionControl(PFAST486_STATE State, FAST486_EXEC_CMD Command)
/* Main execution loop */
do
{
NextInst:
if (!State->Halted)
{
NextInst:
/* Check if this is a new instruction */
if (State->PrefixFlags == 0) State->SavedInstPtr = State->InstPtr;

View file

@ -4985,8 +4985,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeLoop)
/* Additional rule for LOOPNZ */
if (State->Flags.Zf) Condition = FALSE;
}
if (Opcode == 0xE1)
else if (Opcode == 0xE1)
{
/* Additional rule for LOOPZ */
if (!State->Flags.Zf) Condition = FALSE;

View file

@ -1703,7 +1703,8 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeGroupFF)
return TRUE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0F00)
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeGroup0F00)
{
FAST486_MOD_REG_RM ModRegRm;
BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
@ -2014,7 +2015,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0F00)
}
}
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0F01)
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeGroup0F01)
{
// FAST486_TABLE_REG TableReg;
UCHAR TableReg[6];
@ -2230,7 +2231,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0F01)
}
}
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0FB9)
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeGroup0FB9)
{
FAST486_MOD_REG_RM ModRegRm;
BOOLEAN AddressSize = State->SegmentRegs[FAST486_REG_CS].Size;
@ -2248,7 +2249,7 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0FB9)
return FALSE;
}
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0FBA)
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeGroup0FBA)
{
FAST486_MOD_REG_RM ModRegRm;
BOOLEAN OperandSize, AddressSize;

View file

@ -42,10 +42,11 @@ FAST486_OPCODE_HANDLER(Fast486OpcodeGroupF6);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupF7);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupFE);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroupFF);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0F00);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0F01);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0FB9);
FAST486_OPCODE_HANDLER(Fast486OpcodeGroup0FBA);
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeGroup0F00);
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeGroup0F01);
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeGroup0FB9);
FAST486_OPCODE_HANDLER(Fast486ExtOpcodeGroup0FBA);
#endif // _OPGROUPS_H_

View file

@ -362,8 +362,11 @@ RtlClearBits(
/* Clear what's left */
NumberToClear &= (_BITCOUNT - 1);
Mask = MAXINDEX << NumberToClear;
*Buffer &= Mask;
if (NumberToClear)
{
Mask = MAXINDEX << NumberToClear;
*Buffer &= Mask;
}
}
VOID
@ -419,8 +422,11 @@ RtlSetBits(
/* Set what's left */
NumberToSet &= (_BITCOUNT - 1);
Mask = MAXINDEX << NumberToSet;
*Buffer |= ~Mask;
if (NumberToSet)
{
Mask = MAXINDEX << NumberToSet;
*Buffer |= ~Mask;
}
}
BOOLEAN

View file

@ -269,10 +269,10 @@ kernel32 -
reactos/dll/win32/kernel32/wine/lzexpand.c # Synced in r52754
reactos/dll/win32/kernel32/wine/profile.c # Synced in r52754
reactos/dll/win32/kernel32/wine/res.c # Synced in r52754
reactos/dll/win32/kernel32/winnls/string/casemap.c # Synced in r52754
reactos/dll/win32/kernel32/winnls/string/casemap.c # Synced to Wine-1.7.27
reactos/dll/win32/kernel32/winnls/string/chartype.c # Synced in r52754
reactos/dll/win32/kernel32/winnls/string/collation.c # Synced in r52754
reactos/dll/win32/kernel32/winnls/string/format_msg.c # Synced to Wine-1.5.4
reactos/dll/win32/kernel32/winnls/string/format_msg.c # Synced to Wine-1.7.27
reactos/dll/win32/kernel32/winnls/string/lang.c # Synced in r52754
reactos/dll/win32/kernel32/winnls/string/lcformat.c # Synced in r52754
reactos/dll/win32/kernel32/winnls/string/nls.c # Synced in r52754

View file

@ -719,7 +719,7 @@ MmPageFault(
VOID
NTAPI
MiInitializeSpecialPool();
MiInitializeSpecialPool(VOID);
BOOLEAN
NTAPI
@ -732,6 +732,11 @@ NTAPI
MmIsSpecialPoolAddress(
IN PVOID P);
BOOLEAN
NTAPI
MmIsSpecialPoolAddressFree(
IN PVOID P);
PVOID
NTAPI
MmAllocateSpecialPool(

View file

@ -975,15 +975,31 @@ KeBugCheckWithTf(IN ULONG BugCheckCode,
FALSE,
&IsSystem);
}
else
{
/* Can't blame a driver, assume system */
IsSystem = TRUE;
}
/*
* Now we should check if this happened in:
* 1) Special Pool 2) Free Special Pool 3) Session Pool
* and update the bugcheck code appropriately.
*/
/* FIXME: Check for session pool in addition to special pool */
/* Check if we didn't have a driver base */
if (!DriverBase)
/* Special pool has its own bug check codes */
if (MmIsSpecialPoolAddress((PVOID)BugCheckParameter1))
{
if (MmIsSpecialPoolAddressFree((PVOID)BugCheckParameter1))
{
KiBugCheckData[0] = IsSystem
? PAGE_FAULT_IN_FREED_SPECIAL_POOL
: DRIVER_PAGE_FAULT_IN_FREED_SPECIAL_POOL;
}
else
{
KiBugCheckData[0] = IsSystem
? PAGE_FAULT_BEYOND_END_OF_ALLOCATION
: DRIVER_PAGE_FAULT_BEYOND_END_OF_ALLOCATION;
}
}
else if (!DriverBase)
{
/* Find the driver that unloaded at this address */
KiBugCheckDriver = NULL; // FIXME: ROS can't locate

View file

@ -932,7 +932,7 @@ InitializePool(IN POOL_TYPE PoolType,
}
//
// Finally, add one entry, compute the hash, and zero the table
// Add one entry, compute the hash, and zero the table
//
PoolTrackTableSize++;
PoolTrackTableMask = PoolTrackTableSize - 2;
@ -940,6 +940,11 @@ InitializePool(IN POOL_TYPE PoolType,
RtlZeroMemory(PoolTrackTable,
PoolTrackTableSize * sizeof(POOL_TRACKER_TABLE));
//
// Finally, add the most used tags to speed up those allocations
//
ExpSeedHotTags();
//
// We now do the exact same thing with the tracker table for big pages
//
@ -2041,10 +2046,25 @@ NTAPI
ExAllocatePool(POOL_TYPE PoolType,
SIZE_T NumberOfBytes)
{
//
// Use a default tag of "None"
//
return ExAllocatePoolWithTag(PoolType, NumberOfBytes, TAG_NONE);
ULONG Tag = TAG_NONE;
#if 0 && DBG
PLDR_DATA_TABLE_ENTRY LdrEntry;
/* Use the first four letters of the driver name, or "None" if unavailable */
LdrEntry = KeGetCurrentIrql() <= APC_LEVEL
? MiLookupDataTableEntry(_ReturnAddress())
: NULL;
if (LdrEntry)
{
ULONG i;
Tag = 0;
for (i = 0; i < min(4, LdrEntry->BaseDllName.Length / sizeof(WCHAR)); i++)
Tag = Tag >> 8 | (LdrEntry->BaseDllName.Buffer[i] & 0xff) << 24;
for (; i < 4; i++)
Tag = Tag >> 8 | ' ' << 24;
}
#endif
return ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag);
}
/*
@ -2508,7 +2528,7 @@ ExAllocatePoolWithQuota(IN POOL_TYPE PoolType,
//
// Allocate the pool
//
return ExAllocatePoolWithQuotaTag(PoolType, NumberOfBytes, 'enoN');
return ExAllocatePoolWithQuotaTag(PoolType, NumberOfBytes, TAG_NONE);
}
/*

View file

@ -935,15 +935,15 @@ MiResolveTransitionFault(IN PVOID FaultingAddress,
/* See if we should wait before terminating the fault */
if (Pfn1->u3.e1.ReadInProgress == 1)
{
DPRINT1("The page is currently being read!\n");
ASSERT(Pfn1->u1.Event != NULL);
*InPageBlock = Pfn1->u1.Event;
if (PointerPte == Pfn1->PteAddress)
{
DPRINT1("And this if for this particular PTE.\n");
/* The PTE will be made valid by the thread serving the fault */
return STATUS_SUCCESS; // FIXME: Maybe something more descriptive
}
DPRINT1("The page is currently being read!\n");
ASSERT(Pfn1->u1.Event != NULL);
*InPageBlock = Pfn1->u1.Event;
if (PointerPte == Pfn1->PteAddress)
{
DPRINT1("And this if for this particular PTE.\n");
/* The PTE will be made valid by the thread serving the fault */
return STATUS_SUCCESS; // FIXME: Maybe something more descriptive
}
}
/* Windows checks there's some free pages and this isn't an in-page error */
@ -1424,8 +1424,8 @@ MiDispatchFault(IN BOOLEAN StoreInstruction,
if (InPageBlock != NULL)
{
/* The page is being paged in by another process */
KeWaitForSingleObject(InPageBlock, WrPageIn, KernelMode, FALSE, NULL);
/* The page is being paged in by another process */
KeWaitForSingleObject(InPageBlock, WrPageIn, KernelMode, FALSE, NULL);
}
ASSERT(OldIrql == KeGetCurrentIrql());
@ -1833,6 +1833,17 @@ _WARN("Session space stuff is not implemented yet!")
(ULONG_PTR)TrapInformation,
1);
}
/* Check for no protecton at all */
if (TempPte.u.Soft.Protection == MM_ZERO_ACCESS)
{
/* Bugcheck the system! */
KeBugCheckEx(PAGE_FAULT_IN_NONPAGED_AREA,
(ULONG_PTR)Address,
StoreInstruction,
(ULONG_PTR)TrapInformation,
0);
}
}
/* Check for demand page */

View file

@ -20,6 +20,7 @@
#define MODULE_INVOLVED_IN_ARM3
#include "../ARM3/miarm.h"
extern ULONG ExpPoolFlags;
extern PMMPTE MmSystemPteBase;
PMMPTE
@ -73,22 +74,40 @@ MmUseSpecialPool(SIZE_T NumberOfBytes, ULONG Tag)
if (NumberOfBytes > (PAGE_SIZE - sizeof(POOL_HEADER)))
return FALSE;
// FIXME
//return TRUE;
return FALSE;
return Tag == MmSpecialPoolTag;
}
BOOLEAN
NTAPI
MmIsSpecialPoolAddress(PVOID P)
{
return((P >= MmSpecialPoolStart) &&
(P <= MmSpecialPoolEnd));
return ((P >= MmSpecialPoolStart) &&
(P <= MmSpecialPoolEnd));
}
BOOLEAN
NTAPI
MmIsSpecialPoolAddressFree(PVOID P)
{
PMMPTE PointerPte;
ASSERT(MmIsSpecialPoolAddress(P));
PointerPte = MiAddressToPte(P);
if (PointerPte->u.Soft.PageFileHigh == SPECIAL_POOL_PAGED_PTE ||
PointerPte->u.Soft.PageFileHigh == SPECIAL_POOL_NONPAGED_PTE)
{
/* Guard page PTE */
return FALSE;
}
/* Free PTE */
return TRUE;
}
VOID
NTAPI
MiInitializeSpecialPool()
MiInitializeSpecialPool(VOID)
{
ULONG SpecialPoolPtes, i;
PMMPTE PointerPte;
@ -98,7 +117,7 @@ MiInitializeSpecialPool()
(MmSpecialPoolTag == -1)) return;
/* Calculate number of system PTEs for the special pool */
if ( MmNumberOfSystemPtes >= 0x3000 )
if (MmNumberOfSystemPtes >= 0x3000)
SpecialPoolPtes = MmNumberOfSystemPtes / 3;
else
SpecialPoolPtes = MmNumberOfSystemPtes / 6;
@ -119,7 +138,7 @@ MiInitializeSpecialPool()
/* Reserving didn't work, so try to reduce the requested size */
ASSERT(SpecialPoolPtes >= PTE_PER_PAGE);
SpecialPoolPtes -= 1024;
SpecialPoolPtes -= PTE_PER_PAGE;
} while (SpecialPoolPtes);
/* Fail if we couldn't reserve them at all */
@ -132,7 +151,7 @@ MiInitializeSpecialPool()
MiSpecialPoolFirstPte = PointerPte;
MmSpecialPoolStart = MiPteToAddress(PointerPte);
for (i = 0; i<512; i++)
for (i = 0; i < PTE_PER_PAGE / 2; i++)
{
/* Point it to the next entry */
PointerPte->u.List.NextEntry = &PointerPte[2] - MmSystemPteBase;
@ -143,7 +162,7 @@ MiInitializeSpecialPool()
/* Save extra values */
MiSpecialPoolExtra = PointerPte;
MiSpecialPoolExtraCount = SpecialPoolPtes - 1024;
MiSpecialPoolExtraCount = SpecialPoolPtes - PTE_PER_PAGE;
/* Mark the previous PTE as the last one */
MiSpecialPoolLastPte = PointerPte - 2;
@ -160,10 +179,52 @@ MiInitializeSpecialPool()
MiSpecialPagesNonPagedMaximum = MmResidentAvailablePages >> 3;
DPRINT1("Special pool start %p - end %p\n", MmSpecialPoolStart, MmSpecialPoolEnd);
ExpPoolFlags |= POOL_FLAG_SPECIAL_POOL;
//MiTestSpecialPool();
}
NTSTATUS
NTAPI
MmExpandSpecialPool(VOID)
{
ULONG i;
PMMPTE PointerPte;
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
if (MiSpecialPoolExtraCount == 0)
return STATUS_INSUFFICIENT_RESOURCES;
PointerPte = MiSpecialPoolExtra;
ASSERT(MiSpecialPoolFirstPte == MiSpecialPoolLastPte);
ASSERT(MiSpecialPoolFirstPte->u.List.NextEntry == MM_EMPTY_PTE_LIST);
MiSpecialPoolFirstPte->u.List.NextEntry = PointerPte - MmSystemPteBase;
ASSERT(MiSpecialPoolExtraCount >= PTE_PER_PAGE);
for (i = 0; i < PTE_PER_PAGE / 2; i++)
{
/* Point it to the next entry */
PointerPte->u.List.NextEntry = &PointerPte[2] - MmSystemPteBase;
/* Move to the next pair */
PointerPte += 2;
}
/* Save remaining extra values */
MiSpecialPoolExtra = PointerPte;
MiSpecialPoolExtraCount -= PTE_PER_PAGE;
/* Mark the previous PTE as the last one */
MiSpecialPoolLastPte = PointerPte - 2;
MiSpecialPoolLastPte->u.List.NextEntry = MM_EMPTY_PTE_LIST;
/* Save new end address of the special pool */
MmSpecialPoolEnd = MiPteToAddress(MiSpecialPoolLastPte + 1);
return STATUS_SUCCESS;
}
PVOID
NTAPI
MmAllocateSpecialPool(SIZE_T NumberOfBytes, ULONG Tag, POOL_TYPE PoolType, ULONG SpecialType)
@ -176,7 +237,7 @@ MmAllocateSpecialPool(SIZE_T NumberOfBytes, ULONG Tag, POOL_TYPE PoolType, ULONG
PVOID Entry;
PPOOL_HEADER Header;
DPRINT1("MmAllocateSpecialPool(%x %x %x %x)\n", NumberOfBytes, Tag, PoolType, SpecialType);
DPRINT("MmAllocateSpecialPool(%x %x %x %x)\n", NumberOfBytes, Tag, PoolType, SpecialType);
/* Check if the pool is initialized and quit if it's not */
if (!MiSpecialPoolFirstPte) return NULL;
@ -191,7 +252,11 @@ MmAllocateSpecialPool(SIZE_T NumberOfBytes, ULONG Tag, POOL_TYPE PoolType, ULONG
((PoolType != PagedPool) && (Irql > DISPATCH_LEVEL)))
{
/* Bad caller */
KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION, Irql, PoolType, NumberOfBytes, 0x30);
KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION,
Irql,
PoolType,
NumberOfBytes,
0x30);
}
/* TODO: Take into account various limitations */
@ -210,14 +275,19 @@ MmAllocateSpecialPool(SIZE_T NumberOfBytes, ULONG Tag, POOL_TYPE PoolType, ULONG
return NULL;
}
/* Reject allocation if special pool PTE list is exhausted */
/* Check if special pool PTE list is exhausted */
if (MiSpecialPoolFirstPte->u.List.NextEntry == MM_EMPTY_PTE_LIST)
{
/* Release the PFN database lock */
KeReleaseQueuedSpinLock(LockQueuePfnLock, Irql);
DPRINT1("Special pool: No PTEs left!\n");
/* TODO: Expand the special pool */
return NULL;
/* Try to expand it */
if (!NT_SUCCESS(MmExpandSpecialPool()))
{
/* No reserves left, reject this allocation */
static int once;
KeReleaseQueuedSpinLock(LockQueuePfnLock, Irql);
if (!once++) DPRINT1("Special pool: No PTEs left!\n");
return NULL;
}
ASSERT(MiSpecialPoolFirstPte->u.List.NextEntry != MM_EMPTY_PTE_LIST);
}
/* Save allocation time */
@ -286,8 +356,8 @@ MmAllocateSpecialPool(SIZE_T NumberOfBytes, ULONG Tag, POOL_TYPE PoolType, ULONG
That time will be used to check memory consistency within the allocated
page. */
Header->PoolTag = Tag;
Header->BlockSize = (USHORT)TickCount.LowPart;
DPRINT1("%p\n", Entry);
Header->BlockSize = (UCHAR)TickCount.LowPart;
DPRINT("%p\n", Entry);
return Entry;
}
@ -300,6 +370,7 @@ MiSpecialPoolCheckPattern(PUCHAR P, PPOOL_HEADER Header)
/* Get amount of bytes user requested to be allocated by clearing out the paged mask */
BytesRequested = (Header->Ulong1 & ~SPECIAL_POOL_PAGED) & 0xFFFF;
ASSERT(BytesRequested <= PAGE_SIZE - sizeof(POOL_HEADER));
/* Get a pointer to the end of user's area */
Ptr = P + BytesRequested;
@ -320,7 +391,11 @@ MiSpecialPoolCheckPattern(PUCHAR P, PPOOL_HEADER Header)
/* Bugcheck if bytes don't match */
if (Ptr[Index] != Header->BlockSize)
{
KeBugCheckEx(BAD_POOL_HEADER, (ULONG_PTR)P, (ULONG_PTR)&Ptr[Index], Header->BlockSize, 0x24);
KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION,
(ULONG_PTR)P,
(ULONG_PTR)&Ptr[Index],
Header->BlockSize,
0x24);
}
}
}
@ -341,7 +416,7 @@ MmFreeSpecialPool(PVOID P)
LARGE_INTEGER TickCount;
PMMPFN Pfn;
DPRINT1("MmFreeSpecialPool(%p)\n", P);
DPRINT("MmFreeSpecialPool(%p)\n", P);
/* Get the PTE */
PointerPte = MiAddressToPte(P);
@ -353,7 +428,11 @@ MmFreeSpecialPool(PVOID P)
if (PointerPte->u.Soft.Protection == MM_NOACCESS ||
!PointerPte->u.Soft.Protection)
{
KeBugCheckEx(BAD_POOL_HEADER, (ULONG_PTR)P, (ULONG_PTR)PointerPte, 0, 0x20);
KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION,
(ULONG_PTR)P,
(ULONG_PTR)PointerPte,
0,
0x20);
}
}
@ -375,28 +454,35 @@ MmFreeSpecialPool(PVOID P)
if ((Header->Ulong1 & SPECIAL_POOL_PAGED) == 0)
{
/* Non-paged allocation, ensure that IRQ is not higher that DISPATCH */
ASSERT((PointerPte + 1)->u.Soft.PageFileHigh == SPECIAL_POOL_NONPAGED_PTE);
PoolType = NonPagedPool;
ASSERT(PointerPte[1].u.Soft.PageFileHigh == SPECIAL_POOL_NONPAGED_PTE);
if (Irql > DISPATCH_LEVEL)
{
KeBugCheckEx(BAD_POOL_HEADER, Irql, (ULONG_PTR)P, 0, 0x31);
KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION,
Irql,
PoolType,
(ULONG_PTR)P,
0x31);
}
PoolType = NonPagedPool;
}
else
{
/* Paged allocation, ensure */
ASSERT((PointerPte + 1)->u.Soft.PageFileHigh == SPECIAL_POOL_PAGED_PTE);
if (Irql > DISPATCH_LEVEL)
{
KeBugCheckEx(BAD_POOL_HEADER, Irql, (ULONG_PTR)P, 1, 0x31);
}
PoolType = PagedPool;
ASSERT(PointerPte[1].u.Soft.PageFileHigh == SPECIAL_POOL_PAGED_PTE);
if (Irql > APC_LEVEL)
{
KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION,
Irql,
PoolType,
(ULONG_PTR)P,
0x31);
}
}
/* Get amount of bytes user requested to be allocated by clearing out the paged mask */
BytesRequested = (Header->Ulong1 & ~SPECIAL_POOL_PAGED) & 0xFFFF;
ASSERT(BytesRequested <= PAGE_SIZE - sizeof(POOL_HEADER));
/* Check memory before the allocated user buffer in case of overruns detection */
if (Overruns)
@ -407,21 +493,33 @@ MmFreeSpecialPool(PVOID P)
/* If they mismatch, it's unrecoverable */
if (BytesRequested > BytesReal)
{
KeBugCheckEx(BAD_POOL_HEADER, (ULONG_PTR)P, BytesRequested, BytesReal, 0x21);
KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION,
(ULONG_PTR)P,
BytesRequested,
BytesReal,
0x21);
}
if (BytesRequested + sizeof(POOL_HEADER) < BytesReal)
{
KeBugCheckEx(BAD_POOL_HEADER, (ULONG_PTR)P, BytesRequested, BytesReal, 0x22);
KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION,
(ULONG_PTR)P,
BytesRequested,
BytesReal,
0x22);
}
/* Actually check the memory pattern */
for (b = (PUCHAR)(Header + 1); b < (PUCHAR)P; b++)
{
if (Header->BlockSize != b[0])
if (*b != Header->BlockSize)
{
/* Bytes mismatch */
KeBugCheckEx(BAD_POOL_HEADER, (ULONG_PTR)P, (ULONG_PTR)b, Header->BlockSize, 0x23);
KeBugCheckEx(SPECIAL_POOL_DETECTED_MEMORY_CORRUPTION,
(ULONG_PTR)P,
(ULONG_PTR)b,
Header->BlockSize,
0x23);
}
}
}
@ -448,7 +546,6 @@ MmFreeSpecialPool(PVOID P)
Pfn = MI_PFN_ELEMENT(PointerPte->u.Hard.PageFrameNumber);
/* Lock PFN database */
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
Irql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
/* Delete this PFN */
@ -457,6 +554,8 @@ MmFreeSpecialPool(PVOID P)
/* Decrement share count of this PFN */
MiDecrementShareCount(Pfn, PointerPte->u.Hard.PageFrameNumber);
MI_ERASE_PTE(PointerPte);
/* Flush the TLB */
//FIXME: Use KeFlushSingleTb() instead
KeFlushEntireTb(TRUE, TRUE);
@ -467,12 +566,11 @@ MmFreeSpecialPool(PVOID P)
MiDeleteSystemPageableVm(PointerPte, 1, 0, NULL);
/* Lock PFN database */
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
Irql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
}
/* Mark next PTE as invalid */
PointerPte[1].u.Long = 0; //|= 8000;
MI_ERASE_PTE(PointerPte + 1);
/* Make sure that the last entry is really the last one */
ASSERT(MiSpecialPoolLastPte->u.List.NextEntry == MM_EMPTY_PTE_LIST);

View file

@ -49,8 +49,7 @@ static BYTE Int16To32[] =
0xFB, // sti
// HACK: The following instruction should be HLT!
0x90, // nop
0xF4, // hlt
0xEB, 0xF5, // jmp BOP_SEQ (offset -11)

View file

@ -59,7 +59,7 @@ IntCopyRegistryKey(
if (InfoBuffer == NULL)
{
ERR_(VIDEOPRT, "Could not allocate buffer for key info\n");
return Status;
return STATUS_INSUFFICIENT_RESOURCES;
}
}

View file

@ -2083,7 +2083,7 @@ ftGdiGetGlyphOutline(
src += ft_face->glyph->bitmap.pitch;
dst += pitch;
}
return needed;
break;
}
case ft_glyph_format_outline:
{
@ -2113,22 +2113,24 @@ ftGdiGetGlyphOutline(
{
return GDI_ERROR;
}
start = pvBuf;
for (row = 0; row < height; row++)
{
ptr = start;
for (col = 0; col < width; col++, ptr++)
{
*ptr = (((int)*ptr) * mult + 128) / 256;
}
start += pitch;
}
break;
}
default:
DPRINT1("Loaded glyph format %x\n", ft_face->glyph->format);
return GDI_ERROR;
}
start = pvBuf;
for (row = 0; row < height; row++)
{
ptr = start;
for (col = 0; col < width; col++, ptr++)
{
*ptr = (((int)*ptr) * mult + 128) / 256;
}
start += pitch;
}
break;
}
case GGO_NATIVE:

View file

@ -162,15 +162,3 @@ BOOL NTAPI W32kDosPathNameToNtPathName(PCWSTR, PUNICODE_STRING);
#define ROUND_UP(n, align) \
ROUND_DOWN(((ULONG)n) + (align) - 1, (align))
#define LIST_FOR_EACH(elem, list, type, field) \
for ((elem) = CONTAINING_RECORD((list)->Flink, type, field); \
&(elem)->field != (list) && ((&((elem)->field)) != NULL); \
(elem) = CONTAINING_RECORD((elem)->field.Flink, type, field))
#define LIST_FOR_EACH_SAFE(cursor, cursor2, list, type, field) \
for ((cursor) = CONTAINING_RECORD((list)->Flink, type, field), \
(cursor2) = CONTAINING_RECORD((cursor)->field.Flink, type, field); \
&(cursor)->field != (list); \
(cursor) = (cursor2), \
(cursor2) = CONTAINING_RECORD((cursor)->field.Flink, type, field))

View file

@ -521,18 +521,24 @@ typedef struct _CLS
INT cbclsExtra;
INT cbwndExtra;
HINSTANCE hModule;
#ifdef NEW_CURSORICON
struct _CURICON_OBJECT* spicn;
struct _CURICON_OBJECT* spcur;
#else
HANDLE hIcon; /* FIXME - Use pointer! */
//PCURSOR spicn;
HANDLE hCursor; /* FIXME - Use pointer! */
//PCURSOR spcur;
#endif
HBRUSH hbrBackground;
PWSTR lpszMenuName; // kernel use
PSTR lpszAnsiClassName; // "
#ifdef NEW_CURSORICON
struct _CURICON_OBJECT* spicnSm;
#else
HANDLE hIconSm; /* FIXME - Use pointer! */
//PCURSOR spicnSm;
//// ReactOS dosn't suppot cache icons.
HICON hIconSmIntern; /* Internal small icon, derived from hIcon */
#endif
////
UINT Unicode : 1; // !CSF_ANSIPROC
UINT Global : 1; // CS_GLOBALCLASS or CSF_SERVERSIDEPROC

View file

@ -7,6 +7,7 @@
*/
#include <win32k.h>
DBG_DEFAULT_CHANNEL(UserClass);
/* CALLPROC ******************************************************************/
@ -110,6 +111,7 @@ UserGetCPD(
{
PCLS pCls;
PWND pWnd;
PDESKTOP pDesk;
PCALLPROCDATA CallProc = NULL;
PTHREADINFO pti;
@ -131,7 +133,14 @@ UserGetCPD(
// No luck, create a new one for the requested proc.
if (!CallProc)
{
CallProc = CreateCallProc( pCls->rpdeskParent,
if (!pCls->rpdeskParent)
{
TRACE("Null DESKTOP Atom %d\n",pCls->atomClassName);
pDesk = pti->rpdesk;
}
else
pDesk = pCls->rpdeskParent;
CallProc = CreateCallProc( pDesk,
(WNDPROC)ProcIn,
!!(Flags & UserGetCPDA2U),
pti->ppi);

View file

@ -245,8 +245,17 @@ IntDestroyClass(IN OUT PCLS Class)
IntFreeClassMenuName(Class);
}
#ifdef NEW_CURSORICON
if (Class->spicn)
UserDereferenceObject(Class->spicn);
if (Class->spicnSm)
UserDereferenceObject(Class->spicnSm);
if (Class->spcur)
UserDereferenceObject(Class->spcur);
#else
if (Class->hIconSmIntern)
IntClassDestroyIcon(Class->hIconSmIntern);
#endif
pDesk = Class->rpdeskParent;
Class->rpdeskParent = NULL;
@ -587,11 +596,22 @@ IntGetClassForDesktop(IN OUT PCLS BaseClass,
Class = DesktopHeapAlloc(Desktop,
ClassSize);
if (Class != NULL)
{
/* Simply clone the class */
RtlCopyMemory( Class, BaseClass, ClassSize);
#ifdef NEW_CURSORICON
/* Reference our objects */
if (Class->spcur)
UserReferenceObject(Class->spcur);
if (Class->spicn)
UserReferenceObject(Class->spicn);
if (Class->spicnSm)
UserReferenceObject(Class->spicnSm);
#endif
TRACE("Clone Class 0x%p hM 0x%p\n %S\n",Class, Class->hModule, Class->lpszClientUnicodeMenuName);
/* Restore module address if default user class Ref: Bug 4778 */
@ -1009,10 +1029,15 @@ IntCreateClass(IN CONST WNDCLASSEXW* lpwcx,
Class->cbclsExtra = lpwcx->cbClsExtra;
Class->cbwndExtra = lpwcx->cbWndExtra;
Class->hModule = lpwcx->hInstance;
//// FIXME handles to pointers
#ifdef NEW_CURSORICON
Class->spicn = lpwcx->hIcon ? UserGetCurIconObject(lpwcx->hIcon) : NULL;
Class->spcur = lpwcx->hCursor ? UserGetCurIconObject(lpwcx->hCursor) : NULL;
Class->spicnSm = lpwcx->hIconSm ? UserGetCurIconObject(lpwcx->hIconSm) : NULL;
#else
Class->hIcon = lpwcx->hIcon;
Class->hIconSm = lpwcx->hIconSm;
Class->hCursor = lpwcx->hCursor;
#endif
////
Class->hbrBackground = lpwcx->hbrBackground;
@ -1726,13 +1751,7 @@ IntSetClassMenuName(IN PCLS Class,
return Ret;
}
//// Do this for now in anticipation of new cursor icon code.
#ifndef NEW_CURSORICON
BOOLEAN FASTCALL IntDestroyCurIconObject(PCURICON_OBJECT, PPROCESSINFO);
#else
BOOLEAN FASTCALL IntDestroyCurIconObject(PCURICON_OBJECT, BOOLEAN);
#endif
BOOL FASTCALL
IntClassDestroyIcon(HANDLE hCurIcon)
{
@ -1745,19 +1764,15 @@ IntClassDestroyIcon(HANDLE hCurIcon)
ERR("hCurIcon was not found!\n");
return FALSE;
}
#ifndef NEW_CURSORICON
Ret = IntDestroyCurIconObject(CurIcon, PsGetCurrentProcessWin32Process());
/* Note: IntDestroyCurIconObject will remove our reference for us! */
#else
/* Note: IntDestroyCurIconObject will remove our reference for us! */
Ret = IntDestroyCurIconObject(CurIcon, TRUE);
#endif
Ret = IntDestroyCurIconObject(CurIcon, GetW32ProcessInfo());
if (!Ret)
{
ERR("hCurIcon was not Destroyed!\n");
}
return Ret;
}
#endif
ULONG_PTR
UserSetClassLongPtr(IN PCLS Class,
@ -1766,7 +1781,9 @@ UserSetClassLongPtr(IN PCLS Class,
IN BOOL Ansi)
{
ULONG_PTR Ret = 0;
#ifndef NEW_CURSORICON
HANDLE hIconSmIntern = NULL;
#endif
/* NOTE: For GCLP_MENUNAME and GCW_ATOM this function may raise an exception! */
@ -1838,6 +1855,54 @@ UserSetClassLongPtr(IN PCLS Class,
}
break;
#ifdef NEW_CURSORICON
case GCLP_HCURSOR:
{
PCURICON_OBJECT NewCursor = NULL;
if (NewLong)
{
NewCursor = UserGetCurIconObject((HCURSOR)NewLong);
if (!NewCursor)
{
EngSetLastError(ERROR_INVALID_CURSOR_HANDLE);
return 0;
}
}
if (Class->spcur)
{
Ret = (ULONG_PTR)UserHMGetHandle(Class->spcur);
UserDereferenceObject(Class->spcur);
}
else
{
Ret = 0;
}
if (Ret == NewLong)
{
/* It's a nop */
return Ret;
}
Class->spcur = NewCursor;
/* Update the clones */
Class = Class->pclsClone;
while (Class != NULL)
{
if (Class->spcur)
UserDereferenceObject(Class->spcur);
if (NewCursor)
UserReferenceObject(NewCursor);
Class->spcur = NewCursor;
Class = Class->pclsNext;
}
break;
}
#else
case GCLP_HCURSOR:
/* FIXME: Get handle from pointer to CURSOR object */
Ret = (ULONG_PTR)Class->hCursor;
@ -1851,6 +1916,7 @@ UserSetClassLongPtr(IN PCLS Class,
Class = Class->pclsNext;
}
break;
#endif
// MSDN:
// hIconSm, A handle to a small icon that is associated with the window class.
@ -1858,6 +1924,88 @@ UserSetClassLongPtr(IN PCLS Class,
// the hIcon member for an icon of the appropriate size to use as the small icon.
//
case GCLP_HICON:
#ifdef NEW_CURSORICON
{
PCURICON_OBJECT NewIcon = NULL;
PCURICON_OBJECT NewSmallIcon = NULL;
if (NewLong)
{
NewIcon = UserGetCurIconObject((HCURSOR)NewLong);
if (!NewIcon)
{
EngSetLastError(ERROR_INVALID_ICON_HANDLE);
return 0;
}
}
if (Class->spicn)
{
Ret = (ULONG_PTR)UserHMGetHandle(Class->spicn);
UserDereferenceObject(Class->spicn);
}
else
{
Ret = 0;
}
if (Ret == NewLong)
{
/* It's a nop */
return Ret;
}
if (Ret && (Class->CSF_flags & CSF_CACHEDSMICON))
{
/* We will change the small icon */
UserDereferenceObject(Class->spicnSm);
Class->spicnSm = NULL;
Class->CSF_flags &= ~CSF_CACHEDSMICON;
}
if (NewLong && !Class->spicnSm)
{
/* Create the new small icon from the new large(?) one */
HICON SmallIconHandle = co_IntCopyImage(
(HICON)NewLong,
IMAGE_ICON,
UserGetSystemMetrics( SM_CXSMICON ),
UserGetSystemMetrics( SM_CYSMICON ),
0);
if (SmallIconHandle)
{
/* So use it */
NewSmallIcon = Class->spicnSm = UserGetCurIconObject(SmallIconHandle);
/* Let the handle go, we have the reference on the object */
NtUserDestroyCursor(SmallIconHandle, FALSE);
Class->CSF_flags |= CSF_CACHEDSMICON;
}
}
Class->spicn = NewIcon;
/* Update the clones */
Class = Class->pclsClone;
while (Class != NULL)
{
if (Class->spicn)
UserDereferenceObject(Class->spicn);
if (NewIcon)
UserReferenceObject(NewIcon);
Class->spicn = NewIcon;
if (NewSmallIcon)
{
if (Class->spicnSm)
UserDereferenceObject(Class->spicnSm);
UserReferenceObject(NewSmallIcon);
Class->spicnSm = NewSmallIcon;
Class->CSF_flags |= CSF_CACHEDSMICON;
}
Class = Class->pclsNext;
}
break;
}
#else
/* FIXME: Get handle from pointer to ICON object */
Ret = (ULONG_PTR)Class->hIcon;
if (Class->hIcon == (HANDLE)NewLong) break;
@ -1885,8 +2033,51 @@ UserSetClassLongPtr(IN PCLS Class,
Class = Class->pclsNext;
}
break;
#endif
case GCLP_HICONSM:
#ifdef NEW_CURSORICON
{
PCURICON_OBJECT NewSmallIcon = NULL;
if (NewLong)
{
NewSmallIcon = UserGetCurIconObject((HCURSOR)NewLong);
if (!NewSmallIcon)
{
EngSetLastError(ERROR_INVALID_ICON_HANDLE);
return 0;
}
}
if (Class->spicnSm)
{
Ret = (ULONG_PTR)UserHMGetHandle(Class->spicnSm);
UserDereferenceObject(Class->spicnSm);
}
else
{
Ret = 0;
}
Class->CSF_flags &= ~CSF_CACHEDSMICON;
Class->spicnSm = NewSmallIcon;
/* Update the clones */
Class = Class->pclsClone;
while (Class != NULL)
{
if (Class->spicnSm)
UserDereferenceObject(Class->spicnSm);
if (NewSmallIcon)
UserReferenceObject(NewSmallIcon);
Class->CSF_flags &= ~CSF_CACHEDSMICON;
Class->spicnSm = NewSmallIcon;
Class = Class->pclsNext;
}
}
break;
#else
/* FIXME: Get handle from pointer to ICON object */
Ret = (ULONG_PTR)Class->hIconSm;
if (Class->hIconSm == (HANDLE)NewLong) break;
@ -1920,6 +2111,7 @@ UserSetClassLongPtr(IN PCLS Class,
Class = Class->pclsNext;
}
break;
#endif
case GCLP_HMODULE:
Ret = (ULONG_PTR)Class->hModule;
@ -2011,8 +2203,16 @@ UserGetClassInfo(IN PCLS Class,
lpwcx->cbClsExtra = Class->cbclsExtra;
lpwcx->cbWndExtra = Class->cbwndExtra;
#ifdef NEW_CURSORICON
lpwcx->hIcon = Class->spicn ? UserHMGetHandle(Class->spicn) : NULL;
lpwcx->hCursor = Class->spcur ? UserHMGetHandle(Class->spcur) : NULL;
lpwcx->hIconSm = Class->spicnSm ? UserHMGetHandle(Class->spicnSm) : NULL;
#else
lpwcx->hIcon = Class->hIcon; /* FIXME: Get handle from pointer */
lpwcx->hCursor = Class->hCursor; /* FIXME: Get handle from pointer */
/* FIXME: Get handle from pointer */
lpwcx->hIconSm = Class->hIconSm ? Class->hIconSm : Class->hIconSmIntern;
#endif
lpwcx->hbrBackground = Class->hbrBackground;
/* Copy non-string to user first. */
@ -2042,9 +2242,6 @@ UserGetClassInfo(IN PCLS Class,
/* FIXME: Return the string? Okay! This is performed in User32! */
//lpwcx->lpszClassName = (LPCWSTR)((ULONG_PTR)Class->atomClassName);
/* FIXME: Get handle from pointer */
lpwcx->hIconSm = Class->hIconSm ? Class->hIconSm : Class->hIconSmIntern;
return TRUE;
}

View file

@ -144,12 +144,16 @@ static BOOLEAN FASTCALL
ReferenceCurIconByProcess(PCURICON_OBJECT CurIcon)
{
PPROCESSINFO Win32Process;
PLIST_ENTRY ListEntry;
PCURICON_PROCESS Current;
Win32Process = PsGetCurrentProcessWin32Process();
LIST_FOR_EACH(Current, &CurIcon->ProcessList, CURICON_PROCESS, ListEntry)
ListEntry = CurIcon->ProcessList.Flink;
while (ListEntry != &CurIcon->ProcessList)
{
Current = CONTAINING_RECORD(ListEntry, CURICON_PROCESS, ListEntry);
ListEntry = ListEntry->Flink;
if (Current->Process == Win32Process)
{
/* Already registered for this process */
@ -165,6 +169,7 @@ ReferenceCurIconByProcess(PCURICON_OBJECT CurIcon)
}
InsertHeadList(&CurIcon->ProcessList, &Current->ListEntry);
Current->Process = Win32Process;
IntReferenceProcessInfo(Win32Process);
return TRUE;
}
@ -173,10 +178,14 @@ PCURICON_OBJECT FASTCALL
IntFindExistingCurIconObject(HMODULE hModule,
HRSRC hRsrc, LONG cx, LONG cy)
{
PLIST_ENTRY ListEntry;
PCURICON_OBJECT CurIcon;
LIST_FOR_EACH(CurIcon, &gCurIconList, CURICON_OBJECT, ListEntry)
ListEntry = gCurIconList.Flink;
while (ListEntry != &gCurIconList)
{
CurIcon = CONTAINING_RECORD(ListEntry, CURICON_OBJECT, ListEntry);
ListEntry = ListEntry->Flink;
// if (NT_SUCCESS(UserReferenceObjectByPointer(Object, TYPE_CURSOR))) // <- huh????
// UserReferenceObject( CurIcon);
@ -247,7 +256,8 @@ IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, PPROCESSINFO ppi)
PSYSTEM_CURSORINFO CurInfo;
HBITMAP bmpMask, bmpColor;
BOOLEAN Ret, bListEmpty, bFound = FALSE;
PCURICON_PROCESS Current = NULL;
PLIST_ENTRY ListEntry;
PCURICON_PROCESS Current;
/* For handles created without any data (error handling) */
if(IsListEmpty(&CurIcon->ProcessList))
@ -255,12 +265,16 @@ IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, PPROCESSINFO ppi)
/* Now find this process in the list of processes referencing this object and
remove it from that list */
LIST_FOR_EACH(Current, &CurIcon->ProcessList, CURICON_PROCESS, ListEntry)
ListEntry = CurIcon->ProcessList.Flink;
while (ListEntry != &CurIcon->ProcessList)
{
Current = CONTAINING_RECORD(ListEntry, CURICON_PROCESS, ListEntry);
ListEntry = ListEntry->Flink;
if (Current->Process == ppi)
{
bFound = TRUE;
bListEmpty = RemoveEntryList(&Current->ListEntry);
IntDereferenceProcessInfo(ppi);
break;
}
}

View file

@ -41,6 +41,14 @@ typedef struct tagACON
C_ASSERT(FIELD_OFFSET(ACON, cpcur) == FIELD_OFFSET(CURICON_OBJECT, xHotspot));
BOOLEAN
IntDestroyCurIconObject(PVOID Object);
VOID FASTCALL
IntCleanupCurIconCache(PPROCESSINFO Win32Process);
void FreeCurIconObject(PVOID Object);
#else
typedef struct tagCURICON_PROCESS
@ -62,6 +70,9 @@ typedef struct _CURICON_OBJECT
BYTE Shadow;
ICONINFO IconInfo;
} CURICON_OBJECT, *PCURICON_OBJECT;
BOOLEAN FASTCALL IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, PPROCESSINFO ppi);
BOOL FASTCALL IntDestroyCursor(HANDLE hCurIcon, BOOL bForce);
HCURSOR FASTCALL IntSetCursor(HCURSOR hCursor);
#endif
typedef struct _CURSORACCELERATION_INFO
@ -112,9 +123,6 @@ PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon);
BOOL UserSetCursorPos( INT x, INT y, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook);
BOOL APIENTRY UserClipCursor(RECTL *prcl);
PSYSTEM_CURSORINFO IntGetSysCursorInfo(VOID);
HCURSOR FASTCALL IntSetCursor(HCURSOR hCursor);
BOOL FASTCALL IntDestroyCursor(HANDLE hCurIcon, BOOL bForce);
BOOLEAN FASTCALL IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, PPROCESSINFO ppi);
#define IntReleaseCurIconObject(CurIconObj) \
UserDereferenceObject(CurIconObj)

View file

@ -133,7 +133,7 @@ IntCreateCurIconHandle(BOOLEAN Animated)
CurIcon = UserCreateObject(
gHandleTable,
NULL,
NULL,
GetW32ThreadInfo(),
&hCurIcon,
TYPE_CURSOR,
Animated ? sizeof(ACON) : sizeof(CURICON_OBJECT));
@ -149,35 +149,23 @@ IntCreateCurIconHandle(BOOLEAN Animated)
return hCurIcon;
}
BOOLEAN FASTCALL
IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, BOOLEAN bForce)
BOOLEAN
IntDestroyCurIconObject(
_In_ PVOID Object)
{
if(CurIcon->CURSORF_flags & CURSORF_CURRENT)
{
/* Mark the object as destroyed, and fail, as per tests */
TRACE("Cursor is current, marking as destroyed.\n");
UserDeleteObject(CurIcon->head.h, TYPE_CURSOR);
return FALSE;
}
PCURICON_OBJECT CurIcon = Object;
if(CurIcon->head.ppi != PsGetCurrentProcessWin32Process())
{
/* This object doesn't belong to the current process */
WARN("Trying to delete foreign cursor!\n");
UserDereferenceObject(CurIcon);
EngSetLastError(ERROR_DESTROY_OBJECT_OF_OTHER_THREAD);
return FALSE;
}
/* We just mark the handle as being destroyed.
* Deleting all the stuff will be deferred to the actual struct free. */
return UserDeleteObject(CurIcon->head.h, TYPE_CURSOR);
}
void
FreeCurIconObject(
_In_ PVOID Object)
{
PCURICON_OBJECT CurIcon = Object;
/* Do not destroy it if it is shared. (And we're not forced to) */
if((CurIcon->CURSORF_flags & CURSORF_LRSHARED) && !bForce)
{
/* Tests show this is a valid call */
WARN("Trying to destroy shared cursor!\n");
UserDereferenceObject(CurIcon);
return TRUE;
}
if(!(CurIcon->CURSORF_flags & CURSORF_ACON))
{
HBITMAP bmpMask = CurIcon->hbmMask;
@ -210,103 +198,58 @@ IntDestroyCurIconObject(PCURICON_OBJECT CurIcon, BOOLEAN bForce)
UINT i;
for(i = 0; i < AniCurIcon->cpcur; i++)
IntDestroyCurIconObject(AniCurIcon->aspcur[i], TRUE);
IntDestroyCurIconObject(AniCurIcon->aspcur[i]);
ExFreePoolWithTag(AniCurIcon->aspcur, USERTAG_CURSOR);
}
if (CurIcon->CURSORF_flags & CURSORF_LRSHARED)
{
PPROCESSINFO ppi;
if (!IS_INTRESOURCE(CurIcon->strName.Buffer))
ExFreePoolWithTag(CurIcon->strName.Buffer, TAG_STRING);
if (CurIcon->atomModName)
RtlDeleteAtomFromAtomTable(gAtomTable, CurIcon->atomModName);
CurIcon->strName.Buffer = NULL;
CurIcon->atomModName = 0;
/* Try finding it in its process cache */
ppi = CurIcon->head.ppi;
if (ppi->pCursorCache == CurIcon)
ppi->pCursorCache = CurIcon->pcurNext;
else
{
PCURICON_OBJECT CacheCurIcon= ppi->pCursorCache;
while (CacheCurIcon)
{
if (CacheCurIcon->pcurNext == CurIcon)
{
CacheCurIcon->pcurNext = CurIcon->pcurNext;
break;
}
CacheCurIcon = CacheCurIcon->pcurNext;
}
}
}
/* We were given a pointer, no need to keep the reference any longer! */
UserDereferenceObject(CurIcon);
return UserDeleteObject(CurIcon->head.h, TYPE_CURSOR);
/* Finally free the thing */
FreeProcMarkObject(CurIcon);
}
VOID FASTCALL
IntCleanupCurIcons(struct _EPROCESS *Process, PPROCESSINFO Win32Process)
IntCleanupCurIconCache(PPROCESSINFO Win32Process)
{
PCURICON_OBJECT CurIcon;
/* Run through the list of icon objects */
while(Win32Process->pCursorCache)
while (Win32Process->pCursorCache)
{
CurIcon = Win32Process->pCursorCache;
Win32Process->pCursorCache = CurIcon->pcurNext;
/* One ref for the handle, one for the list,
* and potentially one from an other process via SetCursor */
ASSERT(CurIcon->head.cLockObj <= 3);
IntDestroyCurIconObject(CurIcon, TRUE);
UserDereferenceObject(CurIcon);
}
}
HCURSOR FASTCALL
IntSetCursor(
HCURSOR hCursor)
{
PCURICON_OBJECT pcurOld, pcurNew;
HCURSOR hOldCursor = NULL;
if (hCursor)
{
pcurNew = UserGetCurIconObject(hCursor);
if (!pcurNew)
{
EngSetLastError(ERROR_INVALID_CURSOR_HANDLE);
goto leave;
}
pcurNew->CURSORF_flags |= CURSORF_CURRENT;
}
else
{
pcurNew = NULL;
}
pcurOld = UserSetCursor(pcurNew, FALSE);
if (pcurOld)
{
hOldCursor = pcurOld->head.h;
pcurOld->CURSORF_flags &= ~CURSORF_CURRENT;
if(UserObjectInDestroy(hOldCursor))
{
/* Destroy it once and for all */
IntDestroyCurIconObject(pcurOld, TRUE);
hOldCursor = NULL;
}
else
{
UserDereferenceObject(pcurOld);
}
}
leave:
return hOldCursor;
}
BOOL FASTCALL
IntDestroyCursor(
HANDLE hCurIcon,
BOOL bForce)
{
PCURICON_OBJECT CurIcon;
BOOL ret;
if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
{
return(FALSE);
}
ret = IntDestroyCurIconObject(CurIcon, bForce);
/* Note: IntDestroyCurIconObject will remove our reference for us! */
return ret;
}
/*
* @implemented
*/
@ -690,27 +633,56 @@ NtUserDestroyCursor(
_In_ HANDLE hCurIcon,
_In_ BOOL bForce)
{
PCURICON_OBJECT CurIcon;
BOOL ret;
DECLARE_RETURN(BOOL);
TRACE("Enter NtUserDestroyCursorIcon\n");
UserEnterExclusive();
if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
if (!bForce)
{
RETURN(FALSE);
/* Maybe we have good reasons not to destroy this object */
PCURICON_OBJECT CurIcon = UserGetCurIconObject(hCurIcon);
ULONG Flags;
if (!CurIcon)
{
ret = FALSE;
goto leave;
}
if (CurIcon->head.ppi != PsGetCurrentProcessWin32Process())
{
/* No way, you're not touching my cursor */
ret = FALSE;
UserDereferenceObject(CurIcon);
goto leave;
}
Flags = CurIcon->CURSORF_flags;
UserDereferenceObject(CurIcon);
if (Flags & CURSORF_CURRENT)
{
WARN("Trying to delete current cursor!\n");
ret = FALSE;
goto leave;
}
if (Flags & CURSORF_LRSHARED)
{
WARN("Trying to delete shared cursor.\n");
/* This one is not an error */
ret = TRUE;
goto leave;
}
}
ret = IntDestroyCurIconObject(CurIcon, bForce);
/* Note: IntDestroyCurIconObject will remove our reference for us! */
/* Destroy the handle */
ret = UserDeleteObject(hCurIcon, TYPE_CURSOR);
RETURN(ret);
CLEANUP:
TRACE("Leave NtUserDestroyCursorIcon, ret=%i\n",_ret_);
leave:
TRACE("Leave NtUserDestroyCursorIcon, ret=%i\n", ret);
UserLeave();
END_CLEANUP;
return ret;
}
@ -891,18 +863,8 @@ NtUserSetCursor(
pcurOld = UserSetCursor(pcurNew, FALSE);
if (pcurOld)
{
hOldCursor = pcurOld->head.h;
pcurOld->CURSORF_flags &= ~CURSORF_CURRENT;
if(UserObjectInDestroy(hOldCursor))
{
/* Destroy it once and for all */
IntDestroyCurIconObject(pcurOld, TRUE);
hOldCursor = NULL;
}
else
{
UserDereferenceObject(pcurOld);
}
UserDereferenceObject(pcurOld);
}
leave:
@ -1088,7 +1050,7 @@ done:
for(i = 0; i < numFrames; i++)
{
if(AniCurIcon->aspcur[i])
IntDestroyCurIconObject(AniCurIcon->aspcur[i], TRUE);
IntDestroyCurIconObject(AniCurIcon->aspcur[i]);
}
AniCurIcon->cicur = 0;
AniCurIcon->cpcur = 0;

View file

@ -44,7 +44,7 @@ typedef struct tagDCE
INIT_FUNCTION NTSTATUS NTAPI InitDCEImpl(VOID);
PDCE FASTCALL DceAllocDCE(PWND Window, DCE_TYPE Type);
HWND FASTCALL IntWindowFromDC(HDC hDc);
PDCE FASTCALL DceFreeDCE(PDCE dce, BOOLEAN Force);
void FASTCALL DceFreeDCE(PDCE dce, BOOLEAN Force);
void FASTCALL DceEmptyCache(void);
VOID FASTCALL DceResetActiveDCEs(PWND Window);
void FASTCALL DceFreeClassDCE(HDC);

View file

@ -387,7 +387,11 @@ DefWndDoSizeMove(PWND pwnd, WORD wParam)
RECT sizingRect, mouseRect, origRect, unmodRect;
HDC hdc;
LONG hittest = (LONG)(wParam & 0x0f);
#ifdef NEW_CURSORICON
PCURICON_OBJECT DragCursor = NULL, OldCursor = NULL;
#else
HCURSOR hDragCursor = 0, hOldCursor = 0;
#endif
POINT minTrack, maxTrack;
POINT capturePoint, pt;
ULONG Style, ExStyle;
@ -495,13 +499,35 @@ DefWndDoSizeMove(PWND pwnd, WORD wParam)
}
hdc = UserGetDCEx( pWndParent, 0, DCX_CACHE );
#ifdef NEW_CURSORICON
if (iconic)
{
DragCursor = pwnd->pcls->spicn;
if (DragCursor)
{
UserReferenceObject(DragCursor);
}
else
{
HCURSOR CursorHandle = (HCURSOR)co_IntSendMessage( UserHMGetHandle(pwnd), WM_QUERYDRAGICON, 0, 0 );
if (CursorHandle)
{
DragCursor = UserGetCurIconObject(CursorHandle);
}
else
{
iconic = FALSE;
}
}
}
#else
if ( iconic ) /* create a cursor for dragging */
{
hDragCursor = pwnd->pcls->hIcon;;
hDragCursor = pwnd->pcls->hIcon;
if ( !hDragCursor ) hDragCursor = (HCURSOR)co_IntSendMessage( UserHMGetHandle(pwnd), WM_QUERYDRAGICON, 0, 0 );
if ( !hDragCursor ) iconic = FALSE;
}
#endif
/* repaint the window before moving it around */
co_UserRedrawWindow( pwnd, NULL, 0, RDW_UPDATENOW | RDW_ALLCHILDREN);
@ -558,14 +584,17 @@ DefWndDoSizeMove(PWND pwnd, WORD wParam)
if ( !moved )
{
moved = TRUE;
if ( iconic ) /* ok, no system popup tracking */
{
hOldCursor = IntSetCursor(hDragCursor);
UserShowCursor( TRUE );
}
else if(!DragFullWindows)
UserDrawMovingFrame( hdc, &sizingRect, thickframe );
if ( iconic ) /* ok, no system popup tracking */
{
#ifdef NEW_CURSORICON
OldCursor = UserSetCursor(DragCursor, FALSE);
#else
hOldCursor = IntSetCursor(hDragCursor);
#endif
UserShowCursor( TRUE );
}
else if(!DragFullWindows)
UserDrawMovingFrame( hdc, &sizingRect, thickframe );
}
if (msg.message == WM_KEYDOWN) UserSetCursorPos(pt.x, pt.y, 0, 0, FALSE);
@ -644,10 +673,22 @@ DefWndDoSizeMove(PWND pwnd, WORD wParam)
{
if ( moved ) /* restore cursors, show icon title later on */
{
UserShowCursor( FALSE );
IntSetCursor( hOldCursor );
UserShowCursor( FALSE );
#ifdef NEW_CURSORICON
OldCursor = UserSetCursor(OldCursor, FALSE);
#else
IntSetCursor( hOldCursor );
#endif
}
#ifdef NEW_CURSORICON
/* It could be that the cursor was already changed while we were proceeding,
* so we must unreference whatever cursor was current at the time we restored the old one.
* Maybe it is DragCursor, but maybe it is another one and DragCursor got already freed.
*/
UserDereferenceObject(OldCursor);
#else
IntDestroyCursor( hDragCursor, FALSE );
#endif
}
else if ( moved && !DragFullWindows )
UserDrawMovingFrame( hdc, &sizingRect, thickframe );
@ -990,6 +1031,19 @@ IntDefWindowProc(
hDC = IntBeginPaint(Wnd, &Ps);
if (hDC)
{
#ifdef NEW_CURSORICON
if (((Wnd->style & WS_MINIMIZE) != 0) && (Wnd->pcls->spicn))
{
RECT ClientRect;
INT x, y;
ERR("Doing Paint and Client area is empty!\n");
IntGetClientRect(Wnd, &ClientRect);
x = (ClientRect.right - ClientRect.left - UserGetSystemMetrics(SM_CXICON)) / 2;
y = (ClientRect.bottom - ClientRect.top - UserGetSystemMetrics(SM_CYICON)) / 2;
UserDrawIconEx(hDC, x, y, Wnd->pcls->spicn, 0, 0, 0, 0, DI_NORMAL | DI_COMPAT | DI_DEFAULTSIZE);
}
#else
HICON hIcon;
if (((Wnd->style & WS_MINIMIZE) != 0) && (hIcon = Wnd->pcls->hIcon))
{
@ -1002,7 +1056,9 @@ IntDefWindowProc(
x = (ClientRect.right - ClientRect.left - UserGetSystemMetrics(SM_CXICON)) / 2;
y = (ClientRect.bottom - ClientRect.top - UserGetSystemMetrics(SM_CYICON)) / 2;
UserDrawIconEx( hDC, x, y, pIcon, 0, 0, 0, 0, DI_NORMAL | DI_COMPAT | DI_DEFAULTSIZE );
UserDereferenceObject(pIcon);
}
#endif
IntEndPaint(Wnd, &Ps);
}
return (0);
@ -1096,23 +1152,43 @@ IntDefWindowProc(
return lResult;
}
HICON FASTCALL NC_IconForWindow( PWND pWnd )
PCURICON_OBJECT FASTCALL NC_IconForWindow( PWND pWnd )
{
HICON hIcon = 0;
PCURICON_OBJECT pIcon = NULL;
HICON hIcon;
// First thing to do, init the Window Logo icons.
if (!gpsi->hIconSmWindows) co_IntSetWndIcons();
if (!hIcon) hIcon = UserGetProp(pWnd, gpsi->atomIconSmProp);
//FIXME: Some callers use this function as if it returns a boolean saying "this window has an icon".
//FIXME: Hence we must return a pointer with no reference count.
//FIXME: This is bad and we should feel bad.
hIcon = UserGetProp(pWnd, gpsi->atomIconSmProp);
if (!hIcon) hIcon = UserGetProp(pWnd, gpsi->atomIconProp);
#ifdef NEW_CURSORICON
if (!hIcon && pWnd->pcls->spicnSm)
return pWnd->pcls->spicnSm;
if (!hIcon && pWnd->pcls->spicn)
return pWnd->pcls->spicn;
#else
if (!hIcon) hIcon = pWnd->pcls->hIconSm;
if (!hIcon) hIcon = pWnd->pcls->hIcon;
#endif
if (!hIcon && pWnd->style & DS_MODALFRAME)
if (!hIcon && (pWnd->style & DS_MODALFRAME))
{
if (!hIcon) hIcon = gpsi->hIconSmWindows; // Both are IDI_WINLOGO Small
if (!hIcon) hIcon = gpsi->hIconWindows; // Reg size.
}
return hIcon;
if (hIcon)
{
pIcon = UserGetCurIconObject(hIcon);
if (pIcon)
{
UserDereferenceObject(pIcon);
}
}
return pIcon;
}
DWORD FASTCALL

View file

@ -662,9 +662,15 @@ DesktopWindowProc(PWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam, LRESULT *lRe
{
return TRUE;
}
#ifdef NEW_CURSORICON
pcurNew->CURSORF_flags |= CURSORF_CURRENT;
#endif
pcurOld = UserSetCursor(pcurNew, FALSE);
if (pcurOld)
{
#ifdef NEW_CURSORICON
pcurOld->CURSORF_flags &= ~CURSORF_CURRENT;
#endif
UserDereferenceObject(pcurOld);
}
return TRUE;
@ -806,12 +812,17 @@ HWND* FASTCALL
UserBuildShellHookHwndList(PDESKTOP Desktop)
{
ULONG entries=0;
PLIST_ENTRY ListEntry;
PSHELL_HOOK_WINDOW Current;
HWND* list;
/* FIXME: If we save nb elements in desktop, we dont have to loop to find nb entries */
LIST_FOR_EACH(Current, &Desktop->ShellHookWindows, SHELL_HOOK_WINDOW, ListEntry)
ListEntry = Desktop->ShellHookWindows.Flink;
while (ListEntry != &Desktop->ShellHookWindows)
{
ListEntry = ListEntry->Flink;
entries++;
}
if (!entries) return NULL;
@ -820,8 +831,13 @@ UserBuildShellHookHwndList(PDESKTOP Desktop)
{
HWND* cursor = list;
LIST_FOR_EACH(Current, &Desktop->ShellHookWindows, SHELL_HOOK_WINDOW, ListEntry)
ListEntry = Desktop->ShellHookWindows.Flink;
while (ListEntry != &Desktop->ShellHookWindows)
{
Current = CONTAINING_RECORD(ListEntry, SHELL_HOOK_WINDOW, ListEntry);
ListEntry = ListEntry->Flink;
*cursor++ = Current->hWnd;
}
*cursor = NULL; /* Nullterm list */
}
@ -930,10 +946,14 @@ BOOL IntDeRegisterShellHookWindow(HWND hWnd)
{
PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
PDESKTOP Desktop = pti->rpdesk;
PLIST_ENTRY ListEntry;
PSHELL_HOOK_WINDOW Current;
LIST_FOR_EACH(Current, &Desktop->ShellHookWindows, SHELL_HOOK_WINDOW, ListEntry)
ListEntry = Desktop->ShellHookWindows.Flink;
while (ListEntry != &Desktop->ShellHookWindows)
{
Current = CONTAINING_RECORD(ListEntry, SHELL_HOOK_WINDOW, ListEntry);
ListEntry = ListEntry->Flink;
if (Current->hWnd == hWnd)
{
RemoveEntryList(&Current->ListEntry);

View file

@ -761,7 +761,8 @@ UserChangeDisplaySettings(
ulResult = PDEVOBJ_bSwitchMode(ppdev, pdm);
/* Restore mouse pointer, no hooks called */
UserSetCursor(pvOldCursor, TRUE);
pvOldCursor = UserSetCursor(pvOldCursor, TRUE);
ASSERT(pvOldCursor == NULL);
/* Check for failure */
if (!ulResult)

View file

@ -238,6 +238,11 @@ DestroyProcessInfo(PEPROCESS Process)
ppiCurrent->hdeskStartup = NULL;
}
#ifdef NEW_CURSORICON
/* Clean up the process icon cache */
IntCleanupCurIconCache(ppiCurrent);
#endif
/* The process is dying */
PsSetProcessWin32Process(Process, NULL, ppiCurrent);
ppiCurrent->peProcess = NULL;

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