* Sync to trunk r51266.

svn path=/branches/cmake-bringup/; revision=51268
This commit is contained in:
Amine Khaldi 2011-04-06 16:00:24 +00:00
commit 3793b7fdf1
122 changed files with 6987 additions and 3292 deletions

View file

@ -4,6 +4,7 @@
* https://sourceforge.net/projects/reactospl * https://sourceforge.net/projects/reactospl
* *
* updated by Caemyr - Olaf Siejka (Jan, 2008) * updated by Caemyr - Olaf Siejka (Jan, 2008)
* updated by Saibamen - Adam Stachowicz (Mar, 2011)
*/ */
LANGUAGE LANG_POLISH, SUBLANG_DEFAULT LANGUAGE LANG_POLISH, SUBLANG_DEFAULT
@ -46,7 +47,7 @@ BEGIN
POPUP "Pomoc" POPUP "Pomoc"
BEGIN BEGIN
MENUITEM "Pomoc", ID_HELP MENUITEM "Pomoc", ID_HELP
MENUITEM "Servman - informacje", ID_ABOUT MENUITEM "O programie", ID_ABOUT
END END
END END
@ -72,11 +73,11 @@ BEGIN
END END
IDD_ABOUTBOX DIALOGEX 22,16,190,182 IDD_ABOUTBOX DIALOGEX 22,16,190,182
CAPTION "Service Manager - informacje" CAPTION "Mened¿er Us³ug - informacje"
FONT 8, "MS Shell Dlg",0,0 FONT 8, "MS Shell Dlg",0,0
STYLE DS_SHELLFONT | WS_BORDER | WS_DLGFRAME | WS_SYSMENU | DS_MODALFRAME STYLE DS_SHELLFONT | WS_BORDER | WS_DLGFRAME | WS_SYSMENU | DS_MODALFRAME
BEGIN BEGIN
LTEXT "Service Manager v0.5.1\nCopyright (C) 2005-2006\nby Ged Murphy (gedmurphy@gmail.com)", IDC_STATIC, 48, 7, 135, 26 LTEXT "Mened¿er Us³ug v0.5.1\nCopyright (C) 2005-2006\nby Ged Murphy (gedmurphy@gmail.com)", IDC_STATIC, 48, 7, 135, 26
PUSHBUTTON "Zamknij", IDOK, 75, 162, 44, 15 PUSHBUTTON "Zamknij", IDOK, 75, 162, 44, 15
ICON IDI_SM_ICON, IDC_STATIC, 10, 10, 7, 30 ICON IDI_SM_ICON, IDC_STATIC, 10, 10, 7, 30
EDITTEXT IDC_LICENSE_EDIT, 8, 44, 174, 107, WS_VISIBLE | WS_VSCROLL | WS_TABSTOP | ES_READONLY | ES_MULTILINE EDITTEXT IDC_LICENSE_EDIT, 8, 44, 174, 107, WS_VISIBLE | WS_VSCROLL | WS_TABSTOP | ES_READONLY | ES_MULTILINE
@ -198,8 +199,8 @@ END
STRINGTABLE DISCARDABLE STRINGTABLE DISCARDABLE
BEGIN BEGIN
IDS_NUM_SERVICES "Numer usługi: %d" IDS_NUM_SERVICES "Numer usługi: %d"
IDS_STOP_DEPENDS "When %s stops, these other services will also stop" IDS_STOP_DEPENDS "Kiedy %s siê zatrzyma, inne us³ugi równie¿ siê zatrzymaj¹"
IDS_NO_DEPENDS "<No Dependencies>" IDS_NO_DEPENDS "<Brak zale¿noœci>"
IDS_LICENSE "Niniejszy program jest wolnym oprogramowaniem; możesz go rozprowadzać dalej i/lub modyfikować na warunkach Powszechnej Licencji Publicznej GNU, wydanej przez Fundację Wolnego Oprogramowania - według wersji 2 tej Licencji lub (według Twojego wyboru) którejś z późniejszych wersji.\r\n\r\nNiniejszy program rozpowszechniany jest z nadzieją, iż będzie on użyteczny - jednak BEZ JAKIEJKOLWIEK GWARANCJI, nawet domyślnej gwarancji PRZYDATNOŚCI HANDLOWEJ albo PRZYDATNOŚCI DO OKREŚLONYCH ZASTOSOWAŃ. W celu uzyskania bliższych informacji sięgnij do Powszechnej Licencji Publicznej GNU.\r\n\r\nZ pewnością wraz z niniejszym programem otrzymałeś też egzemplarz Powszechnej Licencji Publicznej GNU (GNU General Public License); jeśli nie - napisz do Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA." IDS_LICENSE "Niniejszy program jest wolnym oprogramowaniem; możesz go rozprowadzać dalej i/lub modyfikować na warunkach Powszechnej Licencji Publicznej GNU, wydanej przez Fundację Wolnego Oprogramowania - według wersji 2 tej Licencji lub (według Twojego wyboru) którejś z późniejszych wersji.\r\n\r\nNiniejszy program rozpowszechniany jest z nadzieją, iż będzie on użyteczny - jednak BEZ JAKIEJKOLWIEK GWARANCJI, nawet domyślnej gwarancji PRZYDATNOŚCI HANDLOWEJ albo PRZYDATNOŚCI DO OKREŚLONYCH ZASTOSOWAŃ. W celu uzyskania bliższych informacji sięgnij do Powszechnej Licencji Publicznej GNU.\r\n\r\nZ pewnością wraz z niniejszym programem otrzymałeś też egzemplarz Powszechnej Licencji Publicznej GNU (GNU General Public License); jeśli nie - napisz do Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA."
END END

View file

@ -59,7 +59,6 @@ typedef struct _ICMP_ECHO_PACKET
#pragma pack(1) #pragma pack(1)
BOOL InvalidOption;
BOOL NeverStop; BOOL NeverStop;
BOOL ResolveAddresses; BOOL ResolveAddresses;
UINT PingCount; UINT PingCount;
@ -213,84 +212,71 @@ static VOID Reset(VOID)
} }
} }
/* Return ULONG in a string */
static ULONG GetULONG(LPWSTR String)
{
UINT i, Length;
ULONG Value;
LPWSTR StopString;
i = 0;
Length = (UINT)wcslen(String);
while ((i < Length) && ((String[i] < L'0') || (String[i] > L'9'))) i++;
if ((i >= Length) || ((String[i] < L'0') || (String[i] > L'9')))
{
InvalidOption = TRUE;
return 0;
}
Value = wcstoul(&String[i], &StopString, 10);
return Value;
}
/* Return ULONG in a string. Try next paramter if not successful */
static ULONG GetULONG2(LPWSTR String1, LPWSTR String2, PINT i)
{
ULONG Value;
Value = GetULONG(String1);
if (InvalidOption)
{
InvalidOption = FALSE;
if (String2[0] != L'-')
{
Value = GetULONG(String2);
if (!InvalidOption)
*i += 1;
}
}
return Value;
}
/* Parse command line parameters */ /* Parse command line parameters */
static BOOL ParseCmdline(int argc, LPWSTR argv[]) static BOOL ParseCmdline(int argc, LPWSTR argv[])
{ {
INT i; INT i;
BOOL ShowUsage; BOOL FoundTarget = FALSE, InvalidOption = FALSE;
BOOL FoundTarget;
if (argc < 2) if (argc < 2)
ShowUsage = TRUE; {
else Usage();
ShowUsage = FALSE; return FALSE;
FoundTarget = FALSE; }
InvalidOption = FALSE;
for (i = 1; i < argc; i++) for (i = 1; i < argc; i++)
{ {
if (argv[i][0] == L'-') if (argv[i][0] == L'-' || argv[i][0] == L'/')
{ {
switch (argv[i][1]) switch (argv[i][1])
{ {
case L't': NeverStop = TRUE; break; case L't': NeverStop = TRUE; break;
case L'a': ResolveAddresses = TRUE; break; case L'a': ResolveAddresses = TRUE; break;
case L'n': PingCount = GetULONG2(&argv[i][2], argv[i + 1], &i); break; case L'n':
if (i + 1 < argc)
PingCount = wcstoul(argv[++i], NULL, 0);
else
InvalidOption = TRUE;
break;
case L'l': case L'l':
DataSize = GetULONG2(&argv[i][2], argv[i + 1], &i); if (i + 1 < argc)
if (DataSize > ICMP_MAXSIZE - sizeof(ICMP_ECHO_PACKET) - sizeof(IPv4_HEADER))
{ {
FormatOutput(IDS_BAD_VALUE_OPTION_L, ICMP_MAXSIZE - \ DataSize = wcstoul(argv[++i], NULL, 0);
(int)sizeof(ICMP_ECHO_PACKET) - \
(int)sizeof(IPv4_HEADER)); if (DataSize > ICMP_MAXSIZE - sizeof(ICMP_ECHO_PACKET) - sizeof(IPv4_HEADER))
return FALSE; {
} FormatOutput(IDS_BAD_VALUE_OPTION_L, ICMP_MAXSIZE - \
(int)sizeof(ICMP_ECHO_PACKET) - \
(int)sizeof(IPv4_HEADER));
return FALSE;
}
} else
InvalidOption = TRUE;
break; break;
case L'f': DontFragment = TRUE; break; case L'f': DontFragment = TRUE; break;
case L'i': TTLValue = GetULONG2(&argv[i][2], argv[i + 1], &i); break; case L'i':
case L'v': TOSValue = GetULONG2(&argv[i][2], argv[i + 1], &i); break; if (i + 1 < argc)
case L'w': Timeout = GetULONG2(&argv[i][2], argv[i + 1], &i); break; TTLValue = wcstoul(argv[++i], NULL, 0);
else
InvalidOption = TRUE;
break;
case L'v':
if (i + 1 < argc)
TOSValue = wcstoul(argv[++i], NULL, 0);
else
InvalidOption = TRUE;
break;
case L'w':
if (i + 1 < argc)
Timeout = wcstoul(argv[++i], NULL, 0);
else
InvalidOption = TRUE;
break;
case '?':
Usage();
return FALSE;
default: default:
FormatOutput(IDS_BAD_OPTION, argv[i]); FormatOutput(IDS_BAD_OPTION, argv[i]);
Usage();
return FALSE; return FALSE;
} }
if (InvalidOption) if (InvalidOption)
@ -314,17 +300,12 @@ static BOOL ParseCmdline(int argc, LPWSTR argv[])
} }
} }
if ((!ShowUsage) && (!FoundTarget)) if (!FoundTarget)
{ {
FormatOutput(IDS_DEST_MUST_BE_SPECIFIED); FormatOutput(IDS_DEST_MUST_BE_SPECIFIED);
return FALSE; return FALSE;
} }
if (ShowUsage)
{
Usage();
return FALSE;
}
return TRUE; return TRUE;
} }

View file

@ -4,7 +4,7 @@
Name = Microsoft Visual Basic 6.0 Common Controls Name = Microsoft Visual Basic 6.0 Common Controls
Version = 6.0 Version = 6.0
Licence = Unknown Licence = Unknown
Description = File needed by some applications. Description = File needed by some applications. Contains: comctl32.ocx, mscomctl.ocx, advpack.dll.
Size = 914kB Size = 914kB
Category = 14 Category = 14
URLSite = http://www.microsoft.com/downloads/details.aspx?FamilyID=25437D98-51D0-41C1-BB14-64662F5F62FE&displaylang=en URLSite = http://www.microsoft.com/downloads/details.aspx?FamilyID=25437D98-51D0-41C1-BB14-64662F5F62FE&displaylang=en

View file

@ -0,0 +1,21 @@
; UTF-8
[Section]
Name = Double Commander
Version = 0.4.5.2 beta
Licence = GPL
Description = Double Commander is an open source file manager with two panels side by side. You need 7-Zip or a similar Utility to extract it.
Size = 6.71MB
Category = 12
URLSite = http://doublecmd.sourceforge.net/
URLDownload = http://ignum.dl.sourceforge.net/project/doublecmd/DC%20for%20Windows%2032%20bit/Double%20Commander%200.4.5.2%20beta/doublecmd-0.4.5.2.i386-win32.zip
CDPath = none
[Section.0415]
Description = Double Commander to menedżer plików, o otwartym źródle, z klasycznym układem dwóch paneli obok siebie. Do rozpakowania archiwum potrzebny jest 7-zip lub podobny program.
[Section.0419]
Description = Double Commander - это открытый двухпанельный файловый менеджер. Вам нужен 7-Zip или подобная утилита для его распаковки.
[Section.0422]
Description = Double Commander - це відкритий двопанельний файловий менеджер. Вам потрібен 7-Zip або подібна утиліта щоб розпакувати його.

View file

@ -2,53 +2,53 @@
[Section] [Section]
Name = Mozilla Firefox 3.6 Name = Mozilla Firefox 3.6
Version = 3.6.15 Version = 3.6.16
Licence = MPL/GPL/LGPL Licence = MPL/GPL/LGPL
Description = The most popular and one of the best free Web Browsers out there. Description = The most popular and one of the best free Web Browsers out there.
Size = 8.2M Size = 8.2M
Category = 5 Category = 5
URLSite = http://www.mozilla.com/en-US/ URLSite = http://www.mozilla.com/en-US/
URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.15/win32/en-US/Firefox%20Setup%203.6.15.exe URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.16/win32/en-US/Firefox%20Setup%203.6.16.exe
CDPath = none CDPath = none
[Section.0407] [Section.0407]
Description = Der populärste und einer der besten freien Webbrowser. Description = Der populärste und einer der besten freien Webbrowser.
Size = 8.1M Size = 8.1M
URLSite = http://www.mozilla-europe.org/de/ URLSite = http://www.mozilla-europe.org/de/
URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.15/win32/de/Firefox%20Setup%203.6.15.exe URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.16/win32/de/Firefox%20Setup%203.6.16.exe
[Section.040a] [Section.040a]
Description = El más popular y uno de los mejores navegadores web gratuitos que hay. Description = El más popular y uno de los mejores navegadores web gratuitos que hay.
Size = 8.1M Size = 8.1M
URLSite = http://www.mozilla-europe.org/es/ URLSite = http://www.mozilla-europe.org/es/
URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.15/win32/es-ES/Firefox%20Setup%203.6.15.exe URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.16/win32/es-ES/Firefox%20Setup%203.6.16.exe
[Section.040c] [Section.040c]
Description = Le navigateur web gratuit le plus populaire et l'un des meilleurs. Description = Le navigateur web gratuit le plus populaire et l'un des meilleurs.
Size = 8.1M Size = 8.1M
URLSite = http://www.mozilla-europe.org/fr/ URLSite = http://www.mozilla-europe.org/fr/
URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.15/win32/fr/Firefox%20Setup%203.6.15.exe URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.16/win32/fr/Firefox%20Setup%203.6.16.exe
[Section.0414] [Section.0414]
Description = Mest populære og best også gratis nettleserene der ute. Description = Mest populære og best også gratis nettleserene der ute.
Size = 8.1M Size = 8.1M
URLSite = http://www.mozilla-europe.org/no/ URLSite = http://www.mozilla-europe.org/no/
URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.15/win32/nb-NO/Firefox%20Setup%203.6.15.exe URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.16/win32/nb-NO/Firefox%20Setup%203.6.16.exe
[Section.0415] [Section.0415]
Description = Najpopularniejsza i jedna z najlepszych darmowych przeglądarek internetowych. Description = Najpopularniejsza i jedna z najlepszych darmowych przeglądarek internetowych.
Size = 8.9M Size = 8.9M
URLSite = http://www.mozilla-europe.org/pl/ URLSite = http://www.mozilla-europe.org/pl/
URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.15/win32/pl/Firefox%20Setup%203.6.15.exe URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.16/win32/pl/Firefox%20Setup%203.6.16.exe
[Section.0419] [Section.0419]
Description = Один из самых популярных и лучших бесплатных браузеров. Description = Один из самых популярных и лучших бесплатных браузеров.
Size = 8.5M Size = 8.5M
URLSite = http://www.mozilla-europe.org/ru/ URLSite = http://www.mozilla-europe.org/ru/
URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.15/win32/ru/Firefox%20Setup%203.6.15.exe URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.16/win32/ru/Firefox%20Setup%203.6.16.exe
[Section.0422] [Section.0422]
Description = Найпопулярніший та один з кращих безплатних веб-браузерів. Description = Найпопулярніший та один з кращих безплатних веб-браузерів.
Size = 8.5M Size = 8.5M
URLSite = http://www.mozilla-europe.org/uk/ URLSite = http://www.mozilla-europe.org/uk/
URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.15/win32/uk/Firefox%20Setup%203.6.15.exe URLDownload = http://mozilla.cdn.leaseweb.com/firefox/releases/3.6.16/win32/uk/Firefox%20Setup%203.6.16.exe

View file

@ -1,27 +0,0 @@
; UTF-8
[Section]
Name = Go-OO
Version = 3.2.1-11
Licence = LGPL
Description = Open Source Office Suite, based on Open Office, but way better.
Size = 181.0MB
Category = 6
URLSite = http://www.go-oo.org/
URLDownload = http://go-oo.mirrorbrain.org/stable/win32/3.2.1/GoOo-3.2.1-11.exe
CDPath = none
[Section.0407]
Description = Open Source Office Suite, basierend auf Open Office, aber viel besser.
[Section.040a]
Description = La suite de ofimática de código abierto.
[Section.040c]
Description = Suite bureautique open source basée sur Open Office, mais bien meilleure.
[Section.0415]
Description = Otwarty pakiet biurowy, bazujący na Open Office, ale znacznie lepszy.
[Section.0422]
Description = Відкритий офісний пакет.

View file

@ -2,13 +2,13 @@
[Section] [Section]
Name = LibreOffice Name = LibreOffice
Version = 3.3.1 Version = 3.3.2
Licence = LGPL Licence = LGPL
Description = Former called OpenOffice. Open Source Office Suite. Description = Former called OpenOffice. Open Source Office Suite.
Size = 213.4MB Size = 214.0MB
Category = 6 Category = 6
URLSite = http://www.documentfoundation.org/ URLSite = http://www.documentfoundation.org/
URLDownload = http://download.documentfoundation.org/libreoffice/stable/3.3.1/win/x86/LibO_3.3.1_Win_x86_install_multi.exe URLDownload = http://download.documentfoundation.org/libreoffice/stable/3.3.2/win/x86/LibO_3.3.2_Win_x86_install_multi.exe
CDPath = none CDPath = none
[Section.0407] [Section.0407]

View file

@ -4,7 +4,7 @@
Name = OLE Viewer and Microsoft Foundation Classes version 4 Name = OLE Viewer and Microsoft Foundation Classes version 4
Version = 4.0 Version = 4.0
Licence = Unknown Licence = Unknown
Description = MFC 4 is needed by some applications. Description = MFC 4 is needed by some applications. Contains: mfc40.dll, msvcrt40.dll.
Size = 865kB Size = 865kB
Category = 14 Category = 14
URLSite = http://support.microsoft.com/kb/122244/ URLSite = http://support.microsoft.com/kb/122244/

View file

@ -2,13 +2,13 @@
[Section] [Section]
Name = Miranda IM Name = Miranda IM
Version = 0.9.17 Version = 0.9.18
Licence = GPL Licence = GPL
Description = Open source multiprotocol instant messaging application - May not work completely. Description = Open source multiprotocol instant messaging application - May not work completely.
Size = 3.0MB Size = 3.0MB
Category = 5 Category = 5
URLSite = http://www.miranda-im.org/ URLSite = http://www.miranda-im.org/
URLDownload = http://miranda.googlecode.com/files/miranda-im-v0.9.17-unicode.exe URLDownload = http://miranda.googlecode.com/files/miranda-im-v0.9.18-unicode.exe
CDPath = none CDPath = none
[Section.0407] [Section.0407]

View file

@ -4,11 +4,11 @@
Name = Microsoft XML 3 Name = Microsoft XML 3
Version = 3.0 Version = 3.0
Licence = Unknown Licence = Unknown
Description = MSXML3 is needed for some MSI Installers. Description = MSXML3 is needed for some MSI Installers. Contains: msxml3.dll, msxml3a.dll, msxml3r.dll.
Size = 1.0MB Size = 1.0MB
Category = 14 Category = 14
URLSite = http://www.microsoft.com/downloads/details.aspx?FamilyID=28494391-052B-42FF-9674-F752BDCA9582&displaylang=en URLSite = http://www.microsoft.com/downloads/details.aspx?FamilyID=28494391-052B-42FF-9674-F752BDCA9582&displaylang=en
URLDownload = http://download.microsoft.com/download/8/8/8/888f34b7-4f54-4f06-8dac-fa29b19f33dd/msxml3.msi URLDownload = ftp://ftp.uni-rostock.de/pub/tools/microsoft/XML/US/msxml3.msi
CDPath = none CDPath = none
[Section.0407] [Section.0407]

View file

@ -2,13 +2,13 @@
[Section] [Section]
Name = SciTE Name = SciTE
Version = 2.24 Version = 2.25
Licence = Freeware Licence = Freeware
Description = SciTE is a SCIntilla based Text Editor. Originally built to demonstrate Scintilla, it has grown to be a generally useful editor with facilities for building and running programs. Description = SciTE is a SCIntilla based Text Editor. Originally built to demonstrate Scintilla, it has grown to be a generally useful editor with facilities for building and running programs.
Size = 0.6M Size = 0.6M
Category = 7 Category = 7
URLSite = http://www.scintilla.org/ URLSite = http://www.scintilla.org/
URLDownload = http://kent.dl.sourceforge.net/project/scintilla/SciTE/2.24/Sc224.exe URLDownload = http://kent.dl.sourceforge.net/project/scintilla/SciTE/2.25/Sc225.exe
CDPath = none CDPath = none
[Section.0407] [Section.0407]

View file

@ -2,36 +2,36 @@
[Section] [Section]
Name = Mozilla SeaMonkey Name = Mozilla SeaMonkey
Version = 2.0.12 Version = 2.0.13
Licence = MPL/GPL/LGPL Licence = MPL/GPL/LGPL
Description = Mozilla Suite is alive. This is the one and only Browser, Mail, Chat, and Composer bundle you will ever need. Description = Mozilla Suite is alive. This is the one and only Browser, Mail, Chat, and Composer bundle you will ever need.
Size = 10.2MB Size = 10.2MB
Category = 5 Category = 5
URLSite = http://www.seamonkey-project.org/ URLSite = http://www.seamonkey-project.org/
URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.12/win32/en-US/SeaMonkey%20Setup%202.0.12.exe URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.13/win32/en-US/SeaMonkey%20Setup%202.0.13.exe
CDPath = none CDPath = none
[Section.0407] [Section.0407]
Description = Mozilla Suite lebt. Dies ist das einzige Browser-, Mail-, Chat- and Composerwerkzeug-Bundle welches Sie benötigen. Description = Mozilla Suite lebt. Dies ist das einzige Browser-, Mail-, Chat- and Composerwerkzeug-Bundle welches Sie benötigen.
Size = 10.1MB Size = 10.1MB
URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.12/win32/de/SeaMonkey%20Setup%202.0.12.exe URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.13/win32/de/SeaMonkey%20Setup%202.0.13.exe
[Section.040a] [Section.040a]
Description = La suite de Mozilla está viva. Es el primero y único navegador web, gestor de correo, lector de noticias, Chat y editor HTML que necesitarás. Description = La suite de Mozilla está viva. Es el primero y único navegador web, gestor de correo, lector de noticias, Chat y editor HTML que necesitarás.
Size = 10.1MB Size = 10.1MB
URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.12/win32/es-ES/SeaMonkey%20Setup%202.0.12.exe URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.13/win32/es-ES/SeaMonkey%20Setup%202.0.13.exe
[Section.040c] [Section.040c]
Description = La suite Mozilla est en vie. Ceci est le seul et l'unique package navigateur, client mail, client chat et composer dont vous aurez besoin. Description = La suite Mozilla est en vie. Ceci est le seul et l'unique package navigateur, client mail, client chat et composer dont vous aurez besoin.
Size = 10.1MB Size = 10.1MB
URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.12/win32/fr/SeaMonkey%20Setup%202.0.12.exe URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.13/win32/fr/SeaMonkey%20Setup%202.0.13.exe
[Section.0415] [Section.0415]
Description = Pakiet Mozilla żyje. W zestawie: przeglądarka, klient poczty, IRC oraz Edytor HTML - wszystko, czego potrzebujesz. Description = Pakiet Mozilla żyje. W zestawie: przeglądarka, klient poczty, IRC oraz Edytor HTML - wszystko, czego potrzebujesz.
Size = 11.0MB Size = 11.0MB
URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.12/win32/pl/SeaMonkey%20Setup%202.0.12.exe URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.13/win32/pl/SeaMonkey%20Setup%202.0.13.exe
[Section.0419] [Section.0419]
Description = Продолжение Mozilla Suite. Включает браузер, почтовый клиент, IRC-клиент и HTML-редактор. Description = Продолжение Mozilla Suite. Включает браузер, почтовый клиент, IRC-клиент и HTML-редактор.
Size = 10.5MB Size = 10.5MB
URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.12/win32/ru/SeaMonkey%20Setup%202.0.12.exe URLDownload = http://releases.mozilla.org/pub/mozilla.org/seamonkey/releases/2.0.13/win32/ru/SeaMonkey%20Setup%202.0.13.exe

View file

@ -4,7 +4,7 @@
Name = Microsoft Tahoma Font Name = Microsoft Tahoma Font
Version = 1.0 Version = 1.0
Licence = Unknown Licence = Unknown
Description = Tahoma Font pack needed by some apps (Steam). Description = Tahoma Font pack needed by some apps (Steam). Contains: Tahoma.tff, Tahomabd.ttf.
Size = 305kB Size = 305kB
Category = 14 Category = 14
URLSite = http://support.microsoft.com/ URLSite = http://support.microsoft.com/

View file

@ -4,7 +4,7 @@
Name = Visual Basic 5 Runtime Name = Visual Basic 5 Runtime
Version = 5.0 Version = 5.0
Licence = Unknown Licence = Unknown
Description = Visual Basic 5 Runtime. Description = Visual Basic 5 Runtime. Contains: advpack.dll, asycfilt.dll, comcat.dll, msvbvm50.dll, oleaut32.dll, olepro32.dll.
Size = 970kB Size = 970kB
Category = 14 Category = 14
URLSite = http://support.microsoft.com/kb/180071/ URLSite = http://support.microsoft.com/kb/180071/

View file

@ -4,7 +4,7 @@
Name = Visual Basic 6 Runtime Name = Visual Basic 6 Runtime
Version = 6.0 Version = 6.0
Licence = Unknown Licence = Unknown
Description = Visual Basic 6 Runtime. Description = Visual Basic 6 Runtime. Contains: advpack.dll, asycfilt.dll, comcat.dll, msvbvm60.dll, oleaut32.dll, olepro32.dll.
Size = 1.0MB Size = 1.0MB
Category = 14 Category = 14
URLSite = http://support.microsoft.com/kb/192461/ URLSite = http://support.microsoft.com/kb/192461/

View file

@ -1,32 +0,0 @@
; UTF-8
[Section]
Name = Microsoft Visual C++ 2005 Redistributable Package
Version = 7.0
Licence = Unknown
Description = Visual Studio 2005 Runtime.
Size = 2.6MB
Category = 14
URLSite = http://www.microsoft.com/Downloads/details.aspx?displaylang=en&FamilyID=32bc1bee-a3f9-4c13-9c99-220b62a191ee
URLDownload = http://download.microsoft.com/download/6/B/B/6BB661D6-A8AE-4819-B79F-236472F6070C/vcredist_x86.exe
CDPath = none
[Section.0407]
Licence = Unbekannt
Description = Visual Studio 2005 Laufzeitsystem.
[Section.040a]
Licence = Desconocida
Description = Librerias Visual Studio 2005.
[Section.040c]
Licence = Inconnue
Description = Bibliothèque Visual Studio 2005.
[Section.0415]
Licence = Nieznana
Description = Biblioteki uruchomieniowe Visual Studio 2005.
[Section.0422]
Licence = Невідома
Description = Бібліотеки Visual Studio 2005.

View file

@ -4,7 +4,7 @@
Name = Microsoft Visual C++ 2005 SP1 Redistributable Package Name = Microsoft Visual C++ 2005 SP1 Redistributable Package
Version = 7.1 Version = 7.1
Licence = Unknown Licence = Unknown
Description = Visual Studio 2005 Runtime SP1. Description = Visual Studio 2005 Runtime SP1. Contains: atl80.dll, mfc80.dll, mfcm80.dll, mfcm80u.dll, msdia80.dll, msvcm80.dll, msvcp80.dll, msvcr80.dll, vcomp.dll.
Size = 2.6MB Size = 2.6MB
Category = 14 Category = 14
URLSite = http://www.microsoft.com/downloads/details.aspx?FamilyID=200b2fd9-ae1a-4a14-984d-389c36f85647&displaylang=en URLSite = http://www.microsoft.com/downloads/details.aspx?FamilyID=200b2fd9-ae1a-4a14-984d-389c36f85647&displaylang=en

View file

@ -1,32 +0,0 @@
; UTF-8
[Section]
Name = Microsoft Visual C++ 2008 Redistributable Package
Version = 8.0
Licence = Unknown
Description = Visual Studio 2008 Runtime.
Size = 4.3MB
Category = 14
URLSite = http://www.microsoft.com/DOWNLOADS/details.aspx?FamilyID=9b2da534-3e03-4391-8a4d-074b9f2bc1bf&displaylang=en
URLDownload = http://download.microsoft.com/download/9/7/7/977B481A-7BA6-4E30-AC40-ED51EB2028F2/vcredist_x86.exe
CDPath = none
[Section.0407]
Licence = Unbekannt
Description = Visual Studio 2008 Laufzeitsystem.
[Section.040a]
Licence = Desconocida
Description = Librerias Visual Studio 2008.
[Section.040c]
Licence = Inconnue
Description = Bibliothèque Visual Studio 2008.
[Section.0415]
Licence = Nieznana
Description = Biblioteki uruchomieniowe Visual Studio 2008.
[Section.0422]
Licence = Невідома
Description = Бібліотеки Visual Studio 2008.

View file

@ -4,7 +4,7 @@
Name = Microsoft Visual C++ 2008 SP1 Redistributable Package Name = Microsoft Visual C++ 2008 SP1 Redistributable Package
Version = 8.0 Version = 8.0
Licence = Unknown Licence = Unknown
Description = Visual Studio 2008 SP1 Runtime. Description = Visual Studio 2008 SP1 Runtime. Contains: atl90.dll, mfc90.dll, mfc90u.dll, mfcm90.dll, mfcm90u.dll, msdia90.dll, msvcm90.dll, msvcp90.dll, msvcr90.dll, vcomp90.dll.
Size = 4.0MB Size = 4.0MB
Category = 14 Category = 14
URLSite = http://www.microsoft.com/downloads/details.aspx?familyid=A5C84275-3B97-4AB7-A40D-3802B2AF5FC2&displaylang=en URLSite = http://www.microsoft.com/downloads/details.aspx?familyid=A5C84275-3B97-4AB7-A40D-3802B2AF5FC2&displaylang=en

View file

@ -4,7 +4,7 @@
Name = Microsoft Visual C++ 6 Redistributable Package Name = Microsoft Visual C++ 6 Redistributable Package
Version = 6.0 Version = 6.0
Licence = Unknown Licence = Unknown
Description = Visual Studio 6 Runtime. Description = Visual Studio 6 Runtime. Contains: advpack.dll, asycfilt.dll, atla.dll, atlu.dll, comcat.dll, mfc42.dll, mfc42u.dll, msvcirt.dll, msvcp60.dll, msvcrt.dll, oleaut32.dll, olepro32.dll.
Size = 1.7MB Size = 1.7MB
Category = 14 Category = 14
URLSite = http://support.microsoft.com/kb/259403/ URLSite = http://support.microsoft.com/kb/259403/

View file

@ -2,13 +2,13 @@
[Section] [Section]
Name = VLC media player Name = VLC media player
Version = 1.1.7 Version = 1.1.8
Licence = GPL Licence = GPL
Description = A media player. Description = A media player.
Size = 19.4MB Size = 19.6MB
Category = 1 Category = 1
URLSite = http://www.videolan.org/vlc/ URLSite = http://www.videolan.org/vlc/
URLDownload = http://kent.dl.sourceforge.net/project/vlc/1.1.7/win32/vlc-1.1.7-win32.exe URLDownload = http://kent.dl.sourceforge.net/project/vlc/1.1.8/win32/vlc-1.1.8-win32.exe
CDPath = none CDPath = none
[Section.0407] [Section.0407]

View file

@ -189,7 +189,7 @@ SndMixerQueryConnections(PSND_MIXER Mixer,
MIXER_GETLINEINFOF_SOURCE); MIXER_GETLINEINFOF_SOURCE);
if (Result == MMSYSERR_NOERROR) if (Result == MMSYSERR_NOERROR)
{ {
LPMIXERCONTROL Controls; LPMIXERCONTROL Controls = NULL;
PSND_MIXER_CONNECTION Con; PSND_MIXER_CONNECTION Con;
DPRINT("++ Source: %ws\n", LineInfo.szName); DPRINT("++ Source: %ws\n", LineInfo.szName);

View file

@ -680,10 +680,10 @@ FormatTime(TCHAR *lpTime, LPSYSTEMTIME dt)
{ {
case 0: /* 12 hour format */ case 0: /* 12 hour format */
default: default:
return _stprintf(lpTime,_T("%02d%c%02u%c"), return _stprintf(lpTime,_T("%02d%c%02u %cM"),
(dt->wHour == 0 ? 12 : (dt->wHour <= 12 ? dt->wHour : dt->wHour - 12)), (dt->wHour == 0 ? 12 : (dt->wHour <= 12 ? dt->wHour : dt->wHour - 12)),
cTimeSeparator, cTimeSeparator,
dt->wMinute, (dt->wHour <= 11 ? _T('a') : _T('p'))); dt->wMinute, (dt->wHour <= 11 ? _T('A') : _T('P')));
break; break;
case 1: /* 24 hour format */ case 1: /* 24 hour format */

File diff suppressed because it is too large Load diff

View file

@ -381,8 +381,8 @@ BEGIN
IDS_DESKTOPBAR_SETTINGS "W³aœciwoœci pulpitu" IDS_DESKTOPBAR_SETTINGS "W³aœciwoœci pulpitu"
IDS_DESKTOP "Pulpit" IDS_DESKTOP "Pulpit"
IDS_TASKBAR "Pasek zadañ" IDS_TASKBAR "Pasek zadañ"
IDS_NAMECOLUMN "Name" IDS_NAMECOLUMN "Nazwa"
IDS_PATHCOLUMN "Path" IDS_PATHCOLUMN "Ścieżka"
IDS_MENUCOLUMN "Menu path" IDS_MENUCOLUMN "Menu path"
END END

View file

@ -125,7 +125,7 @@ ScmWriteDependencies(HKEY hServiceKey,
lpDst = lpGroupDeps; lpDst = lpGroupDeps;
while (*lpSrc != 0) while (*lpSrc != 0)
{ {
dwLength = wcslen(lpSrc); dwLength = wcslen(lpSrc) + 1;
if (*lpSrc == SC_GROUP_IDENTIFIERW) if (*lpSrc == SC_GROUP_IDENTIFIERW)
{ {
lpSrc++; lpSrc++;
@ -157,21 +157,37 @@ ScmWriteDependencies(HKEY hServiceKey,
*lpDst = 0; *lpDst = 0;
dwServiceLength++; dwServiceLength++;
dwError = RegSetValueExW(hServiceKey, if (dwGroupLength > 1)
L"DependOnGroup", {
0, dwError = RegSetValueExW(hServiceKey,
REG_MULTI_SZ, L"DependOnGroup",
(LPBYTE)lpGroupDeps, 0,
dwGroupLength * sizeof(WCHAR)); REG_MULTI_SZ,
(LPBYTE)lpGroupDeps,
dwGroupLength * sizeof(WCHAR));
}
else
{
RegDeleteValueW(hServiceKey,
L"DependOnGroup");
}
if (dwError == ERROR_SUCCESS) if (dwError == ERROR_SUCCESS)
{ {
dwError = RegSetValueExW(hServiceKey, if (dwServiceLength > 1)
L"DependOnService", {
0, dwError = RegSetValueExW(hServiceKey,
REG_MULTI_SZ, L"DependOnService",
(LPBYTE)lpServiceDeps, 0,
dwServiceLength * sizeof(WCHAR)); REG_MULTI_SZ,
(LPBYTE)lpServiceDeps,
dwServiceLength * sizeof(WCHAR));
}
else
{
RegDeleteValueW(hServiceKey,
L"DependOnService");
}
} }
HeapFree(GetProcessHeap(), 0, lpGroupDeps); HeapFree(GetProcessHeap(), 0, lpGroupDeps);

View file

@ -7,6 +7,7 @@
* Use ReactOS forum PM or IRC to contact me * Use ReactOS forum PM or IRC to contact me
* http://www.reactos.org * http://www.reactos.org
* IRC: irc.freenode.net #reactos-pl; * IRC: irc.freenode.net #reactos-pl;
* update by Saibamen saibamenppl@gmail.com (29.03.2011)
*/ */
LANGUAGE LANG_POLISH, SUBLANG_DEFAULT LANGUAGE LANG_POLISH, SUBLANG_DEFAULT
@ -217,11 +218,11 @@ END
STRINGTABLE DISCARDABLE STRINGTABLE DISCARDABLE
BEGIN BEGIN
IDS_COLOR_4BIT "16 kolorów (4 Bity)" IDS_COLOR_4BIT "16 kolorów"
IDS_COLOR_8BIT "256 kolorów (8 Bitów)" IDS_COLOR_8BIT "256 kolorów"
IDS_COLOR_16BIT "65,536 kolorów (16 Bitów)" IDS_COLOR_16BIT "High Color (16 Bitów)"
IDS_COLOR_24BIT "16,777,216 kolorów (24 Bitów)" IDS_COLOR_24BIT "True Color (24 Bitów)"
IDS_COLOR_32BIT "16,777,216 kolorów (32 Bity)" IDS_COLOR_32BIT "True Color (32 Bity)"
IDS_PIXEL "%lux%lu pikseli" IDS_PIXEL "%lux%lu pikseli"
END END

View file

@ -139,7 +139,7 @@ InitGroupMembersList(HWND hwndDlg,
pUserBuffer[i].usri20_comment); pUserBuffer[i].usri20_comment);
} }
NetApiBufferFree(&pUserBuffer); NetApiBufferFree(pUserBuffer);
/* No more data left */ /* No more data left */
if (netStatus != ERROR_MORE_DATA) if (netStatus != ERROR_MORE_DATA)

View file

@ -77,7 +77,7 @@ UpdateGroupsList(HWND hwndListView)
pBuffer[i].lgrpi1_comment); pBuffer[i].lgrpi1_comment);
} }
NetApiBufferFree(&pBuffer); NetApiBufferFree(pBuffer);
/* No more data left */ /* No more data left */
if (netStatus != ERROR_MORE_DATA) if (netStatus != ERROR_MORE_DATA)

View file

@ -432,7 +432,7 @@ InitUserGroupsList(HWND hwndDlg)
pBuffer[i].lgrpi1_comment); pBuffer[i].lgrpi1_comment);
} }
NetApiBufferFree(&pBuffer); NetApiBufferFree(pBuffer);
/* No more data left */ /* No more data left */
if (netStatus != ERROR_MORE_DATA) if (netStatus != ERROR_MORE_DATA)

View file

@ -441,7 +441,7 @@ UpdateUsersList(HWND hwndListView)
pBuffer[i].usri20_comment); pBuffer[i].usri20_comment);
} }
NetApiBufferFree(&pBuffer); NetApiBufferFree(pBuffer);
/* No more data left */ /* No more data left */
if (netStatus != ERROR_MORE_DATA) if (netStatus != ERROR_MORE_DATA)

View file

@ -75,7 +75,7 @@
;@ stdcall LdrDestroyOutOfProcessImage ;@ stdcall LdrDestroyOutOfProcessImage
@ stdcall LdrDisableThreadCalloutsForDll(long) @ stdcall LdrDisableThreadCalloutsForDll(long)
@ stdcall LdrEnumResources(ptr ptr long ptr ptr) @ stdcall LdrEnumResources(ptr ptr long ptr ptr)
;@ stdcall LdrEnumerateLoadedModules @ stdcall LdrEnumerateLoadedModules(long ptr long)
;@ stdcall LdrFindCreateProcessManifest ; 5.1 and 5.2 only ;@ stdcall LdrFindCreateProcessManifest ; 5.1 and 5.2 only
@ stdcall LdrFindEntryForAddress(ptr ptr) @ stdcall LdrFindEntryForAddress(ptr ptr)
@ stdcall LdrFindResourceDirectory_U(long ptr long ptr) @ stdcall LdrFindResourceDirectory_U(long ptr long ptr)

View file

@ -15,9 +15,6 @@
/* GLOBALS *******************************************************************/ /* GLOBALS *******************************************************************/
#define LDR_LOCK_HELD 0x2
#define LDR_LOCK_FREE 0x1
LONG LdrpLoaderLockAcquisitonCount; LONG LdrpLoaderLockAcquisitonCount;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
@ -38,7 +35,7 @@ LdrUnlockLoaderLock(IN ULONG Flags,
if (Flags & ~1) if (Flags & ~1)
{ {
/* Flags are invalid, check how to fail */ /* Flags are invalid, check how to fail */
if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS) if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS)
{ {
/* The caller wants us to raise status */ /* The caller wants us to raise status */
RtlRaiseStatus(STATUS_INVALID_PARAMETER_1); RtlRaiseStatus(STATUS_INVALID_PARAMETER_1);
@ -60,7 +57,7 @@ LdrUnlockLoaderLock(IN ULONG Flags,
DPRINT1("LdrUnlockLoaderLock() called with an invalid cookie!\n"); DPRINT1("LdrUnlockLoaderLock() called with an invalid cookie!\n");
/* Invalid cookie, check how to fail */ /* Invalid cookie, check how to fail */
if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS) if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS)
{ {
/* The caller wants us to raise status */ /* The caller wants us to raise status */
RtlRaiseStatus(STATUS_INVALID_PARAMETER_2); RtlRaiseStatus(STATUS_INVALID_PARAMETER_2);
@ -73,7 +70,7 @@ LdrUnlockLoaderLock(IN ULONG Flags,
} }
/* Ready to release the lock */ /* Ready to release the lock */
if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS) if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS)
{ {
/* Do a direct leave */ /* Do a direct leave */
RtlLeaveCriticalSection(&LdrpLoaderLock); RtlLeaveCriticalSection(&LdrpLoaderLock);
@ -118,11 +115,11 @@ LdrLockLoaderLock(IN ULONG Flags,
if (Cookie) *Cookie = 0; if (Cookie) *Cookie = 0;
/* Validate the flags */ /* Validate the flags */
if (Flags & ~(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS | if (Flags & ~(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS |
LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY)) LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY))
{ {
/* Flags are invalid, check how to fail */ /* Flags are invalid, check how to fail */
if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS) if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS)
{ {
/* The caller wants us to raise status */ /* The caller wants us to raise status */
RtlRaiseStatus(STATUS_INVALID_PARAMETER_1); RtlRaiseStatus(STATUS_INVALID_PARAMETER_1);
@ -136,7 +133,7 @@ LdrLockLoaderLock(IN ULONG Flags,
if (!Cookie) if (!Cookie)
{ {
/* No cookie check how to fail */ /* No cookie check how to fail */
if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS) if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS)
{ {
/* The caller wants us to raise status */ /* The caller wants us to raise status */
RtlRaiseStatus(STATUS_INVALID_PARAMETER_3); RtlRaiseStatus(STATUS_INVALID_PARAMETER_3);
@ -150,7 +147,7 @@ LdrLockLoaderLock(IN ULONG Flags,
if ((Flags & LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY) && !(Result)) if ((Flags & LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY) && !(Result))
{ {
/* No pointer to return the data to */ /* No pointer to return the data to */
if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS) if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS)
{ {
/* The caller wants us to raise status */ /* The caller wants us to raise status */
RtlRaiseStatus(STATUS_INVALID_PARAMETER_2); RtlRaiseStatus(STATUS_INVALID_PARAMETER_2);
@ -164,7 +161,7 @@ LdrLockLoaderLock(IN ULONG Flags,
if (InInit) return STATUS_SUCCESS; if (InInit) return STATUS_SUCCESS;
/* Check what locking semantic to use */ /* Check what locking semantic to use */
if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS) if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS)
{ {
/* Check if we should enter or simply try */ /* Check if we should enter or simply try */
if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY) if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY)
@ -173,13 +170,13 @@ LdrLockLoaderLock(IN ULONG Flags,
if (!RtlTryEnterCriticalSection(&LdrpLoaderLock)) if (!RtlTryEnterCriticalSection(&LdrpLoaderLock))
{ {
/* It's locked */ /* It's locked */
*Result = LDR_LOCK_HELD; *Result = LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_NOT_ACQUIRED;
goto Quickie; goto Quickie;
} }
else else
{ {
/* It worked */ /* It worked */
*Result = LDR_LOCK_FREE; *Result = LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_ACQUIRED;
} }
} }
else else
@ -188,7 +185,7 @@ LdrLockLoaderLock(IN ULONG Flags,
RtlEnterCriticalSection(&LdrpLoaderLock); RtlEnterCriticalSection(&LdrpLoaderLock);
/* See if result was requested */ /* See if result was requested */
if (Result) *Result = LDR_LOCK_FREE; if (Result) *Result = LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_ACQUIRED;
} }
/* Increase the acquisition count */ /* Increase the acquisition count */
@ -209,13 +206,13 @@ LdrLockLoaderLock(IN ULONG Flags,
if (!RtlTryEnterCriticalSection(&LdrpLoaderLock)) if (!RtlTryEnterCriticalSection(&LdrpLoaderLock))
{ {
/* It's locked */ /* It's locked */
*Result = LDR_LOCK_HELD; *Result = LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_NOT_ACQUIRED;
_SEH2_YIELD(return STATUS_SUCCESS); _SEH2_YIELD(return STATUS_SUCCESS);
} }
else else
{ {
/* It worked */ /* It worked */
*Result = LDR_LOCK_FREE; *Result = LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_ACQUIRED;
} }
} }
else else
@ -224,7 +221,7 @@ LdrLockLoaderLock(IN ULONG Flags,
RtlEnterCriticalSection(&LdrpLoaderLock); RtlEnterCriticalSection(&LdrpLoaderLock);
/* See if result was requested */ /* See if result was requested */
if (Result) *Result = LDR_LOCK_FREE; if (Result) *Result = LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_ACQUIRED;
} }
/* Increase the acquisition count */ /* Increase the acquisition count */
@ -530,4 +527,66 @@ LdrQueryProcessModuleInformation(IN PRTL_PROCESS_MODULES ModuleInformation,
return LdrQueryProcessModuleInformationEx(0, 0, ModuleInformation, Size, ReturnedSize); return LdrQueryProcessModuleInformationEx(0, 0, ModuleInformation, Size, ReturnedSize);
} }
NTSTATUS
NTAPI
LdrEnumerateLoadedModules(BOOLEAN ReservedFlag, PLDR_ENUM_CALLBACK EnumProc, PVOID Context)
{
PLIST_ENTRY ListHead, ListEntry;
PLDR_DATA_TABLE_ENTRY LdrEntry;
NTSTATUS Status;
ULONG Cookie;
BOOLEAN Stop = FALSE;
/* Check parameters */
if (ReservedFlag || !EnumProc) return STATUS_INVALID_PARAMETER;
/* Acquire the loader lock */
Status = LdrLockLoaderLock(0, NULL, &Cookie);
if (!NT_SUCCESS(Status)) return Status;
/* Loop all the modules and call enum proc */
ListHead = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
ListEntry = ListHead->Flink;
while (ListHead != ListEntry)
{
/* Get the entry */
LdrEntry = CONTAINING_RECORD(ListEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
/* Call the enumeration proc inside SEH */
_SEH2_TRY
{
EnumProc(LdrEntry, Context, &Stop);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Ignoring the exception */
} _SEH2_END;
/* Break if we were asked to stop enumeration */
if (Stop)
{
/* Release loader lock */
Status = LdrUnlockLoaderLock(0, Cookie);
/* Reset any successful status to STATUS_SUCCESS, but leave
failure to the caller */
if (NT_SUCCESS(Status))
Status = STATUS_SUCCESS;
/* Return any possible failure status */
return Status;
}
/* Advance to the next module */
ListEntry = ListEntry->Flink;
}
/* Release loader lock, it must succeed this time */
Status = LdrUnlockLoaderLock(0, Cookie);
ASSERT(NT_SUCCESS(Status));
/* Return success */
return STATUS_SUCCESS;
}
/* EOF */ /* EOF */

View file

@ -786,8 +786,8 @@ LdrpAllocateTls(VOID)
PVOID *TlsVector; PVOID *TlsVector;
/* Check if we have any entries */ /* Check if we have any entries */
if (LdrpNumberOfTlsEntries) if (!LdrpNumberOfTlsEntries)
return 0; return STATUS_SUCCESS;
/* Allocate the vector array */ /* Allocate the vector array */
TlsVector = RtlAllocateHeap(RtlGetProcessHeap(), TlsVector = RtlAllocateHeap(RtlGetProcessHeap(),

View file

@ -1350,7 +1350,7 @@ RtlpRaiseImportNotFound(CHAR *FuncName, ULONG Ordinal, PUNICODE_STRING DllName)
ULONG ErrorResponse; ULONG ErrorResponse;
ULONG_PTR ErrorParameters[2]; ULONG_PTR ErrorParameters[2];
ANSI_STRING ProcNameAnsi; ANSI_STRING ProcNameAnsi;
UNICODE_STRING ProcName; ANSI_STRING DllNameAnsi;
CHAR Buffer[8]; CHAR Buffer[8];
if (!FuncName) if (!FuncName)
@ -1360,16 +1360,16 @@ RtlpRaiseImportNotFound(CHAR *FuncName, ULONG Ordinal, PUNICODE_STRING DllName)
} }
RtlInitAnsiString(&ProcNameAnsi, FuncName); RtlInitAnsiString(&ProcNameAnsi, FuncName);
RtlAnsiStringToUnicodeString(&ProcName, &ProcNameAnsi, TRUE); RtlUnicodeStringToAnsiString(&DllNameAnsi, DllName, TRUE);
ErrorParameters[0] = (ULONG_PTR)&ProcName; ErrorParameters[0] = (ULONG_PTR)&ProcNameAnsi;
ErrorParameters[1] = (ULONG_PTR)DllName; ErrorParameters[1] = (ULONG_PTR)&DllNameAnsi;
NtRaiseHardError(STATUS_ENTRYPOINT_NOT_FOUND, NtRaiseHardError(STATUS_ENTRYPOINT_NOT_FOUND,
2, 2,
3, 3,
ErrorParameters, ErrorParameters,
OptionOk, OptionOk,
&ErrorResponse); &ErrorResponse);
RtlFreeUnicodeString(&ProcName); RtlFreeAnsiString(&DllNameAnsi);
} }
static NTSTATUS static NTSTATUS

View file

@ -519,3 +519,22 @@ RtlPcToFileHeader(IN PVOID PcValue,
*BaseOfImage = ImageBase; *BaseOfImage = ImageBase;
return ImageBase; return ImageBase;
} }
NTSYSAPI
NTSTATUS
NTAPI
RtlDosApplyFileIsolationRedirection_Ustr(
IN BOOLEAN Unknown,
IN PUNICODE_STRING OriginalName,
IN PUNICODE_STRING Extension,
IN OUT PUNICODE_STRING RedirectedName,
IN OUT PUNICODE_STRING RedirectedName2,
IN OUT PUNICODE_STRING *OriginalName2,
IN PVOID Unknown1,
IN PVOID Unknown2,
IN PVOID Unknown3
)
{
return STATUS_SXS_KEY_NOT_FOUND;
}

View file

@ -3988,7 +3988,7 @@ RegQueryValueExA(HKEY hKey,
LPDWORD lpcbData) LPDWORD lpcbData)
{ {
UNICODE_STRING ValueName; UNICODE_STRING ValueName;
UNICODE_STRING ValueData; LPWSTR lpValueBuffer;
LONG ErrorCode; LONG ErrorCode;
DWORD Length; DWORD Length;
DWORD Type; DWORD Type;
@ -4003,39 +4003,42 @@ RegQueryValueExA(HKEY hKey,
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
} }
Length = (lpcbData == NULL || lpData == NULL) ? 0 : *lpcbData * sizeof(WCHAR);
if (lpData) if (lpData)
{ {
ValueData.Length = 0; lpValueBuffer = RtlAllocateHeap(ProcessHeap,
ValueData.MaximumLength = (*lpcbData + 1) * sizeof(WCHAR); 0,
ValueData.Buffer = RtlAllocateHeap(ProcessHeap, Length + sizeof(WCHAR));
0, if (!lpValueBuffer)
ValueData.MaximumLength);
if (!ValueData.Buffer)
{ {
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
} }
} }
else else
{ {
ValueData.Buffer = NULL; lpValueBuffer = NULL;
ValueData.Length = 0;
ValueData.MaximumLength = 0;
if (lpcbData) if (lpcbData)
*lpcbData = 0; *lpcbData = 0;
} }
RtlCreateUnicodeStringFromAsciiz(&ValueName, if(!RtlCreateUnicodeStringFromAsciiz(&ValueName,
(LPSTR)lpValueName); (LPSTR)lpValueName))
{
ERR("RtlCreateUnicodeStringFromAsciiz failed!\n");
ErrorCode = ERROR_OUTOFMEMORY;
goto cleanup;
}
Length = (lpcbData == NULL) ? 0 : *lpcbData * sizeof(WCHAR);
ErrorCode = RegQueryValueExW(hKey, ErrorCode = RegQueryValueExW(hKey,
ValueName.Buffer, ValueName.Buffer,
lpReserved, lpReserved,
&Type, &Type,
(lpData == NULL) ? NULL : (LPBYTE)ValueData.Buffer, (LPBYTE)lpValueBuffer,
&Length); &Length);
TRACE("ErrorCode %lu\n", ErrorCode); TRACE("ErrorCode %lu\n", ErrorCode);
RtlFreeUnicodeString(&ValueName); RtlFreeUnicodeString(&ValueName);
if (ErrorCode == ERROR_SUCCESS || if (ErrorCode == ERROR_SUCCESS ||
@ -4044,9 +4047,9 @@ RegQueryValueExA(HKEY hKey,
if (is_string(Type)) if (is_string(Type))
{ {
if (ErrorCode == ERROR_SUCCESS && ValueData.Buffer != NULL) if (ErrorCode == ERROR_SUCCESS && lpValueBuffer != NULL)
{ {
Status = RtlUnicodeToMultiByteN((PCHAR)lpData, *lpcbData, &Index, (PWCHAR)ValueData.Buffer, Length); Status = RtlUnicodeToMultiByteN((PCHAR)lpData, *lpcbData, &Index, (PWCHAR)lpValueBuffer, Length);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
PCHAR szData = (PCHAR)lpData; PCHAR szData = (PCHAR)lpData;
@ -4063,7 +4066,7 @@ RegQueryValueExA(HKEY hKey,
Length = Length / sizeof(WCHAR); Length = Length / sizeof(WCHAR);
} }
else if (ErrorCode == ERROR_SUCCESS && ValueData.Buffer != NULL) else if (ErrorCode == ERROR_SUCCESS && lpValueBuffer != NULL)
{ {
if (*lpcbData < Length) if (*lpcbData < Length)
{ {
@ -4071,7 +4074,7 @@ RegQueryValueExA(HKEY hKey,
} }
else else
{ {
RtlMoveMemory(lpData, ValueData.Buffer, Length); RtlMoveMemory(lpData, lpValueBuffer, Length);
} }
} }
@ -4086,9 +4089,10 @@ RegQueryValueExA(HKEY hKey,
*lpType = Type; *lpType = Type;
} }
if (ValueData.Buffer != NULL) cleanup:
if (lpValueBuffer != NULL)
{ {
RtlFreeHeap(ProcessHeap, 0, ValueData.Buffer); RtlFreeHeap(ProcessHeap, 0, lpValueBuffer);
} }
return ErrorCode; return ErrorCode;

View file

@ -430,20 +430,22 @@ LsaLookupNames(IN LSA_HANDLE PolicyHandle,
OUT PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains, OUT PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains,
OUT PLSA_TRANSLATED_SID *Sids) OUT PLSA_TRANSLATED_SID *Sids)
{ {
LSAPR_TRANSLATED_SIDS TranslatedSids; LSAPR_TRANSLATED_SIDS TranslatedSids = {0, NULL};
ULONG MappedCount = 0; ULONG MappedCount = 0;
NTSTATUS Status; NTSTATUS Status;
TRACE("(%p,0x%08x,%p,%p,%p)\n", PolicyHandle, Count, Names, TRACE("(%p,0x%08x,%p,%p,%p)\n", PolicyHandle, Count, Names,
ReferencedDomains, Sids); ReferencedDomains, Sids);
if (ReferencedDomains == NULL || Sids == NULL)
return STATUS_INVALID_PARAMETER;
RpcTryExcept RpcTryExcept
{ {
*ReferencedDomains = NULL; *ReferencedDomains = NULL;
*Sids = NULL; *Sids = NULL;
TranslatedSids.Entries = Count; TranslatedSids.Entries = Count;
TranslatedSids.Sids = *Sids;
Status = LsarLookupNames((LSAPR_HANDLE)PolicyHandle, Status = LsarLookupNames((LSAPR_HANDLE)PolicyHandle,
Count, Count,
@ -458,9 +460,7 @@ LsaLookupNames(IN LSA_HANDLE PolicyHandle,
RpcExcept(EXCEPTION_EXECUTE_HANDLER) RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{ {
if (TranslatedSids.Sids != NULL) if (TranslatedSids.Sids != NULL)
{
MIDL_user_free(TranslatedSids.Sids); MIDL_user_free(TranslatedSids.Sids);
}
Status = I_RpcMapWin32Status(RpcExceptionCode()); Status = I_RpcMapWin32Status(RpcExceptionCode());
} }
@ -471,27 +471,56 @@ LsaLookupNames(IN LSA_HANDLE PolicyHandle,
/* /*
* @unimplemented * @implemented
*/ */
NTSTATUS NTSTATUS
WINAPI WINAPI
LsaLookupNames2( LsaLookupNames2(IN LSA_HANDLE PolicyHandle,
LSA_HANDLE PolicyHandle, IN ULONG Flags,
ULONG Flags, IN ULONG Count,
ULONG Count, IN PLSA_UNICODE_STRING Names,
PLSA_UNICODE_STRING Names, OUT PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains,
PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains, OUT PLSA_TRANSLATED_SID2 *Sids)
PLSA_TRANSLATED_SID2 *Sids)
{ {
FIXME("(%p,0x%08x,0x%08x,%p,%p,%p) stub\n", PolicyHandle, Flags, LSAPR_TRANSLATED_SIDS_EX2 TranslatedSids = {0, NULL};
Count, Names, ReferencedDomains, Sids); ULONG MappedCount = 0;
if (Names != NULL && Count > 0) NTSTATUS Status;
TRACE("(%p,0x%08x,0x%08x,%p,%p,%p) stub\n", PolicyHandle, Flags,
Count, Names, ReferencedDomains, Sids);
if (ReferencedDomains == NULL || Sids == NULL)
return STATUS_INVALID_PARAMETER;
RpcTryExcept
{ {
*ReferencedDomains = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(LSA_REFERENCED_DOMAIN_LIST)); *ReferencedDomains = NULL;
*Sids = RtlAllocateHeap(RtlGetProcessHeap(), 0, Count * sizeof(LSA_TRANSLATED_SID2)); *Sids = NULL;
return STATUS_SOME_NOT_MAPPED;
TranslatedSids.Entries = Count;
Status = LsarLookupNames3((LSAPR_HANDLE)PolicyHandle,
Count,
(PRPC_UNICODE_STRING)Names,
(PLSAPR_REFERENCED_DOMAIN_LIST *)ReferencedDomains,
&TranslatedSids,
LsapLookupWksta,
&MappedCount,
Flags,
2);
*Sids = (PLSA_TRANSLATED_SID2)TranslatedSids.Sids;
} }
return STATUS_NONE_MAPPED; RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
if (TranslatedSids.Sids != NULL)
MIDL_user_free(TranslatedSids.Sids);
Status = I_RpcMapWin32Status(RpcExceptionCode());
}
RpcEndExcept;
return Status;
} }
@ -762,6 +791,7 @@ LsaQueryDomainInformationPolicy(
return STATUS_NOT_IMPLEMENTED; return STATUS_NOT_IMPLEMENTED;
} }
/* /*
* @unimplemented * @unimplemented
*/ */

View file

@ -275,7 +275,7 @@ HGDIOBJ
FASTCALL FASTCALL
hGetPEBHandle(HANDLECACHETYPE Type, COLORREF cr) hGetPEBHandle(HANDLECACHETYPE Type, COLORREF cr)
{ {
int Number; int Number, Offset, MaxNum, GdiType;
HANDLE Lock; HANDLE Lock;
HGDIOBJ Handle = NULL; HGDIOBJ Handle = NULL;
@ -287,26 +287,58 @@ hGetPEBHandle(HANDLECACHETYPE Type, COLORREF cr)
Number = GdiHandleCache->ulNumHandles[Type]; Number = GdiHandleCache->ulNumHandles[Type];
if ( Number && Number <= CACHE_REGION_ENTRIES ) if (Type == hctBrushHandle)
{ {
if ( Type == hctRegionHandle) Offset = 0;
{ MaxNum = CACHE_BRUSH_ENTRIES;
PRGN_ATTR pRgn_Attr; GdiType = GDILoObjType_LO_BRUSH_TYPE;
HGDIOBJ *hPtr; }
hPtr = GdiHandleCache->Handle + CACHE_BRUSH_ENTRIES+CACHE_PEN_ENTRIES; else if (Type == hctPenHandle)
Handle = hPtr[Number - 1]; {
Offset = CACHE_BRUSH_ENTRIES;
MaxNum = CACHE_PEN_ENTRIES;
GdiType = GDILoObjType_LO_PEN_TYPE;
}
else if (Type == hctRegionHandle)
{
Offset = CACHE_BRUSH_ENTRIES+CACHE_PEN_ENTRIES;
MaxNum = CACHE_REGION_ENTRIES;
GdiType = GDILoObjType_LO_REGION_TYPE;
}
else // Font is not supported here.
{
return Handle;
}
if (GdiGetHandleUserData( Handle, GDI_OBJECT_TYPE_REGION, (PVOID) &pRgn_Attr)) if ( Number && Number <= MaxNum )
{ {
if (pRgn_Attr->AttrFlags & ATTR_CACHED) PBRUSH_ATTR pBrush_Attr;
HGDIOBJ *hPtr;
hPtr = GdiHandleCache->Handle + Offset;
Handle = hPtr[Number - 1];
if (GdiGetHandleUserData( Handle, GdiType, (PVOID) &pBrush_Attr))
{
if (pBrush_Attr->AttrFlags & ATTR_CACHED)
{
DPRINT("Get Handle! Type %d Count %d PEB 0x%x\n", Type, GdiHandleCache->ulNumHandles[Type], NtCurrentTeb()->ProcessEnvironmentBlock);
pBrush_Attr->AttrFlags &= ~ATTR_CACHED;
hPtr[Number - 1] = NULL;
GdiHandleCache->ulNumHandles[Type]--;
if ( Type == hctBrushHandle ) // Handle only brush.
{
if ( pBrush_Attr->lbColor != cr )
{ {
DPRINT("Get Handle! Count %d PEB 0x%x\n", GdiHandleCache->ulNumHandles[Type], NtCurrentTeb()->ProcessEnvironmentBlock); pBrush_Attr->lbColor = cr ;
pRgn_Attr->AttrFlags &= ~ATTR_CACHED; pBrush_Attr->AttrFlags |= ATTR_NEW_COLOR;
hPtr[Number - 1] = NULL;
GdiHandleCache->ulNumHandles[Type]--;
} }
} }
} }
}
else
{
Handle = NULL;
}
} }
(void)InterlockedExchangePointer((PVOID*)&GdiHandleCache->ulLock, Lock); (void)InterlockedExchangePointer((PVOID*)&GdiHandleCache->ulLock, Lock);
return Handle; return Handle;

View file

@ -234,6 +234,8 @@ CreateBrushIndirect(
break; break;
case BS_SOLID: case BS_SOLID:
/* hBrush = hGetPEBHandle(hctBrushHandle, LogBrush->lbColor);
if (!hBrush)*/
hBrush = NtGdiCreateSolidBrush(LogBrush->lbColor, 0); hBrush = NtGdiCreateSolidBrush(LogBrush->lbColor, 0);
break; break;

View file

@ -23,12 +23,34 @@ CreatePen(
int nWidth, int nWidth,
COLORREF crColor) COLORREF crColor)
{ {
/* FIXME Some part need be done in user mode */ /* HPEN hPen;
PBRUSH_ATTR Pen_Attr;
*/
if (nPenStyle < PS_SOLID) nPenStyle = PS_SOLID;
if (nPenStyle > PS_DASHDOTDOT) if (nPenStyle > PS_DASHDOTDOT)
{ {
if (nPenStyle == PS_NULL) return GetStockObject(NULL_PEN); if (nPenStyle == PS_NULL) return GetStockObject(NULL_PEN);
if (nPenStyle != PS_INSIDEFRAME) nPenStyle = PS_SOLID; if (nPenStyle != PS_INSIDEFRAME) nPenStyle = PS_SOLID;
} }
#if 0
hPen = hGetPEBHandle(hctPenHandle, nPenStyle);
if ( nWidth || nPenStyle || !hPen )
{
return NtGdiCreatePen(nPenStyle, nWidth, crColor, NULL);
}
if ((GdiGetHandleUserData( hPen, GDI_OBJECT_TYPE_PEN, (PVOID) &Pen_Attr)) &&
( Pen_Attr != NULL ))
{
if ( Pen_Attr->lbColor != crColor)
{
Pen_Attr->lbColor = crColor;
Pen_Attr->AttrFlags |= ATTR_NEW_COLOR;
}
return hPen;
}
DeleteObject(hPen);
#endif
return NtGdiCreatePen(nPenStyle, nWidth, crColor, NULL); return NtGdiCreatePen(nPenStyle, nWidth, crColor, NULL);
} }

View file

@ -28,6 +28,8 @@ DEBUG_CHANNEL(kernel32file);
UNICODE_STRING SystemDirectory; UNICODE_STRING SystemDirectory;
UNICODE_STRING WindowsDirectory; UNICODE_STRING WindowsDirectory;
UNICODE_STRING BaseDefaultPathAppend;
UNICODE_STRING BaseDefaultPath;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/

View file

@ -20,7 +20,7 @@
#include <debug.h> #include <debug.h>
DEBUG_CHANNEL(kernel32file); DEBUG_CHANNEL(kernel32file);
UNICODE_STRING DllDirectory = {0, 0, NULL}; UNICODE_STRING BaseDllDirectory = {0, 0, NULL};
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
@ -1079,35 +1079,35 @@ SetDllDirectoryW(
RtlInitUnicodeString(&PathName, lpPathName); RtlInitUnicodeString(&PathName, lpPathName);
RtlEnterCriticalSection(&DllLock); RtlEnterCriticalSection(&BaseDllDirectoryLock);
if(PathName.Length > 0) if(PathName.Length > 0)
{ {
if(PathName.Length + sizeof(WCHAR) <= DllDirectory.MaximumLength) if(PathName.Length + sizeof(WCHAR) <= BaseDllDirectory.MaximumLength)
{ {
RtlCopyUnicodeString(&DllDirectory, &PathName); RtlCopyUnicodeString(&BaseDllDirectory, &PathName);
} }
else else
{ {
RtlFreeUnicodeString(&DllDirectory); RtlFreeUnicodeString(&BaseDllDirectory);
if(!(DllDirectory.Buffer = (PWSTR)RtlAllocateHeap(RtlGetProcessHeap(), if(!(BaseDllDirectory.Buffer = (PWSTR)RtlAllocateHeap(RtlGetProcessHeap(),
0, 0,
PathName.Length + sizeof(WCHAR)))) PathName.Length + sizeof(WCHAR))))
{ {
RtlLeaveCriticalSection(&DllLock); RtlLeaveCriticalSection(&BaseDllDirectoryLock);
SetLastError(ERROR_NOT_ENOUGH_MEMORY); SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE; return FALSE;
} }
DllDirectory.Length = 0; BaseDllDirectory.Length = 0;
DllDirectory.MaximumLength = PathName.Length + sizeof(WCHAR); BaseDllDirectory.MaximumLength = PathName.Length + sizeof(WCHAR);
RtlCopyUnicodeString(&DllDirectory, &PathName); RtlCopyUnicodeString(&BaseDllDirectory, &PathName);
} }
} }
else else
{ {
RtlFreeUnicodeString(&DllDirectory); RtlFreeUnicodeString(&BaseDllDirectory);
} }
RtlLeaveCriticalSection(&DllLock); RtlLeaveCriticalSection(&BaseDllDirectoryLock);
return TRUE; return TRUE;
} }
@ -1144,10 +1144,10 @@ GetDllDirectoryW(
{ {
DWORD Ret; DWORD Ret;
RtlEnterCriticalSection(&DllLock); RtlEnterCriticalSection(&BaseDllDirectoryLock);
if(nBufferLength > 0) if(nBufferLength > 0)
{ {
Ret = DllDirectory.Length / sizeof(WCHAR); Ret = BaseDllDirectory.Length / sizeof(WCHAR);
if(Ret > nBufferLength - 1) if(Ret > nBufferLength - 1)
{ {
Ret = nBufferLength - 1; Ret = nBufferLength - 1;
@ -1155,16 +1155,16 @@ GetDllDirectoryW(
if(Ret > 0) if(Ret > 0)
{ {
RtlCopyMemory(lpBuffer, DllDirectory.Buffer, Ret * sizeof(WCHAR)); RtlCopyMemory(lpBuffer, BaseDllDirectory.Buffer, Ret * sizeof(WCHAR));
} }
lpBuffer[Ret] = L'\0'; lpBuffer[Ret] = L'\0';
} }
else else
{ {
/* include termination character, even if the string is empty! */ /* include termination character, even if the string is empty! */
Ret = (DllDirectory.Length / sizeof(WCHAR)) + 1; Ret = (BaseDllDirectory.Length / sizeof(WCHAR)) + 1;
} }
RtlLeaveCriticalSection(&DllLock); RtlLeaveCriticalSection(&BaseDllDirectoryLock);
return Ret; return Ret;
} }

View file

@ -91,9 +91,11 @@ extern HANDLE hProcessHeap;
extern HANDLE hBaseDir; extern HANDLE hBaseDir;
extern HMODULE hCurrentModule; extern HMODULE hCurrentModule;
extern RTL_CRITICAL_SECTION DllLock; extern RTL_CRITICAL_SECTION BaseDllDirectoryLock;
extern UNICODE_STRING DllDirectory; extern UNICODE_STRING BaseDllDirectory;
extern UNICODE_STRING BaseDefaultPath;
extern UNICODE_STRING BaseDefaultPathAppend;
extern LPTOP_LEVEL_EXCEPTION_FILTER GlobalTopLevelExceptionFilter; extern LPTOP_LEVEL_EXCEPTION_FILTER GlobalTopLevelExceptionFilter;
@ -211,6 +213,12 @@ BasepMapFile(IN LPCWSTR lpApplicationName,
OUT PHANDLE hSection, OUT PHANDLE hSection,
IN PUNICODE_STRING ApplicationName); IN PUNICODE_STRING ApplicationName);
LPWSTR
WINAPI
BasepGetDllPath(LPWSTR FullPath,
PVOID Environment);
PCODEPAGE_ENTRY FASTCALL PCODEPAGE_ENTRY FASTCALL
IntGetCodePageEntry(UINT CodePage); IntGetCodePageEntry(UINT CodePage);

View file

@ -3524,7 +3524,7 @@ SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,
{ {
BOOL Ret; BOOL Ret;
RtlEnterCriticalSection(&DllLock); RtlEnterCriticalSection(&BaseDllDirectoryLock);
if (Add) if (Add)
{ {
Ret = AddConsoleCtrlHandler(HandlerRoutine); Ret = AddConsoleCtrlHandler(HandlerRoutine);
@ -3534,7 +3534,7 @@ SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,
Ret = RemoveConsoleCtrlHandler(HandlerRoutine); Ret = RemoveConsoleCtrlHandler(HandlerRoutine);
} }
RtlLeaveCriticalSection(&DllLock); RtlLeaveCriticalSection(&BaseDllDirectoryLock);
return(Ret); return(Ret);
} }

View file

@ -5,6 +5,7 @@
* FILE: lib/kernel32/misc/dllmain.c * FILE: lib/kernel32/misc/dllmain.c
* PURPOSE: Initialization * PURPOSE: Initialization
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl) * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
* Aleksey Bragin (aleksey@reactos.org)
* UPDATE HISTORY: * UPDATE HISTORY:
* Created 01/11/98 * Created 01/11/98
*/ */
@ -21,6 +22,8 @@
extern UNICODE_STRING SystemDirectory; extern UNICODE_STRING SystemDirectory;
extern UNICODE_STRING WindowsDirectory; extern UNICODE_STRING WindowsDirectory;
WCHAR BaseDefaultPathBuffer[6140];
HANDLE hProcessHeap = NULL; HANDLE hProcessHeap = NULL;
HMODULE hCurrentModule = NULL; HMODULE hCurrentModule = NULL;
HANDLE hBaseDir = NULL; HANDLE hBaseDir = NULL;
@ -36,7 +39,7 @@ DllMain(HANDLE hInst,
LPVOID lpReserved); LPVOID lpReserved);
/* Critical section for various kernel32 data structures */ /* Critical section for various kernel32 data structures */
RTL_CRITICAL_SECTION DllLock; RTL_CRITICAL_SECTION BaseDllDirectoryLock;
RTL_CRITICAL_SECTION ConsoleLock; RTL_CRITICAL_SECTION ConsoleLock;
extern BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event); extern BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event);
@ -275,6 +278,9 @@ DllMain(HANDLE hDll,
/* Don't bother us for each thread */ /* Don't bother us for each thread */
LdrDisableThreadCalloutsForDll((PVOID)hDll); LdrDisableThreadCalloutsForDll((PVOID)hDll);
/* Initialize default path to NULL */
RtlInitUnicodeString(&BaseDefaultPath, NULL);
/* Setup the right Object Directory path */ /* Setup the right Object Directory path */
if (!SessionId) if (!SessionId)
{ {
@ -332,11 +338,25 @@ DllMain(HANDLE hDll,
SystemDirectory.MaximumLength); SystemDirectory.MaximumLength);
if(SystemDirectory.Buffer == NULL) if(SystemDirectory.Buffer == NULL)
{ {
DPRINT1("Failure allocating SystemDirectory buffer\n");
return FALSE; return FALSE;
} }
wcscpy(SystemDirectory.Buffer, WindowsDirectory.Buffer); wcscpy(SystemDirectory.Buffer, WindowsDirectory.Buffer);
wcscat(SystemDirectory.Buffer, L"\\System32"); wcscat(SystemDirectory.Buffer, L"\\System32");
/* Construct the default path (using the static buffer) */
_snwprintf(BaseDefaultPathBuffer, sizeof(BaseDefaultPathBuffer) / sizeof(WCHAR),
L".;%wZ;%wZ\\system;%wZ;", &SystemDirectory, &WindowsDirectory, &WindowsDirectory);
BaseDefaultPath.Buffer = BaseDefaultPathBuffer;
BaseDefaultPath.Length = wcslen(BaseDefaultPathBuffer) * sizeof(WCHAR);
BaseDefaultPath.MaximumLength = sizeof(BaseDefaultPathBuffer);
/* Use remaining part of the default path buffer for the append path */
BaseDefaultPathAppend.Buffer = (PWSTR)((ULONG_PTR)BaseDefaultPathBuffer + BaseDefaultPath.Length);
BaseDefaultPathAppend.Length = 0;
BaseDefaultPathAppend.MaximumLength = BaseDefaultPath.MaximumLength - BaseDefaultPath.Length;
/* Initialize command line */ /* Initialize command line */
InitCommandLines(); InitCommandLines();
@ -349,7 +369,7 @@ DllMain(HANDLE hDll,
} }
/* Initialize the DLL critical section */ /* Initialize the DLL critical section */
RtlInitializeCriticalSection(&DllLock); RtlInitializeCriticalSection(&BaseDllDirectoryLock);
/* Initialize the National Language Support routines */ /* Initialize the National Language Support routines */
if (!NlsInit()) if (!NlsInit())
@ -395,7 +415,7 @@ DllMain(HANDLE hDll,
ConsoleInitialized = FALSE; ConsoleInitialized = FALSE;
RtlDeleteCriticalSection (&ConsoleLock); RtlDeleteCriticalSection (&ConsoleLock);
} }
RtlDeleteCriticalSection (&DllLock); RtlDeleteCriticalSection (&BaseDllDirectoryLock);
/* Close object base directory */ /* Close object base directory */
NtClose(hBaseDir); NtClose(hBaseDir);

View file

@ -1,10 +1,10 @@
/* $Id$ /*
*
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT : ReactOS user mode libraries * PROJECT : ReactOS user mode libraries
* MODULE : kernel32.dll * MODULE : kernel32.dll
* FILE : reactos/lib/kernel32/misc/ldr.c * FILE : reactos/dll/win32/kernel32/misc/ldr.c
* AUTHOR : Ariadne * AUTHOR : Aleksey Bragin <aleksey@reactos.org>
* Ariadne
*/ */
#include <k32.h> #include <k32.h>
@ -22,8 +22,68 @@ typedef struct tagLOADPARMS32 {
extern BOOLEAN InWindows; extern BOOLEAN InWindows;
extern WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle; extern WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle;
#define BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_ERROR 1
#define BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_SUCCESS 2
#define BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_CONTINUE 3
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
DWORD
WINAPI
BasepGetModuleHandleExParameterValidation(DWORD dwFlags,
LPCWSTR lpwModuleName,
HMODULE *phModule)
{
/* Set phModule to 0 if it's not a NULL pointer */
if (phModule) *phModule = 0;
/* Check for invalid flags combination */
if (dwFlags & ~(GET_MODULE_HANDLE_EX_FLAG_PIN |
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT |
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS) ||
((dwFlags & GET_MODULE_HANDLE_EX_FLAG_PIN) &&
(dwFlags & GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT)) ||
(!lpwModuleName && (dwFlags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS))
)
{
BaseSetLastNTError(STATUS_INVALID_PARAMETER_1);
return BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_ERROR;
}
/* Check 2nd parameter */
if (!phModule)
{
BaseSetLastNTError(STATUS_INVALID_PARAMETER_2);
return BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_ERROR;
}
/* Return what we have according to the module name */
if (lpwModuleName)
{
return BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_CONTINUE;
}
/* No name given, so put ImageBaseAddress there */
*phModule = (HMODULE)NtCurrentPeb()->ImageBaseAddress;
return BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_SUCCESS;
}
PVOID
WINAPI
BasepMapModuleHandle(HMODULE hModule, BOOLEAN AsDataFile)
{
/* If no handle is provided - use current image base address */
if (!hModule) return NtCurrentPeb()->ImageBaseAddress;
/* Check if it's a normal or a datafile one */
if (LDR_IS_DATAFILE(hModule) && !AsDataFile)
return NULL;
/* It'a a normal DLL, just return its handle */
return hModule;
}
/** /**
* @name GetDllLoadPath * @name GetDllLoadPath
* *
@ -220,7 +280,7 @@ LoadLibraryExW (
HINSTANCE hInst; HINSTANCE hInst;
NTSTATUS Status; NTSTATUS Status;
PWSTR SearchPath; PWSTR SearchPath;
ULONG DllCharacteristics; ULONG DllCharacteristics = 0;
BOOL FreeString = FALSE; BOOL FreeString = FALSE;
(void)hFile; (void)hFile;
@ -349,27 +409,49 @@ GetProcAddress( HMODULE hModule, LPCSTR lpProcName )
BOOL WINAPI FreeLibrary(HINSTANCE hLibModule) BOOL WINAPI FreeLibrary(HINSTANCE hLibModule)
{ {
NTSTATUS Status; NTSTATUS Status;
PIMAGE_NT_HEADERS NtHeaders;
if (!hLibModule) if (LDR_IS_DATAFILE(hLibModule))
{ {
SetLastError(ERROR_INVALID_HANDLE); // FIXME: This SEH should go inside RtlImageNtHeader instead
return FALSE; _SEH2_TRY
{
/* This is a LOAD_LIBRARY_AS_DATAFILE module, check if it's a valid one */
NtHeaders = RtlImageNtHeader((PVOID)((ULONG_PTR)hLibModule & ~1));
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
NtHeaders = NULL;
} _SEH2_END
if (NtHeaders)
{
/* Unmap view */
Status = NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)((ULONG_PTR)hLibModule & ~1));
/* Unload alternate resource module */
LdrUnloadAlternateResourceModule(hLibModule);
}
else
Status = STATUS_INVALID_IMAGE_FORMAT;
}
else
{
/* Just unload it */
Status = LdrUnloadDll((PVOID)hLibModule);
} }
if ((ULONG_PTR)hLibModule & 1) /* Check what kind of status we got */
{
/* this is a LOAD_LIBRARY_AS_DATAFILE module */
char *ptr = (char *)hLibModule - 1;
return UnmapViewOfFile(ptr);
}
Status = LdrUnloadDll(hLibModule);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
SetLastErrorByStatus(Status); /* Set last error */
BaseSetLastNTError(Status);
/* Return failure */
return FALSE; return FALSE;
} }
/* Return success */
return TRUE; return TRUE;
} }
@ -379,12 +461,30 @@ BOOL WINAPI FreeLibrary(HINSTANCE hLibModule)
*/ */
VOID VOID
WINAPI WINAPI
FreeLibraryAndExitThread ( FreeLibraryAndExitThread(HMODULE hLibModule,
HMODULE hLibModule, DWORD dwExitCode)
DWORD dwExitCode
)
{ {
FreeLibrary(hLibModule); NTSTATUS Status;
if (LDR_IS_DATAFILE(hLibModule))
{
/* This is a LOAD_LIBRARY_AS_DATAFILE module */
if (RtlImageNtHeader((PVOID)((ULONG_PTR)hLibModule & ~1)))
{
/* Unmap view */
Status = NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)((ULONG_PTR)hLibModule & ~1));
/* Unload alternate resource module */
LdrUnloadAlternateResourceModule(hLibModule);
}
}
else
{
/* Just unload it */
Status = LdrUnloadDll((PVOID)hLibModule);
}
/* Exit thread */
ExitThread(dwExitCode); ExitThread(dwExitCode);
} }
@ -394,123 +494,292 @@ FreeLibraryAndExitThread (
*/ */
DWORD DWORD
WINAPI WINAPI
GetModuleFileNameA ( GetModuleFileNameA(HINSTANCE hModule,
HINSTANCE hModule, LPSTR lpFilename,
LPSTR lpFilename, DWORD nSize)
DWORD nSize
)
{ {
ANSI_STRING FileName; UNICODE_STRING FilenameW;
PLIST_ENTRY ModuleListHead; ANSI_STRING FilenameA;
PLIST_ENTRY Entry; NTSTATUS Status;
PLDR_DATA_TABLE_ENTRY Module; DWORD Length = 0, LengthToCopy;
PPEB Peb;
ULONG Length = 0;
Peb = NtCurrentPeb (); /* Allocate a unicode buffer */
RtlEnterCriticalSection (Peb->LoaderLock); FilenameW.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, nSize * sizeof(WCHAR));
if (!FilenameW.Buffer)
{
BaseSetLastNTError(STATUS_NO_MEMORY);
return 0;
}
if (hModule == NULL) /* Call unicode API */
hModule = Peb->ImageBaseAddress; FilenameW.Length = GetModuleFileNameW(hModule, FilenameW.Buffer, nSize) * sizeof(WCHAR);
FilenameW.MaximumLength = FilenameW.Length + sizeof(WCHAR);
ModuleListHead = &Peb->Ldr->InLoadOrderModuleList; if (FilenameW.Length)
Entry = ModuleListHead->Flink; {
/* Convert to ansi string */
Status = BasepUnicodeStringTo8BitString(&FilenameA, &FilenameW, TRUE);
if (!NT_SUCCESS(Status))
{
/* Set last error, free string and retun failure */
BaseSetLastNTError(Status);
RtlFreeUnicodeString(&FilenameW);
return 0;
}
while (Entry != ModuleListHead) /* Calculate size to copy */
{ Length = min(nSize, FilenameA.Length);
Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
if (Module->DllBase == (PVOID)hModule)
{
Length = min(nSize, Module->FullDllName.Length / sizeof(WCHAR));
FileName.Length = 0;
FileName.MaximumLength = (USHORT)Length * sizeof(WCHAR);
FileName.Buffer = lpFilename;
/* convert unicode string to ansi (or oem) */ /* Include terminating zero */
if (bIsFileApiAnsi) if (nSize > Length)
RtlUnicodeStringToAnsiString (&FileName, LengthToCopy = Length + 1;
&Module->FullDllName, else
FALSE); LengthToCopy = nSize;
else
RtlUnicodeStringToOemString (&FileName,
&Module->FullDllName,
FALSE);
if (Length < nSize) /* Now copy back to the caller amount he asked */
lpFilename[Length] = '\0'; RtlMoveMemory(lpFilename, FilenameA.Buffer, LengthToCopy);
else
SetLastErrorByStatus (STATUS_BUFFER_TOO_SMALL);
RtlLeaveCriticalSection (Peb->LoaderLock); /* Free ansi filename */
return Length; RtlFreeAnsiString(&FilenameA);
} }
Entry = Entry->Flink; /* Free unicode filename */
} RtlFreeHeap(RtlGetProcessHeap(), 0, FilenameW.Buffer);
SetLastErrorByStatus (STATUS_DLL_NOT_FOUND); /* Return length copied */
RtlLeaveCriticalSection (Peb->LoaderLock); return Length;
return 0;
} }
/* /*
* @implemented * @implemented
*/ */
DWORD DWORD
WINAPI WINAPI
GetModuleFileNameW ( GetModuleFileNameW(HINSTANCE hModule,
HINSTANCE hModule, LPWSTR lpFilename,
LPWSTR lpFilename, DWORD nSize)
DWORD nSize
)
{ {
UNICODE_STRING FileName; PLIST_ENTRY ModuleListHead, Entry;
PLIST_ENTRY ModuleListHead; PLDR_DATA_TABLE_ENTRY Module;
PLIST_ENTRY Entry; ULONG Length = 0;
PLDR_DATA_TABLE_ENTRY Module; ULONG Cookie;
PPEB Peb; PPEB Peb;
ULONG Length = 0;
Peb = NtCurrentPeb (); hModule = BasepMapModuleHandle(hModule, FALSE);
RtlEnterCriticalSection (Peb->LoaderLock);
if (hModule == NULL) /* Upscale nSize from chars to bytes */
hModule = Peb->ImageBaseAddress; nSize *= sizeof(WCHAR);
ModuleListHead = &Peb->Ldr->InLoadOrderModuleList; _SEH2_TRY
Entry = ModuleListHead->Flink; {
while (Entry != ModuleListHead) /* We don't use per-thread cur dir now */
{ //PRTL_PERTHREAD_CURDIR PerThreadCurdir = (PRTL_PERTHREAD_CURDIR)teb->NtTib.SubSystemTib;
Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
if (Module->DllBase == (PVOID)hModule) Peb = NtCurrentPeb ();
{
Length = min(nSize, Module->FullDllName.Length / sizeof(WCHAR));
FileName.Length = 0;
FileName.MaximumLength = (USHORT) Length * sizeof(WCHAR);
FileName.Buffer = lpFilename;
RtlCopyUnicodeString (&FileName, /* Acquire a loader lock */
&Module->FullDllName); LdrLockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, NULL, &Cookie);
if (Length < nSize)
lpFilename[Length] = L'\0';
else
SetLastErrorByStatus (STATUS_BUFFER_TOO_SMALL);
RtlLeaveCriticalSection (Peb->LoaderLock); /* Traverse the module list */
ModuleListHead = &Peb->Ldr->InLoadOrderModuleList;
Entry = ModuleListHead->Flink;
while (Entry != ModuleListHead)
{
Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
return Length; /* Check if this is the requested module */
} if (Module->DllBase == (PVOID)hModule)
{
/* Calculate size to copy */
Length = min(nSize, Module->FullDllName.MaximumLength);
Entry = Entry->Flink; /* Copy contents */
} RtlMoveMemory(lpFilename, Module->FullDllName.Buffer, Length);
SetLastErrorByStatus (STATUS_DLL_NOT_FOUND); /* Subtract a terminating zero */
RtlLeaveCriticalSection (Peb->LoaderLock); if (Length == Module->FullDllName.MaximumLength)
Length -= sizeof(WCHAR);
return 0; /* Break out of the loop */
break;
}
/* Advance to the next entry */
Entry = Entry->Flink;
}
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
BaseSetLastNTError(_SEH2_GetExceptionCode());
Length = 0;
} _SEH2_END
/* Release the loader lock */
LdrUnlockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, Cookie);
return Length / sizeof(WCHAR);
}
HMODULE
WINAPI
GetModuleHandleForUnicodeString(PUNICODE_STRING ModuleName)
{
NTSTATUS Status;
PVOID Module;
LPWSTR DllPath;
/* Try to get a handle with a magic value of 1 for DllPath */
Status = LdrGetDllHandle((LPWSTR)1, NULL, ModuleName, &Module);
/* If that succeeded - we're done */
if (NT_SUCCESS(Status)) return Module;
/* If not, then the path should be computed */
DllPath = BasepGetDllPath(NULL, 0);
/* Call LdrGetHandle() again providing the computed DllPath
and wrapped into SEH */
_SEH2_TRY
{
Status = LdrGetDllHandle(DllPath, NULL, ModuleName, &Module);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Fail with the SEH error */
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
/* Free the DllPath */
RtlFreeHeap(RtlGetProcessHeap(), 0, DllPath);
/* In case of error set last win32 error and return NULL */
if (!NT_SUCCESS(Status))
{
DPRINT("Failure acquiring DLL module '%wZ' handle, Status 0x%08X\n", ModuleName, Status);
SetLastErrorByStatus(Status);
Module = 0;
}
/* Return module */
return (HMODULE)Module;
}
BOOLEAN
WINAPI
BasepGetModuleHandleExW(BOOLEAN NoLock, DWORD dwPublicFlags, LPCWSTR lpwModuleName, HMODULE *phModule)
{
DWORD Cookie;
NTSTATUS Status = STATUS_SUCCESS, Status2;
HANDLE hModule = 0;
UNICODE_STRING ModuleNameU;
DWORD dwValid;
BOOLEAN Redirected = FALSE; // FIXME
/* Validate parameters */
dwValid = BasepGetModuleHandleExParameterValidation(dwPublicFlags, lpwModuleName, phModule);
ASSERT(dwValid == BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_CONTINUE);
/* Acquire lock if necessary */
if (!NoLock)
{
Status = LdrLockLoaderLock(0, NULL, &Cookie);
if (!NT_SUCCESS(Status))
{
/* Fail */
SetLastErrorByStatus(Status);
if (phModule) *phModule = 0;
return Status;
}
}
if (!(dwPublicFlags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS))
{
/* Create a unicode string out of module name */
RtlInitUnicodeString(&ModuleNameU, lpwModuleName);
// FIXME: Do some redirected DLL stuff?
if (Redirected)
{
UNIMPLEMENTED;
}
if (!hModule)
{
hModule = GetModuleHandleForUnicodeString(&ModuleNameU);
if (!hModule)
{
/* Last error is already set, so just return failure by setting status */
Status = STATUS_DLL_NOT_FOUND;
goto quickie;
}
}
}
else
{
/* Perform Pc to file header to get module instance */
hModule = (HMODULE)RtlPcToFileHeader((PVOID)lpwModuleName,
(PVOID*)&hModule);
/* Check if it succeeded */
if (!hModule)
{
/* Set "dll not found" status and quit */
Status = STATUS_DLL_NOT_FOUND;
goto quickie;
}
}
/* Check if changing reference is not forbidden */
if (!(dwPublicFlags & GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT))
{
/* Add reference to this DLL */
Status = LdrAddRefDll((dwPublicFlags & GET_MODULE_HANDLE_EX_FLAG_PIN) ? LDR_PIN_MODULE : 0,
hModule);
}
/* Set last error in case of failure */
if (!NT_SUCCESS(Status))
SetLastErrorByStatus(Status);
quickie:
/* Unlock loader lock if it was acquired */
if (!NoLock)
{
Status2 = LdrUnlockLoaderLock(0, Cookie);
ASSERT(NT_SUCCESS(Status2));
}
/* Set the module handle to the caller */
if (phModule) *phModule = hModule;
/* Return TRUE on success and FALSE otherwise */
return NT_SUCCESS(Status);
}
/*
* @implemented
*/
HMODULE
WINAPI
GetModuleHandleA(LPCSTR lpModuleName)
{
PUNICODE_STRING ModuleNameW;
PTEB pTeb = NtCurrentTeb();
/* Check if we have no name to convert */
if (!lpModuleName)
return ((HMODULE)pTeb->ProcessEnvironmentBlock->ImageBaseAddress);
/* Convert module name to unicode */
ModuleNameW = Basep8BitStringToStaticUnicodeString(lpModuleName);
/* Call W version if conversion was successful */
if (ModuleNameW)
return GetModuleHandleW(ModuleNameW->Buffer);
/* Return failure */
return 0;
} }
@ -519,61 +788,26 @@ GetModuleFileNameW (
*/ */
HMODULE HMODULE
WINAPI WINAPI
GetModuleHandleA ( LPCSTR lpModuleName ) GetModuleHandleW(LPCWSTR lpModuleName)
{ {
ANSI_STRING ModuleName; HMODULE hModule;
NTSTATUS Status; NTSTATUS Status;
PTEB pTeb = NtCurrentTeb();
if (lpModuleName == NULL) /* If current module is requested - return it right away */
{ if (!lpModuleName)
return ((HMODULE)pTeb->ProcessEnvironmentBlock->ImageBaseAddress); return ((HMODULE)NtCurrentPeb()->ImageBaseAddress);
}
RtlInitAnsiString(&ModuleName, lpModuleName); /* Use common helper routine */
Status = BasepGetModuleHandleExW(TRUE,
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
lpModuleName,
&hModule);
Status = RtlAnsiStringToUnicodeString(&pTeb->StaticUnicodeString, /* If it wasn't successful - return 0 */
&ModuleName, if (!NT_SUCCESS(Status)) hModule = 0;
FALSE);
if (NT_SUCCESS(Status)) /* Return the handle */
{ return hModule;
return GetModuleHandleW(pTeb->StaticUnicodeString.Buffer);
}
SetLastErrorByStatus(Status);
return FALSE;
}
/*
* @implemented
*/
HMODULE
WINAPI
GetModuleHandleW (LPCWSTR lpModuleName)
{
UNICODE_STRING ModuleName;
PVOID BaseAddress;
NTSTATUS Status;
if (lpModuleName == NULL)
return ((HMODULE)NtCurrentPeb()->ImageBaseAddress);
RtlInitUnicodeString (&ModuleName,
(LPWSTR)lpModuleName);
Status = LdrGetDllHandle (0,
0,
&ModuleName,
&BaseAddress);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus (Status);
return NULL;
}
return ((HMODULE)BaseAddress);
} }
@ -583,64 +817,31 @@ GetModuleHandleW (LPCWSTR lpModuleName)
BOOL BOOL
WINAPI WINAPI
GetModuleHandleExW(IN DWORD dwFlags, GetModuleHandleExW(IN DWORD dwFlags,
IN LPCWSTR lpModuleName OPTIONAL, IN LPCWSTR lpwModuleName OPTIONAL,
OUT HMODULE* phModule) OUT HMODULE* phModule)
{ {
HMODULE hModule;
NTSTATUS Status; NTSTATUS Status;
DWORD dwValid;
BOOL Ret = FALSE; BOOL Ret = FALSE;
if (phModule == NULL || /* Validate parameters */
((dwFlags & (GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT)) == dwValid = BasepGetModuleHandleExParameterValidation(dwFlags, lpwModuleName, phModule);
(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT)))
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (lpModuleName == NULL) /* If result is invalid parameter - return failure */
{ if (dwValid == BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_ERROR) return FALSE;
hModule = NtCurrentPeb()->ImageBaseAddress;
}
else
{
if (dwFlags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS)
{
hModule = (HMODULE)RtlPcToFileHeader((PVOID)lpModuleName,
(PVOID*)&hModule);
if (hModule == NULL)
{
SetLastErrorByStatus(STATUS_DLL_NOT_FOUND);
}
}
else
{
hModule = GetModuleHandleW(lpModuleName);
}
}
if (hModule != NULL) /* If result is 2, there is no need to do anything - return success. */
{ if (dwValid == BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_SUCCESS) return TRUE;
if (!(dwFlags & GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT))
{
Status = LdrAddRefDll((dwFlags & GET_MODULE_HANDLE_EX_FLAG_PIN) ? LDR_PIN_MODULE : 0,
hModule);
if (NT_SUCCESS(Status)) /* Use common helper routine */
{ Status = BasepGetModuleHandleExW(FALSE,
Ret = TRUE; dwFlags,
} lpwModuleName,
else phModule);
{
SetLastErrorByStatus(Status); /* Return TRUE in case of success */
hModule = NULL; if (NT_SUCCESS(Status)) Ret = TRUE;
}
}
else
Ret = TRUE;
}
*phModule = hModule;
return Ret; return Ret;
} }
@ -650,41 +851,52 @@ GetModuleHandleExW(IN DWORD dwFlags,
BOOL BOOL
WINAPI WINAPI
GetModuleHandleExA(IN DWORD dwFlags, GetModuleHandleExA(IN DWORD dwFlags,
IN LPCSTR lpModuleName OPTIONAL, IN LPCSTR lpModuleName OPTIONAL,
OUT HMODULE* phModule) OUT HMODULE* phModule)
{ {
ANSI_STRING ModuleName; PUNICODE_STRING lpModuleNameW;
LPCWSTR lpModuleNameW; DWORD dwValid;
BOOL Ret = FALSE;
NTSTATUS Status; NTSTATUS Status;
BOOL Ret;
PTEB pTeb = NtCurrentTeb(); /* Validate parameters */
dwValid = BasepGetModuleHandleExParameterValidation(dwFlags, (LPCWSTR)lpModuleName, phModule);
/* If result is invalid parameter - return failure */
if (dwValid == BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_ERROR) return FALSE;
/* If result is 2, there is no need to do anything - return success. */
if (dwValid == BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_SUCCESS) return TRUE;
/* Check if we don't need to convert the name */
if (dwFlags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS) if (dwFlags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS)
{ {
lpModuleNameW = (LPCWSTR)lpModuleName; /* Call the extended version of the API without conversion */
Status = BasepGetModuleHandleExW(FALSE,
dwFlags,
(LPCWSTR)lpModuleName,
phModule);
} }
else else
{ {
RtlInitAnsiString(&ModuleName, lpModuleName); /* Convert module name to unicode */
lpModuleNameW = Basep8BitStringToStaticUnicodeString(lpModuleName);
Status = RtlAnsiStringToUnicodeString(&pTeb->StaticUnicodeString, /* Return FALSE if conversion failed */
&ModuleName, if (!lpModuleNameW) return FALSE;
FALSE);
if (!NT_SUCCESS(Status)) /* Call the extended version of the API */
{ Status = BasepGetModuleHandleExW(FALSE,
SetLastErrorByStatus(Status); dwFlags,
return FALSE; lpModuleNameW->Buffer,
} phModule);
lpModuleNameW = pTeb->StaticUnicodeString.Buffer;
} }
Ret = GetModuleHandleExW(dwFlags, /* If result was successful - return true */
lpModuleNameW, if (NT_SUCCESS(Status))
phModule); Ret = TRUE;
/* Return result */
return Ret; return Ret;
} }

View file

@ -14,6 +14,10 @@
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
UNICODE_STRING BasePathVariableName = RTL_CONSTANT_STRING(L"PATH");
UNICODE_STRING BaseDefaultPath;
PLDR_DATA_TABLE_ENTRY BasepExeLdrEntry;
#define CMD_STRING L"cmd /c " #define CMD_STRING L"cmd /c "
extern __declspec(noreturn) extern __declspec(noreturn)
@ -352,13 +356,230 @@ BasepDuplicateAndWriteHandle(IN HANDLE ProcessHandle,
} }
} }
VOID
NTAPI
BasepLocateExeLdrEntry(IN PLDR_DATA_TABLE_ENTRY Entry,
IN PVOID Context,
OUT BOOLEAN *StopEnumeration)
{
/* Make sure we get Entry, Context and valid StopEnumeration pointer */
ASSERT(Entry);
ASSERT(Context);
ASSERT(StopEnumeration);
/* If entry is already found - signal to stop */
if (BasepExeLdrEntry)
{
/* Signal to stop enumeration and return */
*StopEnumeration = TRUE;
return;
}
/* We don't have a exe ldr entry, so try to see if this one is ours
by matching base address */
if (Entry->DllBase == Context)
{
/* It matches, so remember the ldr entry */
BasepExeLdrEntry = Entry;
/* And stop enumeration */
*StopEnumeration = TRUE;
}
}
LPWSTR
WINAPI
BasepGetProcessPath(DWORD Reserved,
LPWSTR FullPath,
PVOID Environment)
{
NTSTATUS Status;
LPWSTR AllocatedPath = NULL, ch;
ULONG DefaultLength = BaseDefaultPath.Length;
ULONG AppLength = 0;
UNICODE_STRING EnvPath;
LPWSTR NamePtr;
LPWSTR PathBuffer;
BOOLEAN SecondAttempt = FALSE;
PPEB Peb = NtCurrentPeb();
if (!Environment) RtlAcquirePebLock();
/* Query PATH env var into append path */
Status = RtlQueryEnvironmentVariable_U(Environment,
&BasePathVariableName,
&BaseDefaultPathAppend);
if (NT_SUCCESS(Status))
{
/* Add up PATH environment length */
DefaultLength += BaseDefaultPathAppend.Length;
}
else if (Status == STATUS_BUFFER_TOO_SMALL)
{
/* We have to allocate path dynamically */
AllocatedPath = RtlAllocateHeap(RtlGetProcessHeap(), 0, BaseDefaultPathAppend.Length + sizeof(UNICODE_NULL));
if (AllocatedPath)
{
/* Set up EnvPath */
EnvPath.Buffer = AllocatedPath;
EnvPath.Length = BaseDefaultPathAppend.Length + sizeof(UNICODE_NULL);
EnvPath.MaximumLength = EnvPath.Length;
/* Query PATH env var into newly allocated path */
Status = RtlQueryEnvironmentVariable_U(Environment,
&BasePathVariableName,
&EnvPath);
if (NT_SUCCESS(Status))
{
DefaultLength += EnvPath.Length;
}
else
{
/* Free newly allocated path, it didn't work */
RtlFreeHeap(RtlGetProcessHeap(), 0, AllocatedPath);
AllocatedPath = NULL;
Status = STATUS_NO_MEMORY;
}
}
}
secondattempt:
if (!FullPath)
{
/* Initialize BasepExeLdrEntry if necessary */
if (!BasepExeLdrEntry)
LdrEnumerateLoadedModules(0, BasepLocateExeLdrEntry, Peb->ImageBaseAddress);
DPRINT("Found BasepExeLdrEntry %wZ\n", &BasepExeLdrEntry->FullDllName);
/* Set name pointer to the full dll path */
NamePtr = BasepExeLdrEntry->FullDllName.Buffer;
}
else
{
/* Set name pointer to the provided path */
NamePtr = FullPath;
}
/* Determine application path length */
if (NamePtr)
{
ch = NamePtr;
while (*ch)
{
/* Check if there is a slash */
if (*ch == L'\\')
{
/* Update app length */
AppLength = (ULONG_PTR)ch - (ULONG_PTR)NamePtr + sizeof(WCHAR);
}
ch++;
}
}
/* Now check, if we found a valid path in the provided full path */
if (!AppLength && FullPath && !SecondAttempt)
{
/* We were provided with a bad full path, retry again using just this app's path */
FullPath = NULL;
SecondAttempt = TRUE;
goto secondattempt;
}
/* Allocate the path buffer */
PathBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, DefaultLength + AppLength + 2*sizeof(WCHAR));
if (!PathBuffer)
{
/* Fail */
if (!Environment) RtlReleasePebLock();
if (AllocatedPath) RtlFreeHeap(RtlGetProcessHeap(), 0, AllocatedPath);
return NULL;
}
/* Copy contents there */
if (AppLength)
{
/* Remove trailing slashes if it's not root dir */
if (AppLength != 3*sizeof(WCHAR))
AppLength -= sizeof(WCHAR);
/* Copy contents */
RtlMoveMemory(PathBuffer, NamePtr, AppLength);
}
/* Release the lock */
if (!Environment) RtlReleasePebLock();
/* Finish preparing the path string */
NamePtr = &PathBuffer[AppLength / sizeof(WCHAR)];
/* Put a separating ";" if something was added */
if (AppLength)
{
*NamePtr = L';';
NamePtr++;
}
if (AllocatedPath)
{
/* Dynamically allocated env path, copy from the static buffer,
concatenate with dynamic buffer and free it */
RtlMoveMemory(NamePtr, BaseDefaultPath.Buffer, BaseDefaultPath.Length);
RtlMoveMemory(&NamePtr[BaseDefaultPath.Length / sizeof(WCHAR)], AllocatedPath, EnvPath.Length);
/* Free it */
RtlFreeHeap(RtlGetProcessHeap(), 0, AllocatedPath);
}
else
{
/* Static env path string, copy directly from BaseDefaultPath */
RtlMoveMemory(NamePtr, BaseDefaultPath.Buffer, DefaultLength);
}
/* Null terminate the string */
NamePtr[DefaultLength / sizeof(WCHAR)] = 0;
return PathBuffer;
}
LPWSTR LPWSTR
WINAPI WINAPI
BasepGetDllPath(LPWSTR FullPath, BasepGetDllPath(LPWSTR FullPath,
PVOID Environment) PVOID Environment)
{ {
/* FIXME: Not yet implemented */ #if 0
return NULL; LPWSTR DllPath = NULL;
/* Acquire DLL directory lock */
RtlEnterCriticalSection(&BaseDllDirectoryLock);
/* Check if we have a base dll directory */
if (BaseDllDirectory.Buffer)
{
/* Then get process path */
DllPath = BasepGetProcessPath(0, FullPath, Environment);
/* Release DLL directory lock */
RtlLeaveCriticalSection(&BaseDllDirectoryLock);
/* Return dll path */
return DllPath;
}
/* Release DLL directory lock */
RtlLeaveCriticalSection(&BaseDllDirectoryLock);
/* There is no base DLL directory */
UNIMPLEMENTED;
/* Return dll path */
return DllPath;
#else
return BasepGetProcessPath(0, FullPath, Environment);
#endif
} }
VOID VOID

View file

@ -554,7 +554,7 @@ NTSTATUS WINAPI LsarLookupNames(
for (i = 0; i < Count; i++) for (i = 0; i < Count; i++)
{ {
OutputSids[i].Use = SidTypeWellKnownGroup; OutputSids[i].Use = SidTypeWellKnownGroup;
OutputSids[i].RelativeId = DOMAIN_ALIAS_RID_ADMINS; OutputSids[i].RelativeId = DOMAIN_USER_RID_ADMIN; //DOMAIN_ALIAS_RID_ADMINS;
OutputSids[i].DomainIndex = i; OutputSids[i].DomainIndex = i;
} }
@ -1185,7 +1185,7 @@ NTSTATUS WINAPI LsarLookupNames2(
DWORD Count, DWORD Count,
PRPC_UNICODE_STRING Names, PRPC_UNICODE_STRING Names,
PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains, PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
PLSAPR_TRANSLATED_SID_EX TranslatedSids, PLSAPR_TRANSLATED_SIDS_EX TranslatedSids,
LSAP_LOOKUP_LEVEL LookupLevel, LSAP_LOOKUP_LEVEL LookupLevel,
DWORD *MappedCount, DWORD *MappedCount,
DWORD LookupOptions, DWORD LookupOptions,
@ -1287,14 +1287,132 @@ NTSTATUS WINAPI LsarLookupNames3(
DWORD Count, DWORD Count,
PRPC_UNICODE_STRING Names, PRPC_UNICODE_STRING Names,
PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains, PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
PLSAPR_TRANSLATED_SID_EX2 TranslatedSids, PLSAPR_TRANSLATED_SIDS_EX2 TranslatedSids,
LSAP_LOOKUP_LEVEL LookupLevel, LSAP_LOOKUP_LEVEL LookupLevel,
DWORD *MappedCount, DWORD *MappedCount,
DWORD LookupOptions, DWORD LookupOptions,
DWORD ClientRevision) DWORD ClientRevision)
{ {
UNIMPLEMENTED; SID_IDENTIFIER_AUTHORITY IdentifierAuthority = {SECURITY_NT_AUTHORITY};
return STATUS_NOT_IMPLEMENTED; static const UNICODE_STRING DomainName = RTL_CONSTANT_STRING(L"DOMAIN");
PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer = NULL;
PLSAPR_TRANSLATED_SID_EX2 SidsBuffer = NULL;
ULONG SidsBufferLength;
ULONG DomainSidLength;
ULONG AccountSidLength;
PSID DomainSid;
PSID AccountSid;
ULONG i;
NTSTATUS Status;
TRACE("LsarLookupNames3(%p, %lu, %p, %p, %p, %d, %p, %lu, %lu)\n",
PolicyHandle, Count, Names, ReferencedDomains, TranslatedSids,
LookupLevel, MappedCount, LookupOptions, ClientRevision);
if (Count == 0)
return STATUS_NONE_MAPPED;
TranslatedSids->Entries = Count;
TranslatedSids->Sids = NULL;
*ReferencedDomains = NULL;
SidsBufferLength = Count * sizeof(LSAPR_TRANSLATED_SID_EX2);
SidsBuffer = MIDL_user_allocate(SidsBufferLength);
if (SidsBuffer == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
for (i = 0; i < Count; i++)
{
SidsBuffer[i].Use = SidTypeUser;
SidsBuffer[i].Sid = NULL;
SidsBuffer[i].DomainIndex = -1;
SidsBuffer[i].Flags = 0;
}
DomainsBuffer = MIDL_user_allocate(sizeof(LSAPR_REFERENCED_DOMAIN_LIST));
if (DomainsBuffer == NULL)
{
MIDL_user_free(SidsBuffer);
return STATUS_INSUFFICIENT_RESOURCES;
}
DomainsBuffer->Entries = Count;
DomainsBuffer->Domains = MIDL_user_allocate(Count * sizeof(LSA_TRUST_INFORMATION));
if (DomainsBuffer->Domains == NULL)
{
MIDL_user_free(DomainsBuffer);
MIDL_user_free(SidsBuffer);
return STATUS_INSUFFICIENT_RESOURCES;
}
Status = RtlAllocateAndInitializeSid(&IdentifierAuthority,
2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&DomainSid);
if (!NT_SUCCESS(Status))
{
MIDL_user_free(DomainsBuffer->Domains);
MIDL_user_free(DomainsBuffer);
MIDL_user_free(SidsBuffer);
return Status;
}
DomainSidLength = RtlLengthSid(DomainSid);
for (i = 0; i < Count; i++)
{
DomainsBuffer->Domains[i].Sid = MIDL_user_allocate(DomainSidLength);
RtlCopyMemory(DomainsBuffer->Domains[i].Sid,
DomainSid,
DomainSidLength);
DomainsBuffer->Domains[i].Name.Buffer = MIDL_user_allocate(DomainName.MaximumLength);
DomainsBuffer->Domains[i].Name.Length = DomainName.Length;
DomainsBuffer->Domains[i].Name.MaximumLength = DomainName.MaximumLength;
RtlCopyMemory(DomainsBuffer->Domains[i].Name.Buffer,
DomainName.Buffer,
DomainName.MaximumLength);
}
Status = RtlAllocateAndInitializeSid(&IdentifierAuthority,
3,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
DOMAIN_USER_RID_ADMIN,
0, 0, 0, 0, 0,
&AccountSid);
if (!NT_SUCCESS(Status))
{
MIDL_user_free(DomainsBuffer->Domains);
MIDL_user_free(DomainsBuffer);
MIDL_user_free(SidsBuffer);
return Status;
}
AccountSidLength = RtlLengthSid(AccountSid);
for (i = 0; i < Count; i++)
{
SidsBuffer[i].Use = SidTypeWellKnownGroup;
SidsBuffer[i].Sid = MIDL_user_allocate(AccountSidLength);
RtlCopyMemory(SidsBuffer[i].Sid,
AccountSid,
AccountSidLength);
SidsBuffer[i].DomainIndex = i;
SidsBuffer[i].Flags = 0;
}
*ReferencedDomains = DomainsBuffer;
*MappedCount = Count;
TranslatedSids->Entries = Count;
TranslatedSids->Sids = SidsBuffer;
return STATUS_SUCCESS;
} }
@ -1391,7 +1509,7 @@ NTSTATUS WINAPI LsarLookupNames4(
DWORD Count, DWORD Count,
PRPC_UNICODE_STRING Names, PRPC_UNICODE_STRING Names,
PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains, PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
PLSAPR_TRANSLATED_SID_EX2 TranslatedSids, PLSAPR_TRANSLATED_SIDS_EX2 TranslatedSids,
LSAP_LOOKUP_LEVEL LookupLevel, LSAP_LOOKUP_LEVEL LookupLevel,
DWORD *MappedCount, DWORD *MappedCount,
DWORD LookupOptions, DWORD LookupOptions,

View file

@ -223,7 +223,7 @@ BEGIN
LTEXT "", 14011, 68, 93, 160, 10 LTEXT "", 14011, 68, 93, 160, 10
LTEXT "Utworzony:", 14014, 8, 118, 45, 10 LTEXT "Utworzony:", 14014, 8, 118, 45, 10
LTEXT "", 14015, 68, 118, 160, 10 LTEXT "", 14015, 68, 118, 160, 10
AUTOCHECKBOX "&Tylko-do-odczytu", 14021, 45, 150, 67, 10 AUTOCHECKBOX "&Tylko do odczytu", 14021, 45, 150, 67, 10
AUTOCHECKBOX "&Ukryty", 14022, 126, 150, 50, 10 AUTOCHECKBOX "&Ukryty", 14022, 126, 150, 50, 10
END END

View file

@ -584,7 +584,7 @@ BOOL
QueueFile( QueueFile(
FILE_OPERATION_CONTEXT * Context) FILE_OPERATION_CONTEXT * Context)
{ {
FILE_ENTRY * from, *to; FILE_ENTRY * from, *to = NULL;
BOOL bRet = FALSE; BOOL bRet = FALSE;
if (Context->Index >= Context->from->dwNumFiles) if (Context->Index >= Context->from->dwNumFiles)
@ -593,7 +593,7 @@ QueueFile(
/* get current file */ /* get current file */
from = &Context->from->feFiles[Context->Index]; from = &Context->from->feFiles[Context->Index];
if (Context->op->req->fFlags != FO_DELETE) if (Context->op->req->wFunc != FO_DELETE)
to = &Context->to->feFiles[Context->Index]; to = &Context->to->feFiles[Context->Index];
/* update status */ /* update status */

View file

@ -20,6 +20,7 @@
#include <shlobj.h> #include <shlobj.h>
#define NTOS_MODE_USER #define NTOS_MODE_USER
#include <ndk/ntndk.h> #include <ndk/ntndk.h>
#include <time.h>
#include <syssetup/syssetup.h> #include <syssetup/syssetup.h>
@ -1916,11 +1917,30 @@ ProcessPageDlgProc(HWND hwndDlg,
static VOID static VOID
SetupIsActive( DWORD dw ) SetInstallationCompleted(VOID)
{ {
HKEY hKey = 0; HKEY hKey = 0;
if (RegOpenKeyExW( HKEY_LOCAL_MACHINE, L"SYSTEM\\Setup", 0, KEY_WRITE, &hKey ) == ERROR_SUCCESS) { DWORD InProgress = 0;
RegSetValueExW( hKey, L"SystemSetupInProgress", 0, REG_DWORD, (CONST BYTE *)&dw, sizeof(dw) ); DWORD InstallDate;
if (RegOpenKeyExW( HKEY_LOCAL_MACHINE,
L"SYSTEM\\Setup",
0,
KEY_WRITE,
&hKey ) == ERROR_SUCCESS)
{
RegSetValueExW( hKey, L"SystemSetupInProgress", 0, REG_DWORD, (LPBYTE)&InProgress, sizeof(InProgress) );
RegCloseKey( hKey );
}
if (RegOpenKeyExW( HKEY_LOCAL_MACHINE,
L"Software\\Microsoft\\Windows NT\\CurrentVersion",
0,
KEY_WRITE,
&hKey ) == ERROR_SUCCESS)
{
InstallDate = (DWORD)time(NULL);
RegSetValueExW( hKey, L"InstallDate", 0, REG_DWORD, (LPBYTE)&InstallDate, sizeof(InstallDate) );
RegCloseKey( hKey ); RegCloseKey( hKey );
} }
} }
@ -1951,7 +1971,7 @@ FinishDlgProc(HWND hwndDlg,
if (SetupData->UnattendSetup) if (SetupData->UnattendSetup)
{ {
KillTimer(hwndDlg, 1); KillTimer(hwndDlg, 1);
SetupIsActive(0); SetInstallationCompleted();
PostQuitMessage(0); PostQuitMessage(0);
} }
} }
@ -1959,7 +1979,7 @@ FinishDlgProc(HWND hwndDlg,
case WM_DESTROY: case WM_DESTROY:
{ {
SetupIsActive(0); SetInstallationCompleted();
PostQuitMessage(0); PostQuitMessage(0);
return TRUE; return TRUE;
} }

View file

@ -116,6 +116,7 @@ EnumDisplayMonitors(
HMONITOR *hMonitorList; HMONITOR *hMonitorList;
LPRECT pRectList; LPRECT pRectList;
HANDLE hHeap; HANDLE hHeap;
BOOL ret = FALSE;
/* get list of monitors/rects */ /* get list of monitors/rects */
iCount = NtUserEnumDisplayMonitors(hdc, lprcClip, NULL, NULL, 0); iCount = NtUserEnumDisplayMonitors(hdc, lprcClip, NULL, NULL, 0);
@ -139,18 +140,15 @@ EnumDisplayMonitors(
pRectList = HeapAlloc(hHeap, 0, sizeof (RECT) * iCount); pRectList = HeapAlloc(hHeap, 0, sizeof (RECT) * iCount);
if (pRectList == NULL) if (pRectList == NULL)
{ {
HeapFree(hHeap, 0, hMonitorList);
SetLastError(ERROR_NOT_ENOUGH_MEMORY); SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE; goto cleanup;
} }
iCount = NtUserEnumDisplayMonitors(hdc, lprcClip, hMonitorList, pRectList, iCount); iCount = NtUserEnumDisplayMonitors(hdc, lprcClip, hMonitorList, pRectList, iCount);
if (iCount <= 0) if (iCount <= 0)
{ {
/* FIXME: SetLastError() */ /* FIXME: SetLastError() */
HeapFree(hHeap, 0, hMonitorList); goto cleanup;
HeapFree(hHeap, 0, pRectList);
return FALSE;
} }
/* enumerate list */ /* enumerate list */
@ -167,11 +165,17 @@ EnumDisplayMonitors(
} }
if (!lpfnEnum(hMonitor, hMonitorDC, pMonitorRect, dwData)) if (!lpfnEnum(hMonitor, hMonitorDC, pMonitorRect, dwData))
break; goto cleanup; /* return FALSE */
} }
HeapFree(hHeap, 0, hMonitorList);
HeapFree(hHeap, 0, pRectList); ret = TRUE;
return TRUE;
cleanup:
if(hMonitorList)
HeapFree(hHeap, 0, hMonitorList);
if(pRectList)
HeapFree(hHeap, 0, pRectList);
return ret;
} }

View file

@ -696,22 +696,20 @@ GetClassNameA(
LPSTR lpClassName, LPSTR lpClassName,
int nMaxCount) int nMaxCount)
{ {
ANSI_STRING ClassName; WCHAR tmpbuf[MAX_ATOM_LEN + 1];
int Result; int len;
ClassName.MaximumLength = nMaxCount; if (nMaxCount <= 0) return 0;
ClassName.Buffer = lpClassName; if (!GetClassNameW( hWnd, tmpbuf, sizeof(tmpbuf)/sizeof(WCHAR) )) return 0;
RtlUnicodeToMultiByteN( lpClassName, nMaxCount - 1, (PULONG)&len, tmpbuf, strlenW(tmpbuf) * sizeof(WCHAR) );
Result = NtUserGetClassName(hWnd, lpClassName[len] = 0;
(PUNICODE_STRING)&ClassName,
TRUE);
TRACE("%p class/atom: %s/%04x %x\n", hWnd, TRACE("%p class/atom: %s/%04x %x\n", hWnd,
IS_ATOM(lpClassName) ? NULL : lpClassName, IS_ATOM(lpClassName) ? NULL : lpClassName,
IS_ATOM(lpClassName) ? lpClassName : 0, IS_ATOM(lpClassName) ? lpClassName : 0,
nMaxCount); nMaxCount);
return Result; return len;
} }
@ -732,8 +730,8 @@ GetClassNameW(
ClassName.Buffer = lpClassName; ClassName.Buffer = lpClassName;
Result = NtUserGetClassName(hWnd, Result = NtUserGetClassName(hWnd,
&ClassName, FALSE,
FALSE); &ClassName);
TRACE("%p class/atom: %S/%04x %x\n", hWnd, TRACE("%p class/atom: %S/%04x %x\n", hWnd,
IS_ATOM(lpClassName) ? NULL : lpClassName, IS_ATOM(lpClassName) ? NULL : lpClassName,
@ -914,8 +912,11 @@ RealGetWindowClassW(
LPWSTR pszType, LPWSTR pszType,
UINT cchType) UINT cchType)
{ {
/* FIXME: Implement correct functionality of RealGetWindowClass */ UNICODE_STRING ClassName;
return GetClassNameW(hwnd,pszType,cchType); ClassName.MaximumLength = cchType * sizeof(WCHAR);
ClassName.Buffer = (PWSTR)pszType;
return NtUserGetClassName(hwnd,TRUE,&ClassName);
} }
@ -929,8 +930,14 @@ RealGetWindowClassA(
LPSTR pszType, LPSTR pszType,
UINT cchType) UINT cchType)
{ {
/* FIXME: Implement correct functionality of RealGetWindowClass */ WCHAR tmpbuf[MAX_ATOM_LEN + 1];
return GetClassNameA(hwnd,pszType,cchType); UINT len;
if ((INT)cchType <= 0) return 0;
if (!RealGetWindowClassW( hwnd, tmpbuf, sizeof(tmpbuf)/sizeof(WCHAR) )) return 0;
RtlUnicodeToMultiByteN( pszType, cchType - 1, (PULONG)&len, tmpbuf, strlenW(tmpbuf) * sizeof(WCHAR) );
pszType[len] = 0;
return len;
} }
/* /*

View file

@ -458,16 +458,10 @@ static BOOL create_icon_bitmaps( const BITMAPINFO *bmi, int width, int height,
void *color_bits, *mask_bits; void *color_bits, *mask_bits;
BOOL ret = FALSE; BOOL ret = FALSE;
HDC hdc = 0; HDC hdc = 0;
static HDC hScreenDC = 0;
if (!(info = HeapAlloc( GetProcessHeap(), 0, max( size, FIELD_OFFSET( BITMAPINFO, bmiColors[2] ))))) if (!(info = HeapAlloc( GetProcessHeap(), 0, max( size, FIELD_OFFSET( BITMAPINFO, bmiColors[2] )))))
return FALSE; return FALSE;
if(!hScreenDC) if (!(hdc = CreateCompatibleDC(NULL))) goto done;
{
hScreenDC = GetDC(0);
if(!hScreenDC) goto done;
}
if (!(hdc = CreateCompatibleDC(hScreenDC))) goto done;
memcpy( info, bmi, size ); memcpy( info, bmi, size );
info->bmiHeader.biHeight /= 2; info->bmiHeader.biHeight /= 2;
@ -491,8 +485,8 @@ static BOOL create_icon_bitmaps( const BITMAPINFO *bmi, int width, int height,
else else
{ {
if (!(*mask = CreateBitmap( width, height, 1, 1, NULL ))) goto done; if (!(*mask = CreateBitmap( width, height, 1, 1, NULL ))) goto done;
if (!(*color = CreateBitmap( width, height, GetDeviceCaps(hScreenDC, PLANES), if (!(*color = CreateBitmap( width, height, GetDeviceCaps(hdc, PLANES),
GetDeviceCaps(hScreenDC, BITSPIXEL), NULL ))) GetDeviceCaps(hdc, BITSPIXEL), NULL )))
{ {
DeleteObject( *mask ); DeleteObject( *mask );
goto done; goto done;

View file

@ -1564,20 +1564,29 @@ FlashWindow(HWND hWnd, BOOL bInvert)
INT WINAPI INT WINAPI
FillRect(HDC hDC, CONST RECT *lprc, HBRUSH hbr) FillRect(HDC hDC, CONST RECT *lprc, HBRUSH hbr)
{ {
HBRUSH prevhbr; BOOL Ret;
HBRUSH prevhbr = NULL;
if (hbr <= (HBRUSH)(COLOR_MENUBAR + 1)) /* Select brush if specified */
if (hbr)
{ {
hbr = GetSysColorBrush(PtrToUlong(hbr) - 1); /* Handle system colors */
if (hbr <= (HBRUSH)(COLOR_MENUBAR + 1))
hbr = GetSysColorBrush(PtrToUlong(hbr) - 1);
prevhbr = SelectObject(hDC, hbr);
if (prevhbr == NULL)
return (INT)FALSE;
} }
if ((prevhbr = SelectObject(hDC, hbr)) == NULL)
{ Ret = PatBlt(hDC, lprc->left, lprc->top, lprc->right - lprc->left,
return FALSE; lprc->bottom - lprc->top, PATCOPY);
}
PatBlt(hDC, lprc->left, lprc->top, lprc->right - lprc->left, /* Select old brush */
lprc->bottom - lprc->top, PATCOPY); if (prevhbr)
SelectObject(hDC, prevhbr); SelectObject(hDC, prevhbr);
return TRUE;
return (INT)Ret;
} }
/* /*

View file

@ -100,7 +100,6 @@ DragDetect(
#endif #endif
} }
/* /*
* @implemented * @implemented
*/ */
@ -108,43 +107,9 @@ BOOL WINAPI
EnableWindow(HWND hWnd, EnableWindow(HWND hWnd,
BOOL bEnable) BOOL bEnable)
{ {
// This will soon be moved to win32k. return NtUserCallTwoParam((DWORD_PTR)hWnd, (DWORD_PTR)bEnable, TWOPARAM_ROUTINE_ENABLEWINDOW);
BOOL Update;
LONG Style = GetWindowLongPtrW(hWnd, GWL_STYLE);
/* check if updating is needed */
UINT bIsDisabled = (Style & WS_DISABLED);
Update = bIsDisabled;
if (bEnable)
{
Style &= ~WS_DISABLED;
}
else
{
Update = !bIsDisabled;
SendMessageW( hWnd, WM_CANCELMODE, 0, 0);
/* Remove keyboard focus from that window if it had focus */
if (hWnd == GetFocus())
{
SetFocus(NULL);
}
Style |= WS_DISABLED;
}
NtUserSetWindowLong(hWnd, GWL_STYLE, Style, FALSE);
if (Update)
{
IntNotifyWinEvent(EVENT_OBJECT_STATECHANGE, hWnd, OBJID_WINDOW, CHILDID_SELF, 0);
SendMessageW(hWnd, WM_ENABLE, (LPARAM)bEnable, 0);
}
// Return nonzero if it was disabled, or zero if it wasn't:
return bIsDisabled;
} }
/* /*
* @implemented * @implemented
*/ */

View file

@ -1576,6 +1576,11 @@ static BOOL FASTCALL MenuShowPopup(HWND hwndOwner, HMENU hmenu, UINT id, UINT fl
MenuInfo.FocusedItem = NO_SELECTED_ITEM; MenuInfo.FocusedItem = NO_SELECTED_ITEM;
} }
/* ReactOS Check */
if (!ValidateHwnd(hwndOwner))
{ // This window maybe already DEAD!!!
return FALSE;
}
/* store the owner for DrawItem */ /* store the owner for DrawItem */
MenuInfo.WndOwner = hwndOwner; MenuInfo.WndOwner = hwndOwner;
MenuSetRosMenuInfo(&MenuInfo); MenuSetRosMenuInfo(&MenuInfo);
@ -3174,6 +3179,7 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y,
BOOL fRemove; BOOL fRemove;
INT executedMenuId = -1; INT executedMenuId = -1;
MTRACKER mt; MTRACKER mt;
HWND capture_win;
BOOL enterIdleSent = FALSE; BOOL enterIdleSent = FALSE;
mt.TrackFlags = 0; mt.TrackFlags = 0;
@ -3207,12 +3213,16 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y,
fEndMenu = !fRemove; fEndMenu = !fRemove;
} }
SetCapture(mt.OwnerWnd); if (wFlags & TF_ENDMENU) fEndMenu = TRUE;
(void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, mt.OwnerWnd);
/* owner may not be visible when tracking a popup, so use the menu itself */
capture_win = (wFlags & TPM_POPUPMENU) ? MenuInfo.Wnd : mt.OwnerWnd;
(void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, capture_win); // 1
SetCapture(capture_win); // 2
FIXME("MenuTrackMenu 1\n");
while (! fEndMenu) while (! fEndMenu)
{ {
BOOL ErrorExit = FALSE;
PVOID menu = ValidateHandle(mt.CurrentMenu, VALIDATE_TYPE_MENU); PVOID menu = ValidateHandle(mt.CurrentMenu, VALIDATE_TYPE_MENU);
if (!menu) /* sometimes happens if I do a window manager close */ if (!menu) /* sometimes happens if I do a window manager close */
break; break;
@ -3230,6 +3240,12 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y,
} }
else else
{ {
/* ReactOS Check */
if (!ValidateHwnd(mt.OwnerWnd) || !ValidateHwnd(MenuInfo.Wnd))
{
ErrorExit = TRUE; // Do not wait on dead windows, now test_capture_4 works.
break;
}
if (!enterIdleSent) if (!enterIdleSent)
{ {
HWND win = MenuInfo.Flags & MF_POPUP ? MenuInfo.Wnd : NULL; HWND win = MenuInfo.Flags & MF_POPUP ? MenuInfo.Wnd : NULL;
@ -3238,9 +3254,10 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y,
} }
WaitMessage(); WaitMessage();
} }
//FIXME("MenuTrackMenu loop 1\n");
} }
if (ErrorExit) break; // Gracefully dropout.
/* check if EndMenu() tried to cancel us, by posting this message */ /* check if EndMenu() tried to cancel us, by posting this message */
if (msg.message == WM_CANCELMODE) if (msg.message == WM_CANCELMODE)
{ {
@ -3446,7 +3463,6 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y,
{ {
PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE ); PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE );
DispatchMessageW( &msg ); DispatchMessageW( &msg );
//FIXME("MenuTrackMenu loop 2\n");
continue; continue;
} }
@ -3457,9 +3473,7 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y,
if (fRemove && !(mt.TrackFlags & TF_SKIPREMOVE) ) if (fRemove && !(mt.TrackFlags & TF_SKIPREMOVE) )
PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE ); PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE );
else mt.TrackFlags &= ~TF_SKIPREMOVE; else mt.TrackFlags &= ~TF_SKIPREMOVE;
//FIXME("MenuTrackMenu loop 3\n");
} }
FIXME("MenuTrackMenu 2\n");
(void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, NULL); (void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, NULL);
SetCapture(NULL); /* release the capture */ SetCapture(NULL); /* release the capture */
@ -3518,12 +3532,11 @@ static BOOL FASTCALL MenuInitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT
HideCaret(0); HideCaret(0);
MenuGetRosMenuInfo(&MenuInfo, hMenu);
/* This makes the menus of applications built with Delphi work. /* This makes the menus of applications built with Delphi work.
* It also enables menus to be displayed in more than one window, * It also enables menus to be displayed in more than one window,
* but there are some bugs left that need to be fixed in this case. * but there are some bugs left that need to be fixed in this case.
*/ */
if(MenuInfo.Self == hMenu) if (MenuGetRosMenuInfo(&MenuInfo, hMenu))
{ {
MenuInfo.Wnd = hWnd; MenuInfo.Wnd = hWnd;
MenuSetRosMenuInfo(&MenuInfo); MenuSetRosMenuInfo(&MenuInfo);
@ -3655,13 +3668,7 @@ VOID MenuTrackKbdMenuBar(HWND hwnd, UINT wParam, WCHAR wChar)
MenuSelectItem( hwnd, &MenuInfo, uItem, TRUE, 0 ); MenuSelectItem( hwnd, &MenuInfo, uItem, TRUE, 0 );
if (wParam & HTSYSMENU) if (!(wParam & HTSYSMENU) || wChar == ' ')
{
/* prevent sysmenu activation for managed windows on Alt down/up */
// if (GetPropA( hwnd, "__wine_x11_managed" ))
wFlags |= TF_ENDMENU; /* schedule end of menu tracking */
}
else
{ {
if( uItem == NO_SELECTED_ITEM ) if( uItem == NO_SELECTED_ITEM )
MenuMoveSelection( hwnd, &MenuInfo, ITEM_NEXT ); MenuMoveSelection( hwnd, &MenuInfo, ITEM_NEXT );
@ -3690,6 +3697,12 @@ BOOL WINAPI TrackPopupMenuEx( HMENU Menu, UINT Flags, int x, int y,
return FALSE; return FALSE;
} }
/* ReactOS Check */
if (!ValidateHwnd(Wnd))
{
return FALSE;
}
MenuGetRosMenuInfo(&MenuInfo, Menu); MenuGetRosMenuInfo(&MenuInfo, Menu);
if (IsWindow(MenuInfo.Wnd)) if (IsWindow(MenuInfo.Wnd))
{ {

View file

@ -2380,8 +2380,7 @@ GetCapture(VOID)
BOOL WINAPI BOOL WINAPI
ReleaseCapture(VOID) ReleaseCapture(VOID)
{ {
NtUserSetCapture(NULL); return (BOOL)NtUserCallNoParam(NOPARAM_ROUTINE_RELEASECAPTURE);
return(TRUE);
} }
@ -2491,11 +2490,13 @@ BOOL WINAPI SetMessageQueue(int cMessagesMax)
} }
typedef DWORD (WINAPI * RealGetQueueStatusProc)(UINT flags); typedef DWORD (WINAPI * RealGetQueueStatusProc)(UINT flags);
typedef DWORD (WINAPI * RealMsgWaitForMultipleObjectsExProc)(DWORD nCount, CONST HANDLE *lpHandles, DWORD dwMilliseconds, DWORD dwWakeMask, DWORD dwFlags); typedef DWORD (WINAPI * RealMsgWaitForMultipleObjectsExProc)(DWORD nCount, CONST HANDLE *lpHandles, DWORD dwMilliseconds, DWORD dwWakeMask, DWORD dwFlags);
typedef BOOL (WINAPI * RealInternalGetMessageProc)(LPMSG,HWND,UINT,UINT,UINT,BOOL);
typedef BOOL (WINAPI * RealWaitMessageExProc)(DWORD,UINT);
typedef struct _USER_MESSAGE_PUMP_ADDRESSES { typedef struct _USER_MESSAGE_PUMP_ADDRESSES {
DWORD cbSize; DWORD cbSize;
//NtUserRealInternalGetMessageProc NtUserRealInternalGetMessage; RealInternalGetMessageProc NtUserRealInternalGetMessage;
//NtUserRealWaitMessageExProc NtUserRealWaitMessageEx; RealWaitMessageExProc NtUserRealWaitMessageEx;
RealGetQueueStatusProc RealGetQueueStatus; RealGetQueueStatusProc RealGetQueueStatus;
RealMsgWaitForMultipleObjectsExProc RealMsgWaitForMultipleObjectsEx; RealMsgWaitForMultipleObjectsExProc RealMsgWaitForMultipleObjectsEx;
} USER_MESSAGE_PUMP_ADDRESSES, * PUSER_MESSAGE_PUMP_ADDRESSES; } USER_MESSAGE_PUMP_ADDRESSES, * PUSER_MESSAGE_PUMP_ADDRESSES;
@ -2515,8 +2516,8 @@ CRITICAL_SECTION gcsMPH;
MESSAGEPUMPHOOKPROC gpfnInitMPH; MESSAGEPUMPHOOKPROC gpfnInitMPH;
DWORD gcLoadMPH = 0; DWORD gcLoadMPH = 0;
USER_MESSAGE_PUMP_ADDRESSES gmph = {sizeof(USER_MESSAGE_PUMP_ADDRESSES), USER_MESSAGE_PUMP_ADDRESSES gmph = {sizeof(USER_MESSAGE_PUMP_ADDRESSES),
//NtUserRealInternalGetMessage, NtUserRealInternalGetMessage,
//NtUserRealInternalWaitMessageEx, NtUserRealWaitMessageEx,
RealGetQueueStatus, RealGetQueueStatus,
RealMsgWaitForMultipleObjectsEx RealMsgWaitForMultipleObjectsEx
}; };
@ -2532,8 +2533,8 @@ BOOL WINAPI IsInsideMessagePumpHook()
void WINAPI ResetMessagePumpHook(PUSER_MESSAGE_PUMP_ADDRESSES Addresses) void WINAPI ResetMessagePumpHook(PUSER_MESSAGE_PUMP_ADDRESSES Addresses)
{ {
Addresses->cbSize = sizeof(USER_MESSAGE_PUMP_ADDRESSES); Addresses->cbSize = sizeof(USER_MESSAGE_PUMP_ADDRESSES);
//Addresses->NtUserRealInternalGetMessage = (NtUserRealInternalGetMessageProc)NtUserRealInternalGetMessage; Addresses->NtUserRealInternalGetMessage = NtUserRealInternalGetMessage;
//Addresses->NtUserRealWaitMessageEx = (NtUserRealWaitMessageExProc)NtUserRealInternalWaitMessageEx; Addresses->NtUserRealWaitMessageEx = NtUserRealWaitMessageEx;
Addresses->RealGetQueueStatus = RealGetQueueStatus; Addresses->RealGetQueueStatus = RealGetQueueStatus;
Addresses->RealMsgWaitForMultipleObjectsEx = RealMsgWaitForMultipleObjectsEx; Addresses->RealMsgWaitForMultipleObjectsEx = RealMsgWaitForMultipleObjectsEx;
} }

View file

@ -107,19 +107,19 @@ GetUpdateRect(
pWnd = ValidateHwnd(Wnd); pWnd = ValidateHwnd(Wnd);
if (!pWnd) if (!pWnd)
return FALSE; return FALSE;
/*
if ( pWnd->hrgnUpdate || if ( pWnd->hrgnUpdate ||
pWnd->state & (WNDS_SENDERASEBACKGROUND|WNDS_SENDNCPAINT|WNDS_UPDATEDIRTY|WNDS_PAINTNOTPROCESSED)) pWnd->state & (WNDS_SENDERASEBACKGROUND|WNDS_SENDNCPAINT|WNDS_UPDATEDIRTY|WNDS_PAINTNOTPROCESSED))
{*/ {
return NtUserGetUpdateRect(Wnd, Rect, Erase); return NtUserGetUpdateRect(Wnd, Rect, Erase);
/* } }
if (Rect) if (Rect)
{ // Did the Rgn update? No! Back set and shutup! { // Did the Rgn update? No! Back set and shutup!
Rect->left = Rect->right = Rect->top = Rect->bottom = 0; Rect->left = Rect->right = Rect->top = Rect->bottom = 0;
} }
return FALSE; // msdn: "If there is no update region, the return value is zero." return FALSE; // msdn: "If there is no update region, the return value is zero."
*/
} }
@ -144,14 +144,14 @@ GetUpdateRgn(
pWnd = ValidateHwnd(hWnd); pWnd = ValidateHwnd(hWnd);
if (!pWnd) if (!pWnd)
return ERROR; return ERROR;
/*
if ( pWnd->hrgnUpdate || if ( pWnd->hrgnUpdate ||
pWnd->state & (WNDS_SENDERASEBACKGROUND|WNDS_SENDNCPAINT|WNDS_UPDATEDIRTY|WNDS_PAINTNOTPROCESSED)) pWnd->state & (WNDS_SENDERASEBACKGROUND|WNDS_SENDNCPAINT|WNDS_UPDATEDIRTY|WNDS_PAINTNOTPROCESSED))
{*/ {
return NtUserGetUpdateRgn(hWnd, hRgn, bErase); return NtUserGetUpdateRgn(hWnd, hRgn, bErase);
/* } }
SetRectRgn(hRgn, 0, 0, 0, 0); SetRectRgn(hRgn, 0, 0, 0, 0);
return NULLREGION;*/ return NULLREGION;
} }
@ -239,14 +239,14 @@ UpdateWindow(
if (!pWnd) if (!pWnd)
return FALSE; return FALSE;
/*
if ( pWnd->hrgnUpdate || if ( pWnd->hrgnUpdate ||
pWnd->state & WNDS_INTERNALPAINT || pWnd->state & WNDS_INTERNALPAINT ||
pWnd->spwndChild ) pWnd->spwndChild )
{*/ {
return NtUserCallHwndLock(hWnd, HWNDLOCK_ROUTINE_UPDATEWINDOW); return NtUserCallHwndLock(hWnd, HWNDLOCK_ROUTINE_UPDATEWINDOW);
/* } }
return TRUE;*/ return TRUE;
} }
/* /*
@ -286,7 +286,7 @@ GetWindowRgn(
if (!Ret) if (!Ret)
return ERROR; return ERROR;
if (pWnd->fnid != FNID_DESKTOP) if (hWnd != GetDesktopWindow()) // pWnd->fnid != FNID_DESKTOP)
Ret = OffsetRgn(hRgn, -pWnd->rcWindow.left, -pWnd->rcWindow.top); Ret = OffsetRgn(hRgn, -pWnd->rcWindow.left, -pWnd->rcWindow.top);
if (pWnd->ExStyle & WS_EX_LAYOUTRTL) if (pWnd->ExStyle & WS_EX_LAYOUTRTL)
@ -320,7 +320,7 @@ GetWindowRgnBox(
if (!Ret) if (!Ret)
return ERROR; return ERROR;
if (pWnd->fnid != FNID_DESKTOP) if (hWnd != GetDesktopWindow()) // pWnd->fnid != FNID_DESKTOP)
OffsetRect(lprc, -pWnd->rcWindow.left, -pWnd->rcWindow.top); OffsetRect(lprc, -pWnd->rcWindow.left, -pWnd->rcWindow.top);
if (pWnd->ExStyle & WS_EX_LAYOUTRTL) if (pWnd->ExStyle & WS_EX_LAYOUTRTL)

View file

@ -118,4 +118,12 @@ LdrProcessRelocationBlockLongLong(
IN LONGLONG Delta IN LONGLONG Delta
); );
NTSTATUS
NTAPI
LdrEnumerateLoadedModules(
IN BOOLEAN ReservedFlag,
IN PLDR_ENUM_CALLBACK EnumProc,
IN PVOID Context
);
#endif #endif

View file

@ -71,14 +71,25 @@ Author:
// //
// LdrLockLoaderLock Flags // LdrLockLoaderLock Flags
// //
#define LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS 0x00000001 #define LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS 0x00000001
#define LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY 0x00000002 #define LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY 0x00000002
#define LDR_LOCK_LOADER_LOCK_DISPOSITION_INVALID 0
#define LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_ACQUIRED 1
#define LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_NOT_ACQUIRED 2
// //
// FIXME: THIS SHOULD *NOT* BE USED! // FIXME: THIS SHOULD *NOT* BE USED!
// //
#define IMAGE_SCN_TYPE_NOLOAD 0x00000002 #define IMAGE_SCN_TYPE_NOLOAD 0x00000002
//
// Loader datafile/imagemapping macros
//
#define LDR_IS_DATAFILE(handle) (((ULONG_PTR)(handle)) & (ULONG_PTR)1)
#define LDR_IS_IMAGEMAPPING(handle) (((ULONG_PTR)(handle)) & (ULONG_PTR)2)
#define LDR_IS_RESOURCE(handle) (LDR_IS_IMAGEMAPPING(handle) || LDR_IS_DATAFILE(handle))
// //
// Loader Data stored in the PEB // Loader Data stored in the PEB
// //
@ -188,4 +199,10 @@ typedef struct _ALT_RESOURCE_MODULE
#endif #endif
} ALT_RESOURCE_MODULE, *PALT_RESOURCE_MODULE; } ALT_RESOURCE_MODULE, *PALT_RESOURCE_MODULE;
//
// Callback function for LdrEnumerateLoadedModules
//
typedef VOID (NTAPI LDR_ENUM_CALLBACK)(IN PLDR_DATA_TABLE_ENTRY ModuleInformation, IN PVOID Parameter, OUT BOOLEAN *Stop);
typedef LDR_ENUM_CALLBACK *PLDR_ENUM_CALLBACK;
#endif #endif

View file

@ -1012,7 +1012,7 @@ typedef struct _CURDIR
HANDLE Handle; HANDLE Handle;
} CURDIR, *PCURDIR; } CURDIR, *PCURDIR;
typedef struct RTL_DRIVE_LETTER_CURDIR typedef struct _RTL_DRIVE_LETTER_CURDIR
{ {
USHORT Flags; USHORT Flags;
USHORT Length; USHORT Length;
@ -1020,6 +1020,13 @@ typedef struct RTL_DRIVE_LETTER_CURDIR
UNICODE_STRING DosPath; UNICODE_STRING DosPath;
} RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR; } RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR;
typedef struct _RTL_PERTHREAD_CURDIR
{
PRTL_DRIVE_LETTER_CURDIR CurrentDirectories;
PUNICODE_STRING ImageName;
PVOID Environment;
} RTL_PERTHREAD_CURDIR, *PRTL_PERTHREAD_CURDIR;
// //
// Private State structure for RtlAcquirePrivilege/RtlReleasePrivilege // Private State structure for RtlAcquirePrivilege/RtlReleasePrivilege
// //

View file

@ -19,6 +19,9 @@ DWORD WINAPI DeleteProxyArpEntry(DWORD,DWORD,DWORD);
DWORD WINAPI EnableRouter(HANDLE*,OVERLAPPED*); DWORD WINAPI EnableRouter(HANDLE*,OVERLAPPED*);
DWORD WINAPI FlushIpNetTable(DWORD); DWORD WINAPI FlushIpNetTable(DWORD);
DWORD WINAPI GetAdapterIndex(LPWSTR,PULONG); DWORD WINAPI GetAdapterIndex(LPWSTR,PULONG);
#ifdef _WINSOCK2API_
DWORD WINAPI GetAdaptersAddresses(ULONG,ULONG,PVOID,PIP_ADAPTER_ADDRESSES,PULONG);
#endif
DWORD WINAPI GetAdaptersInfo(PIP_ADAPTER_INFO,PULONG); DWORD WINAPI GetAdaptersInfo(PIP_ADAPTER_INFO,PULONG);
DWORD WINAPI GetBestInterface(IPAddr,PDWORD); DWORD WINAPI GetBestInterface(IPAddr,PDWORD);
DWORD WINAPI GetBestRoute(DWORD,DWORD,PMIB_IPFORWARDROW); DWORD WINAPI GetBestRoute(DWORD,DWORD,PMIB_IPFORWARDROW);

View file

@ -348,6 +348,25 @@ typedef struct {
WAVEFORMATEX WaveFormatEx; WAVEFORMATEX WaveFormatEx;
} KSDATAFORMAT_WAVEFORMATEX, *PKSDATAFORMAT_WAVEFORMATEX; } KSDATAFORMAT_WAVEFORMATEX, *PKSDATAFORMAT_WAVEFORMATEX;
#ifndef _WAVEFORMATEXTENSIBLE_
#define _WAVEFORMATEXTENSIBLE_
typedef struct {
WAVEFORMATEX Format;
union
{
WORD wValidBitsPerSample;
WORD wSamplesPerBlock;
WORD wReserved;
}Samples;
DWORD dwChannelMask;
GUID SubFormat;
} WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE;
#endif
#if !defined(WAVE_FORMAT_EXTENSIBLE)
#define WAVE_FORMAT_EXTENSIBLE 0xFFFE
#endif
typedef struct { typedef struct {
ULONG Flags; ULONG Flags;
ULONG Control; ULONG Control;
@ -734,4 +753,50 @@ typedef struct
ULONG ChannelMask; ULONG ChannelMask;
} KSDATARANGE_MUSIC, *PKSDATARANGE_MUSIC; } KSDATARANGE_MUSIC, *PKSDATARANGE_MUSIC;
#ifndef _SPEAKER_POSITIONS_
#define _SPEAKER_POSITIONS_
#define SPEAKER_FRONT_LEFT 0x1
#define SPEAKER_FRONT_RIGHT 0x2
#define SPEAKER_FRONT_CENTER 0x4
#define SPEAKER_LOW_FREQUENCY 0x8
#define SPEAKER_BACK_LEFT 0x10
#define SPEAKER_BACK_RIGHT 0x20
#define SPEAKER_FRONT_LEFT_OF_CENTER 0x40
#define SPEAKER_FRONT_RIGHT_OF_CENTER 0x80
#define SPEAKER_BACK_CENTER 0x100
#define SPEAKER_SIDE_LEFT 0x200
#define SPEAKER_SIDE_RIGHT 0x400
#define SPEAKER_TOP_CENTER 0x800
#define SPEAKER_TOP_FRONT_LEFT 0x1000
#define SPEAKER_TOP_FRONT_CENTER 0x2000
#define SPEAKER_TOP_FRONT_RIGHT 0x4000
#define SPEAKER_TOP_BACK_LEFT 0x8000
#define SPEAKER_TOP_BACK_CENTER 0x10000
#define SPEAKER_TOP_BACK_RIGHT 0x20000
#define SPEAKER_RESERVED 0x7FFC0000
#define SPEAKER_ALL 0x80000000
#endif
#if (NTDDI_VERSION >= NTDDI_WINXP)
#define KSAUDIO_SPEAKER_DIRECTOUT 0
#endif
#define KSAUDIO_SPEAKER_MONO (SPEAKER_FRONT_CENTER)
#define KSAUDIO_SPEAKER_STEREO (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT)
#define KSAUDIO_SPEAKER_QUAD (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | \
SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT)
#define KSAUDIO_SPEAKER_SURROUND (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | \
SPEAKER_FRONT_CENTER | SPEAKER_BACK_CENTER)
#define KSAUDIO_SPEAKER_5POINT1 (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | \
SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | \
SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT)
#define KSAUDIO_SPEAKER_7POINT1 (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | \
SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | \
SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | \
SPEAKER_FRONT_LEFT_OF_CENTER | SPEAKER_FRONT_RIGHT_OF_CENTER)
#endif #endif

View file

@ -2416,6 +2416,9 @@ typedef PCACTCTXW PCACTCTX;
#define GetCommandLine GetCommandLineW #define GetCommandLine GetCommandLineW
#define GetCompressedFileSize GetCompressedFileSizeW #define GetCompressedFileSize GetCompressedFileSizeW
#define GetComputerName GetComputerNameW #define GetComputerName GetComputerNameW
#if (_WIN32_WINNT >= 0x0500)
#define GetComputerNameEx GetComputerNameExW
#endif
#define GetCurrentDirectory GetCurrentDirectoryW #define GetCurrentDirectory GetCurrentDirectoryW
#define GetDefaultCommConfig GetDefaultCommConfigW #define GetDefaultCommConfig GetDefaultCommConfigW
#define GetDiskFreeSpace GetDiskFreeSpaceW #define GetDiskFreeSpace GetDiskFreeSpaceW
@ -2619,6 +2622,9 @@ typedef ENUMRESTYPEPROCA ENUMRESTYPEPROC;
#define GetBinaryType GetBinaryTypeA #define GetBinaryType GetBinaryTypeA
#define GetCommandLine GetCommandLineA #define GetCommandLine GetCommandLineA
#define GetComputerName GetComputerNameA #define GetComputerName GetComputerNameA
#if (_WIN32_WINNT >= 0x0500)
#define GetComputerNameEx GetComputerNameExA
#endif
#define GetCompressedFileSize GetCompressedFileSizeA #define GetCompressedFileSize GetCompressedFileSizeA
#define GetCurrentDirectory GetCurrentDirectoryA #define GetCurrentDirectory GetCurrentDirectoryA
#define GetDefaultCommConfig GetDefaultCommConfigA #define GetDefaultCommConfig GetDefaultCommConfigA

View file

@ -975,7 +975,7 @@ cpp_quote("#if _WIN32_WINNT >= 0x0500")
[in] DWORD Count, [in] DWORD Count,
[in, size_is(Count)] PRPC_UNICODE_STRING Names, [in, size_is(Count)] PRPC_UNICODE_STRING Names,
[out] PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains, [out] PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
[in, out] PLSAPR_TRANSLATED_SID_EX TranslatedSids, [in, out] PLSAPR_TRANSLATED_SIDS_EX TranslatedSids,
[in] LSAP_LOOKUP_LEVEL LookupLevel, [in] LSAP_LOOKUP_LEVEL LookupLevel,
[in, out] DWORD *MappedCount, [in, out] DWORD *MappedCount,
[in] DWORD LookupOptions, [in] DWORD LookupOptions,
@ -1029,7 +1029,7 @@ cpp_quote("#if _WIN32_WINNT >= 0x0501")
[in] DWORD Count, [in] DWORD Count,
[in, size_is(Count)] PRPC_UNICODE_STRING Names, [in, size_is(Count)] PRPC_UNICODE_STRING Names,
[out] PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains, [out] PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
[in, out] PLSAPR_TRANSLATED_SID_EX2 TranslatedSids, [in, out] PLSAPR_TRANSLATED_SIDS_EX2 TranslatedSids,
[in] LSAP_LOOKUP_LEVEL LookupLevel, [in] LSAP_LOOKUP_LEVEL LookupLevel,
[in, out] DWORD *MappedCount, [in, out] DWORD *MappedCount,
[in] DWORD LookupOptions, [in] DWORD LookupOptions,
@ -1088,7 +1088,7 @@ cpp_quote("#if _WIN32_WINNT >= 0x0501")
[in] DWORD Count, [in] DWORD Count,
[in, size_is(Count)] PRPC_UNICODE_STRING Names, [in, size_is(Count)] PRPC_UNICODE_STRING Names,
[out] PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains, [out] PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
[in, out] PLSAPR_TRANSLATED_SID_EX2 TranslatedSids, [in, out] PLSAPR_TRANSLATED_SIDS_EX2 TranslatedSids,
[in] LSAP_LOOKUP_LEVEL LookupLevel, [in] LSAP_LOOKUP_LEVEL LookupLevel,
[in, out] DWORD *MappedCount, [in, out] DWORD *MappedCount,
[in] DWORD LookupOptions, [in] DWORD LookupOptions,

View file

@ -34,97 +34,138 @@
Here you can change the configuration of FullFAT as appropriate to your Here you can change the configuration of FullFAT as appropriate to your
platform. platform.
*/ */
//---------- ENDIANESS //---------- ENDIANESS
#define FF_LITTLE_ENDIAN // Choosing the Byte-order of your system is important. #define FF_LITTLE_ENDIAN // Choosing the Byte-order of your system is important.
//#define FF_BIG_ENDIAN // You may be able to provide better Byte-order swapping routines to FullFAT. //#define FF_BIG_ENDIAN // You may be able to provide better Byte-order swapping routines to FullFAT.
// See ff_memory.c for more information. // See ff_memory.c for more information.
//---------- LFN (Long File-name) SUPPORT //---------- LFN (Long File-name) SUPPORT
#define FF_LFN_SUPPORT // Comment this out if you don't want to worry about Patent Issues. #define FF_LFN_SUPPORT // Comment this out if you don't want to worry about Patent Issues.
// FullFAT works great with LFNs and without. You choose, its your project! // FullFAT works great with LFNs and without. You choose, its your project!
//---------- LEGAL LFNS //#define FF_INCLUDE_SHORT_NAME // HT addition, in 'FF_DIRENT', beside FileName, ShortName will be filled as well
//#define FF_LEGAL_LFNS // Enabling this define causes FullFAT to not infringe on any of Microsoft's patents when making LFN names. // Useful for debugging, but also some situations its useful to know both.
// To do this, it will only create LFNs and no shortnames. Microsofts patents are only relevent when mapping //---------- SHORTNAMES CAN USE THE CASE BITS
// a shortname to a long name. This is the same way that Linux gets around the FAT legal issues: #define FF_SHORTNAME_CASE // Works for XP+ e.g. short.TXT or SHORT.txt.
// see http://lkml.org/lkml/2009/6/26/314
//
// Enabling this may break compatibility with devices that cannot read LFN filenames.
// Enabling this option causes no compatibility issues when reading any media.
//---------- TIME SUPPORT
#define FF_TIME_SUPPORT // Should FullFAT use time stamping. Only if you have provided the relevant time drivers in ff_time.c
// Note, by default ff_time.c is set-up for the Windows Demonstration. Please see ff_time.c to disable.
//---------- FILE SPACE ALLOCATION PERFORMANCE
// Uncomment the prefered method. (Can only choose a single method).
#define FF_ALLOC_DEFAULT // Only allocate as much as is needed. (Provides good performance, without wasting space).
//#define FF_ALLOC_DOUBLE // Doubles the size of a file each time allocation is required. (When high-performance writing is required).
//---------- Use Native STDIO.h
//#define FF_USE_NATIVE_STDIO // Makes FullFAT conform to values provided by your native STDIO.h file.
//---------- FREE SPACE CALCULATION
//#define FF_MOUNT_FIND_FREE // Uncomment this option to check for Freespace on a volume mount. (Performance Penalty while mounting).
// If not done in the mount, it will be done on the first call to FF_GetFreeSize() function.
//---------- PATH CACHE
#define FF_PATH_CACHE // Enables a simply Path Caching mechanism that increases performance of repeated operations
// within the same path. E.g. a copy \dir1\*.* \dir2\*.* command.
// This command requires FF_MAX_PATH number of bytes of memory. (Defined below, default 2600).
#define FF_PATH_CACHE_DEPTH 2 // The Number of PATH's to Cache. //---------- UNICODE SUPPORT
#define FF_UNICODE_SUPPORT // If this is defined, then all of FullFAT's API's will expect to receive UTF-16 formatted strings.
// FF_FindFirst() and FF_FindNext() will also return Filenames in UTF-16 format.
// NOTE: This option may cause FullFAT to not "Clean-compile" when using GCC. This is because
// pedantically GCC refuses to accept C99 library functions, unless the -std=c99 flag is used.
// To use UNICODE (UTF-16, or UTF-32 depending on the size of wchar_t) you must have a C99 compliant
// compiler and library.
//---------- DON'T USE MALLOC //#define FF_UNICODE_UTF8_SUPPORT // If this is defined, then all of FullFAT's API's will expect to receive UTF-8 formatted strings.
//#define FF_NO_MALLOC // FF_FindFirst() and FF_FindNext() will also return Filenames in UTF-8 format.
//---------- DON'T // Note the 2 UNICODE options are mutually exclusive. Only one can be enabled.
//---------- Hash Table Support
//#define FF_HASH_TABLE_SUPPORT // Enable HASH to speed up file creation.
#ifdef FF_HASH_TABLE_SUPPORT
#define FF_HASH_FUNCTION CRC16
//#define FF_HASH_FUNCTION CRC8
#endif
// Ensure that dirents are big enough to hold the maximum UTF-8 sequence.
//---------- FAT12 SUPPORT //---------- FAT12 SUPPORT
#define FF_FAT12_SUPPORT // Enable FAT12 Suppport. You can reduce the code-size by commenting this out. #define FF_FAT12_SUPPORT // Enable FAT12 Suppport. You can reduce the code-size by commenting this out.
// If you don't need FAT12 support, why have it. FAT12 is more complex to process, // If you don't need FAT12 support, why have it. FAT12 is more complex to process,
// therefore savings can be made by not having it. // therefore savings can be made by not having it.
//---------- TIME SUPPORT
#define FF_TIME_SUPPORT // Should FullFAT use time stamping. Only if you have provided the relevant time drivers in ff_time.c
// Note, by default ff_time.c is set-up for the Windows Demonstration. Please see ff_time.c to disable.
//---------- FILE SPACE ALLOCATION PERFORMANCE
// Uncomment the prefered method. (Can only choose a single method).
#define FF_ALLOC_DEFAULT // Only allocate as much as is needed. (Provides good performance, without wasting space).
//#define FF_ALLOC_DOUBLE // Doubles the size of a file each time allocation is required. (When high-performance writing is required).
//---------- Use Native STDIO.h
//#define FF_USE_NATIVE_STDIO // Makes FullFAT conform to values provided by your native STDIO.h file.
//---------- FREE SPACE CALCULATION
//#define FF_MOUNT_FIND_FREE // Uncomment this option to check for Freespace on a volume mount. (Performance Penalty while mounting).
// If not done in the mount, it will be done on the first call to FF_GetFreeSize() function.
//---------- FIND API WILD-CARD SUPPORT
#define FF_FINDAPI_ALLOW_WILDCARDS // Defined to enable Wild-cards in the API. Disabling this, makes the API consistent with 1.0.x series.
#define FF_WILDCARD_CASE_INSENSITIVE // Alter the case insensitivity of the Wild-card checking behaviour.
//---------- PATH CACHE ----------
#define FF_PATH_CACHE // Enables a simply Path Caching mechanism that increases performance of repeated operations
// within the same path. E.g. a copy \dir1\*.* \dir2\*.* command.
// This command requires FF_MAX_PATH number of bytes of memory. (Defined below, default 2600).
#define FF_PATH_CACHE_DEPTH 5 // The Number of PATH's to Cache. (Memory Requirement ~= FF_PATH_CACHE_DEPTH * FF_MAX_PATH).
//---------- HASH CACHE // Speed up File-creation with a HASH table. Provides up to 20x performance boost.
//#define FF_HASH_CACHE // Enable HASH to speed up file creation.
#define FF_HASH_CACHE_DEPTH 10 // Number of Directories to be Hashed. (For CRC16 memory is 8KB * DEPTH)
#define FF_HASH_FUNCTION CRC16 // Choose a 16-bit hash.
//#define FF_HASH_FUNCTION CRC8 // Choose an 8-bit hash.
//---------- BLKDEV USES SEMAPHORE
#define FF_BLKDEV_USES_SEM // When defined, each call to fnReadBlocks and fnWriteBlocks will be done while semaphore is locked
// See also ff_safety.c
// (HT addition) - Thanks to Hein Tibosch
//---------- MALLOC
// These should map on to platform specific memory allocators.
#define FF_MALLOC(aSize) FF_Malloc(aSize)
#define FF_FREE(apPtr) FF_Free(apPtr)
//---------- IN-LINE FUNCTIONS
//---------- INLINE KeyWord // Define FF_INLINE as your compiler's inline keyword. This is placed before the type qualifier.
#define FF_INLINE static __forceinline // Keywords to inline functions (Windows)
//#define FF_INLINE static inline // Standard for GCC
//---------- Inline Memory Independence Routines for better performance, but bigger codesize.
//#define FF_INLINE_MEMORY_ACCESS
//---------- Inline Block Calculation Routines for slightly better performance in critical sections.
//#define FF_INLINE_BLOCK_CALCULATIONS
//---------- 64-Bit Number Support //---------- 64-Bit Number Support
#define FF_64_NUM_SUPPORT // This helps to give information about the FreeSpace and VolumeSize of a partition or volume. #define FF_64_NUM_SUPPORT // This helps to give information about the FreeSpace and VolumeSize of a partition or volume.
// If you cannot support 64-bit integers, then FullFAT still works, its just that the functions: // If you cannot support 64-bit integers, then FullFAT still works, its just that the functions:
// FF_GetFreeSize() and FF_GetVolumeSize() don't make sense when reporting sizes > 4GB. // FF_GetFreeSize() and FF_GetVolumeSize() don't make sense when reporting sizes > 4GB.
//---------- Driver Sleep Time // How long FullFAT should sleep the thread for in ms, if FF_ERR_DRIVER_BUSY is recieved.
#define FF_DRIVER_BUSY_SLEEP 20
//---------- Debugging Features //---------- Driver Sleep Time
#define FF_DEBUG // Enable the Error Code string functions. const FF_T_INT8 *FF_GetErrMessage( FF_T_SINT32 iErrorCode); #define FF_DRIVER_BUSY_SLEEP 20 // How long FullFAT should sleep the thread for in ms, if FF_ERR_DRIVER_BUSY is recieved.
// Uncommenting this just stops FullFAT error strings being compiled.
//---------- Actively Determine if partition is FAT
#define FF_FAT_CHECK // This is experimental, so if FullFAT won't mount your volume, comment this out //---------- DEBUGGING FEATURES (HELPFUL ERROR MESSAGES)
// Also report the problem to james@worm.me.uk #define FF_DEBUG // Enable the Error Code string functions. const FF_T_INT8 *FF_GetErrMessage( FF_T_SINT32 iErrorCode);
// Uncommenting this just stops FullFAT error strings being compiled.
// Further calls to FF_GetErrMessage() are safe, and simply returns a pointer to a NULL string. ("").
// This should be disabled to reduce code-size dramatically.
//---------- AUTOMATIC SETTINGS DO NOT EDIT -- These configure your options from above, and check sanity! //---------- AUTOMATIC SETTINGS DO NOT EDIT -- These configure your options from above, and check sanity!
#ifdef FF_LFN_SUPPORT #ifdef FF_LFN_SUPPORT
#define FF_MAX_FILENAME 260 #define FF_MAX_FILENAME (260)
#else #else
#define FF_MAX_FILENAME 13 #define FF_MAX_FILENAME (13)
#endif #endif
#ifdef FF_USE_NATIVE_STDIO #ifdef FF_USE_NATIVE_STDIO
#ifdef MAX_PATH #ifdef MAX_PATH
#define FF_MAX_PATH MAX_PATH #define FF_MAX_PATH MAX_PATH
#elif PATH_MAX
#define FF_MAX_PATH PATH_MAX
#else #else
#define FF_MAX_PATH 2600 #define FF_MAX_PATH 2600
#endif #endif
@ -144,6 +185,16 @@
#endif #endif
#endif #endif
#ifdef FF_UNICODE_SUPPORT
#ifdef FF_UNICODE_UTF8_SUPPORT
#error FullFAT Invalid ff_config.h file: Must choose a single UNICODE support option. FF_UNICODE_SUPPORT for UTF-16, FF_UNICODE_UTF8_SUPPORT for UTF-8.
#endif
#endif
#ifndef FF_FAT_CHECK // FF_FAT_CHECK is now forced.
#define FF_FAT_CHECK
#endif
#ifndef FF_LITTLE_ENDIAN #ifndef FF_LITTLE_ENDIAN
#ifndef FF_BIG_ENDIAN #ifndef FF_BIG_ENDIAN
#error FullFAT Invalid ff_config.h file: An ENDIANESS must be defined for your platform. See ff_config.h file. #error FullFAT Invalid ff_config.h file: An ENDIANESS must be defined for your platform. See ff_config.h file.
@ -156,16 +207,18 @@
#endif #endif
#endif #endif
#ifdef FF_HASH_TABLE_SUPPORT #ifdef FF_HASH_CACHE
#if FF_HASH_FUNCTION == CRC16 #if FF_HASH_FUNCTION == CRC16
#define FF_HASH_TABLE_SIZE 8192 #define FF_HASH_TABLE_SIZE 8192
#elif FF_HASH_FUNCTION == CRC8 #elif FF_HASH_FUNCTION == CRC8
#define FF_HASH_TABLE_SIZE 32 #define FF_HASH_TABLE_SIZE 32
#else #else
#error Invalid Hashing function selected. CRC16 or CRC8! #error FullFAT Invalid ff_config.h file: Invalid Hashing function selected. CRC16 or CRC8!
#endif #endif
#endif #endif
#endif #endif
//---------- END-OF-CONFIGURATION

View file

@ -44,6 +44,7 @@
FF_T_UINT8 FF_GetCRC8 (FF_T_UINT8 *pbyData, FF_T_UINT32 stLength); FF_T_UINT8 FF_GetCRC8 (FF_T_UINT8 *pbyData, FF_T_UINT32 stLength);
FF_T_UINT16 FF_GetCRC16 (FF_T_UINT8 *pbyData, FF_T_UINT32 stLength); FF_T_UINT16 FF_GetCRC16 (FF_T_UINT8 *pbyData, FF_T_UINT32 stLength);
FF_T_UINT32 FF_GetCRC32 (FF_T_UINT8 *pbyData, FF_T_UINT32 stLength);
#endif #endif

View file

@ -43,7 +43,7 @@
#include "ff_ioman.h" #include "ff_ioman.h"
#include "ff_blk.h" #include "ff_blk.h"
#include "ff_fat.h" #include "ff_fat.h"
#include "fat.h" #include "ff_fatdef.h"
#include "ff_memory.h" #include "ff_memory.h"
#include "ff_time.h" #include "ff_time.h"
#include "ff_hash.h" #include "ff_hash.h"
@ -52,54 +52,118 @@
#include <string.h> #include <string.h>
typedef struct { typedef struct {
FF_T_INT8 FileName[FF_MAX_FILENAME]; FF_T_UINT32 ulChainLength;
FF_T_UINT8 Attrib; FF_T_UINT32 ulDirCluster;
FF_T_UINT32 ulCurrentClusterLCN;
FF_T_UINT32 ulCurrentClusterNum;
FF_T_UINT32 ulCurrentEntry;
FF_BUFFER *pBuffer;
} FF_FETCH_CONTEXT;
typedef struct {
FF_T_UINT32 Filesize; FF_T_UINT32 Filesize;
FF_T_UINT32 ObjectCluster; FF_T_UINT32 ObjectCluster;
// Book Keeping
FF_T_UINT32 CurrentCluster;
FF_T_UINT32 AddrCurrentCluster;
FF_T_UINT32 DirCluster;
FF_T_UINT16 CurrentItem;
// End Book Keeping
#ifdef FF_TIME_SUPPORT #ifdef FF_TIME_SUPPORT
FF_SYSTEMTIME CreateTime; ///< Date and Time Created. FF_SYSTEMTIME CreateTime; ///< Date and Time Created.
FF_SYSTEMTIME ModifiedTime; ///< Date and Time Modified. FF_SYSTEMTIME ModifiedTime; ///< Date and Time Modified.
FF_SYSTEMTIME AccessedTime; ///< Date of Last Access. FF_SYSTEMTIME AccessedTime; ///< Date of Last Access.
#endif #endif
//---- Book Keeping for FF_Find Functions #ifdef FF_FINDAPI_ALLOW_WILDCARDS
FF_T_UINT16 CurrentItem; #ifdef FF_UNICODE_SUPPORT
FF_T_UINT32 DirCluster; FF_T_WCHAR szWildCard[FF_MAX_FILENAME];
FF_T_UINT32 CurrentCluster; #else
FF_T_UINT32 AddrCurrentCluster; FF_T_INT8 szWildCard[FF_MAX_FILENAME];
//FF_T_UINT8 NumLFNs; #endif
#endif
#ifdef FF_UNICODE_SUPPORT
FF_T_WCHAR FileName[FF_MAX_FILENAME];
#else
FF_T_INT8 FileName[FF_MAX_FILENAME];
#endif
#if defined(FF_LFN_SUPPORT) && defined(FF_INCLUDE_SHORT_NAME)
FF_T_INT8 ShortName[13];
#endif
FF_T_UINT8 Attrib;
FF_FETCH_CONTEXT FetchContext;
} FF_DIRENT; } FF_DIRENT;
FF_ERROR FF_GetEntry (FF_IOMAN *pIoman, FF_T_UINT16 nEntry, FF_T_UINT32 DirCluster, FF_DIRENT *pDirent);
FF_T_SINT8 FF_PutEntry (FF_IOMAN *pIoman, FF_T_UINT16 Entry, FF_T_UINT32 DirCluster, FF_DIRENT *pDirent);
FF_T_SINT8 FF_FindEntry (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *Name, FF_DIRENT *pDirent, FF_T_BOOL LFNs);
FF_ERROR FF_FindFirst (FF_IOMAN *pIoman, FF_DIRENT *pDirent, const FF_T_INT8 *path);
FF_ERROR FF_FindNext (FF_IOMAN *pIoman, FF_DIRENT *pDirent);
void FF_PopulateShortDirent(FF_IOMAN *pIoman, FF_DIRENT *pDirent, FF_T_UINT8 *EntryBuffer);
FF_T_SINT8 FF_PopulateLongDirent(FF_IOMAN *pIoman, FF_DIRENT *pDirent, FF_T_UINT32 DirCluster, FF_T_UINT16 nEntry);
FF_T_SINT8 FF_FetchEntry (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT16 nEntry, FF_T_UINT8 *buffer);
FF_T_SINT8 FF_PushEntry (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT16 nEntry, FF_T_UINT8 *buffer);
FF_T_BOOL FF_isEndOfDir (FF_T_UINT8 *EntryBuffer);
FF_T_SINT8 FF_FindNextInDir(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_DIRENT *pDirent);
FF_T_UINT32 FF_FindEntryInDir(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *name, FF_T_UINT8 pa_Attrib, FF_DIRENT *pDirent);
FF_T_SINT8 FF_CreateShortName(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *ShortName, FF_T_INT8 *LongName);
void FF_lockDIR (FF_IOMAN *pIoman);
void FF_unlockDIR (FF_IOMAN *pIoman);
FF_T_UINT32 FF_CreateFile(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *FileName, FF_DIRENT *pDirent);
FF_ERROR FF_MkDir(FF_IOMAN *pIoman, const FF_T_INT8 *Path);
FF_T_SINT8 FF_CreateDirent(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_DIRENT *pDirent);
FF_T_SINT8 FF_ExtendDirectory(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster);
FF_T_UINT32 FF_FindDir(FF_IOMAN *pIoman, const FF_T_INT8 *path, FF_T_UINT16 pathLen);
FF_T_BOOL FF_CheckDirentHash(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT32 nHash); // PUBLIC API
FF_T_BOOL FF_DirHashed(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster); #ifdef FF_UNICODE_SUPPORT
FF_ERROR FF_AddDirentHash(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT32 nHash); FF_ERROR FF_FindFirst (FF_IOMAN *pIoman, FF_DIRENT *pDirent, const FF_T_WCHAR *path);
void FF_SetDirHashed(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster); FF_ERROR FF_MkDir (FF_IOMAN *pIoman, const FF_T_WCHAR *Path);
#else
FF_ERROR FF_FindFirst (FF_IOMAN *pIoman, FF_DIRENT *pDirent, const FF_T_INT8 *path);
FF_ERROR FF_MkDir (FF_IOMAN *pIoman, const FF_T_INT8 *Path);
#endif
void FF_RmLFNs(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT16 DirEntry); FF_ERROR FF_FindNext (FF_IOMAN *pIoman, FF_DIRENT *pDirent);
// INTERNAL API
FF_ERROR FF_GetEntry (FF_IOMAN *pIoman, FF_T_UINT16 nEntry, FF_T_UINT32 DirCluster, FF_DIRENT *pDirent);
FF_ERROR FF_PutEntry (FF_IOMAN *pIoman, FF_T_UINT16 Entry, FF_T_UINT32 DirCluster, FF_DIRENT *pDirent);
FF_T_SINT8 FF_FindEntry (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *Name, FF_DIRENT *pDirent, FF_T_BOOL LFNs);
void FF_PopulateShortDirent (FF_IOMAN *pIoman, FF_DIRENT *pDirent, FF_T_UINT8 *EntryBuffer);
FF_ERROR FF_PopulateLongDirent (FF_IOMAN *pIoman, FF_DIRENT *pDirent, FF_T_UINT16 nEntry, FF_FETCH_CONTEXT *pFetchContext);
FF_ERROR FF_InitEntryFetch (FF_IOMAN *pIoman, FF_T_UINT32 ulDirCluster, FF_FETCH_CONTEXT *pContext);
FF_ERROR FF_FetchEntryWithContext (FF_IOMAN *pIoman, FF_T_UINT32 ulEntry, FF_FETCH_CONTEXT *pContext, FF_T_UINT8 *pEntryBuffer);
FF_ERROR FF_PushEntryWithContext (FF_IOMAN *pIoman, FF_T_UINT32 ulEntry, FF_FETCH_CONTEXT *pContext, FF_T_UINT8 *pEntryBuffer);
void FF_CleanupEntryFetch (FF_IOMAN *pIoman, FF_FETCH_CONTEXT *pContext);
FF_T_SINT8 FF_PushEntry (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT16 nEntry, FF_T_UINT8 *buffer, void *pParam);
FF_T_BOOL FF_isEndOfDir (FF_T_UINT8 *EntryBuffer);
FF_ERROR FF_FindNextInDir (FF_IOMAN *pIoman, FF_DIRENT *pDirent, FF_FETCH_CONTEXT *pFetchContext);
#ifdef FF_UNICODE_SUPPORT
FF_T_UINT32 FF_FindEntryInDir (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, const FF_T_WCHAR *name, FF_T_UINT8 pa_Attrib, FF_DIRENT *pDirent, FF_ERROR *pError);
FF_T_SINT8 FF_CreateShortName (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_WCHAR *ShortName, FF_T_WCHAR *LongName);
#else
FF_T_UINT32 FF_FindEntryInDir (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, const FF_T_INT8 *name, FF_T_UINT8 pa_Attrib, FF_DIRENT *pDirent, FF_ERROR *pError);
FF_T_SINT8 FF_CreateShortName (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *ShortName, FF_T_INT8 *LongName);
#endif
void FF_lockDIR (FF_IOMAN *pIoman);
void FF_unlockDIR (FF_IOMAN *pIoman);
#ifdef FF_UNICODE_SUPPORT
FF_T_UINT32 FF_CreateFile(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_WCHAR *FileName, FF_DIRENT *pDirent, FF_ERROR *pError);
#else
FF_T_UINT32 FF_CreateFile(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *FileName, FF_DIRENT *pDirent, FF_ERROR *pError);
#endif
FF_ERROR FF_CreateDirent (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_DIRENT *pDirent);
FF_ERROR FF_ExtendDirectory (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster);
#ifdef FF_UNICODE_SUPPORT
FF_T_UINT32 FF_FindDir (FF_IOMAN *pIoman, const FF_T_WCHAR *path, FF_T_UINT16 pathLen, FF_ERROR *pError);
#else
FF_T_UINT32 FF_FindDir (FF_IOMAN *pIoman, const FF_T_INT8 *path, FF_T_UINT16 pathLen, FF_ERROR *pError);
#endif
#ifdef FF_HASH_CACHE
FF_T_BOOL FF_CheckDirentHash (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT32 nHash);
FF_T_BOOL FF_DirHashed (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster);
FF_ERROR FF_AddDirentHash (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT32 nHash);
FF_ERROR FF_HashDir (FF_IOMAN *pIoman, FF_T_UINT32 ulDirCluster);
#endif
FF_ERROR FF_RmLFNs(FF_IOMAN *pIoman, FF_T_UINT16 usDirEntry, FF_FETCH_CONTEXT *pContext);
#endif #endif

View file

@ -40,53 +40,111 @@
#include "ff_config.h" #include "ff_config.h"
#include "ff_types.h" #include "ff_types.h"
/**
Error codes are 32-bit numbers, and consist of three items:
8Bits 8bits 16bits
........ ........ ........ ........
[ModuleID][FunctionID][-- ERROR CODE --]
**/
#define FF_GETERROR(x) (x & 0x0000FFFF)
#define FF_MODULE_SHIFT 24
#define FF_FUNCTION_SHIFT 16
//----- FullFAT Module Identifiers
#define FF_MODULE_IOMAN (1 << FF_MODULE_SHIFT)
#define FF_MODULE_DIR (2 << FF_MODULE_SHIFT)
#define FF_MODULE_FILE (3 << FF_MODULE_SHIFT)
#define FF_MODULE_FAT (4 << FF_MODULE_SHIFT)
#define FF_MODULE_CRC (5 << FF_MODULE_SHIFT)
#define FF_MODULE_FORMAT (6 << FF_MODULE_SHIFT)
#define FF_MODULE_HASH (7 << FF_MODULE_SHIFT)
#define FF_MODULE_MEMORY (8 << FF_MODULE_SHIFT)
#define FF_MODULE_STRING (9 << FF_MODULE_SHIFT)
#define FF_MODULE_UNICODE (10 << FF_MODULE_SHIFT)
#define FF_MODULE_SAFETY (11 << FF_MODULE_SHIFT)
#define FF_MODULE_TIME (12 << FF_MODULE_SHIFT)
#define FF_MODULE_DRIVER (13 << FF_MODULE_SHIFT) // We can mark underlying platform error codes with this.
//----- FullFAT Function Identifiers (In Modular Order)
//----- FF_IOMAN - The FullFAT I/O Manager.
#define FF_CREATEIOMAN (1 << FF_FUNCTION_SHIFT) | FF_MODULE_IOMAN
#define FF_DESTROYIOMAN (2 << FF_FUNCTION_SHIFT) | FF_MODULE_IOMAN
#define FF_REGISTERBLKDEVICE (3 << FF_FUNCTION_SHIFT) | FF_MODULE_IOMAN
#define FF_UNREGISTERBLKDEVICE (4 << FF_FUNCTION_SHIFT) | FF_MODULE_IOMAN
#define FF_MOUNTPARTITION (5 << FF_FUNCTION_SHIFT) | FF_MODULE_IOMAN
#define FF_UNMOUNTPARTITION (6 << FF_FUNCTION_SHIFT) | FF_MODULE_IOMAN
#define FF_FLUSHCACHE (7 << FF_FUNCTION_SHIFT) | FF_MODULE_IOMAN
#define FF_GETPARTITIONBLOCKSIZE (8 << FF_FUNCTION_SHIFT) | FF_MODULE_IOMAN
#define FF_BLOCKREAD (9 << FF_FUNCTION_SHIFT) | FF_MODULE_IOMAN
#define FF_BLOCKWRITE (10 << FF_FUNCTION_SHIFT) | FF_MODULE_IOMAN
//----- FF_DIR - The FullFAT directory handling routines.
// -- COMPLETE THESE ERROR CODES TOMORROW :P
/* FullFAT defines different Error-Code spaces for each module. This ensures /* FullFAT defines different Error-Code spaces for each module. This ensures
that all error codes remain unique, and their meaning can be quickly identified. that all error codes remain unique, and their meaning can be quickly identified.
*/ */
// Global Error Codes // Global Error Codes
#define FF_ERR_NONE 0 ///< No Error #define FF_ERR_NONE 0 ///< No Error
#define FF_ERR_NULL_POINTER -2 ///< pIoman was NULL. //#define FF_ERR_GENERIC 1 ///< BAD NEVER USE THIS!
#define FF_ERR_NOT_ENOUGH_MEMORY -3 ///< malloc() failed! - Could not allocate handle memory. #define FF_ERR_NULL_POINTER 2 ///< pIoman was NULL.
#define FF_ERR_DEVICE_DRIVER_FAILED -4 ///< The Block Device driver reported a FATAL error, cannot continue. #define FF_ERR_NOT_ENOUGH_MEMORY 3 ///< malloc() failed! - Could not allocate handle memory.
#define FF_ERR_DEVICE_DRIVER_FAILED 4 ///< The Block Device driver reported a FATAL error, cannot continue.
// IOMAN Error Codes // IOMAN Error Codes
#define FF_ERR_IOMAN_BAD_BLKSIZE -11 ///< The provided blocksize was not a multiple of 512. #define FF_ERR_IOMAN_BAD_BLKSIZE 11 ///< The provided blocksize was not a multiple of 512.
#define FF_ERR_IOMAN_BAD_MEMSIZE -12 ///< The memory size was not a multiple of the blocksize. #define FF_ERR_IOMAN_BAD_MEMSIZE 12 ///< The memory size was not a multiple of the blocksize.
#define FF_ERR_IOMAN_DEV_ALREADY_REGD -13 ///< Device was already registered. Use FF_UnRegister() to re-use this IOMAN with another device. #define FF_ERR_IOMAN_DEV_ALREADY_REGD 13 ///< Device was already registered. Use FF_UnRegister() to re-use this IOMAN with another device.
#define FF_ERR_IOMAN_NO_MOUNTABLE_PARTITION -14 ///< A mountable partition could not be found on the device. #define FF_ERR_IOMAN_NO_MOUNTABLE_PARTITION 14 ///< A mountable partition could not be found on the device.
#define FF_ERR_IOMAN_INVALID_FORMAT -15 ///< The #define FF_ERR_IOMAN_INVALID_FORMAT 15 ///< The
#define FF_ERR_IOMAN_INVALID_PARTITION_NUM -16 ///< The partition number provided was out of range. #define FF_ERR_IOMAN_INVALID_PARTITION_NUM 16 ///< The partition number provided was out of range.
#define FF_ERR_IOMAN_NOT_FAT_FORMATTED -17 ///< The partition did not look like a FAT partition. #define FF_ERR_IOMAN_NOT_FAT_FORMATTED 17 ///< The partition did not look like a FAT partition.
#define FF_ERR_IOMAN_DEV_INVALID_BLKSIZE -18 ///< IOMAN object BlkSize is not compatible with the blocksize of this device driver. #define FF_ERR_IOMAN_DEV_INVALID_BLKSIZE 18 ///< IOMAN object BlkSize is not compatible with the blocksize of this device driver.
#define FF_ERR_IOMAN_PARTITION_MOUNTED -19 ///< Device is in use by an actively mounted partition. Unmount the partition first. #define FF_ERR_IOMAN_PARTITION_MOUNTED 19 ///< Device is in use by an actively mounted partition. Unmount the partition first.
#define FF_ERR_IOMAN_ACTIVE_HANDLES -20 ///< The partition cannot be unmounted until all active file handles are closed. (There may also be active handles on the cache). #define FF_ERR_IOMAN_ACTIVE_HANDLES 20 ///< The partition cannot be unmounted until all active file handles are closed. (There may also be active handles on the cache).
#define FF_ERR_IOMAN_GPT_HEADER_CORRUPT 21 ///< The GPT partition table appears to be corrupt, refusing to mount.
#define FF_ERR_IOMAN_NOT_ENOUGH_FREE_SPACE 22
#define FF_ERR_IOMAN_OUT_OF_BOUNDS_READ 23
#define FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE 24
// File Error Codes -30 + // File Error Codes 30 +
#define FF_ERR_FILE_ALREADY_OPEN -30 ///< File is in use. #define FF_ERR_FILE_ALREADY_OPEN 30 ///< File is in use.
#define FF_ERR_FILE_NOT_FOUND -31 ///< File was not found. #define FF_ERR_FILE_NOT_FOUND 31 ///< File was not found.
#define FF_ERR_FILE_OBJECT_IS_A_DIR -32 ///< Tried to FF_Open() a Directory. #define FF_ERR_FILE_OBJECT_IS_A_DIR 32 ///< Tried to FF_Open() a Directory.
#define FF_ERR_FILE_IS_READ_ONLY -33 ///< Tried to FF_Open() a file marked read only. #define FF_ERR_FILE_IS_READ_ONLY 33 ///< Tried to FF_Open() a file marked read only.
#define FF_ERR_FILE_INVALID_PATH -34 ///< The path of the file was not found. #define FF_ERR_FILE_INVALID_PATH 34 ///< The path of the file was not found.
#define FF_ERR_FILE_NOT_OPENED_IN_WRITE_MODE -35 #define FF_ERR_FILE_NOT_OPENED_IN_WRITE_MODE 35
#define FF_ERR_FILE_NOT_OPENED_IN_READ_MODE -36 #define FF_ERR_FILE_NOT_OPENED_IN_READ_MODE 36
#define FF_ERR_FILE_EXTEND_FAILED -37 ///< Could not extend the file. #define FF_ERR_FILE_EXTEND_FAILED 37 ///< Could not extend the file.
#define FF_ERR_FILE_DESTINATION_EXISTS -38 #define FF_ERR_FILE_DESTINATION_EXISTS 38
#define FF_ERR_FILE_SOURCE_NOT_FOUND -39 #define FF_ERR_FILE_SOURCE_NOT_FOUND 39
#define FF_ERR_FILE_DIR_NOT_FOUND -40 #define FF_ERR_FILE_DIR_NOT_FOUND 40
#define FF_ERR_FILE_COULD_NOT_CREATE_DIRENT -41 #define FF_ERR_FILE_COULD_NOT_CREATE_DIRENT 41
// Directory Error Codes -50 + // Directory Error Codes 50 +
#define FF_ERR_DIR_OBJECT_EXISTS -50 ///< A file or folder of the same name already exists in the current directory. #define FF_ERR_DIR_OBJECT_EXISTS 50 ///< A file or folder of the same name already exists in the current directory.
#define FF_ERR_DIR_DIRECTORY_FULL -51 ///< No more items could be added to the directory. #define FF_ERR_DIR_DIRECTORY_FULL 51 ///< No more items could be added to the directory.
#define FF_ERR_DIR_END_OF_DIR -52 /// #define FF_ERR_DIR_END_OF_DIR 52 ///
#define FF_ERR_DIR_NOT_EMPTY -53 ///< Cannot delete a directory that contains files or folders. #define FF_ERR_DIR_NOT_EMPTY 53 ///< Cannot delete a directory that contains files or folders.
#define FF_ERR_DIR_INVALID_PATH -54 ///< Could not find the directory specified by the path. #define FF_ERR_DIR_INVALID_PATH 54 ///< Could not find the directory specified by the path.
#define FF_ERR_DIR_CANT_EXTEND_ROOT_DIR -55 ///< Can't extend the root dir. #define FF_ERR_DIR_CANT_EXTEND_ROOT_DIR 55 ///< Can't extend the root dir.
#define FF_ERR_DIR_EXTEND_FAILED 56 ///< Not enough space to extend the directory.
#define FF_ERR_DIR_NAME_TOO_LONG 57 ///< Name exceeds the number of allowed charachters for a filename.
// Fat Error Codes -70 + // Fat Error Codes 70 +
#define FF_ERR_FAT_NO_FREE_CLUSTERS -70 ///< No more free space is available on the disk. #define FF_ERR_FAT_NO_FREE_CLUSTERS 70 ///< No more free space is available on the disk.
// UNICODE Error Codes 100 +
#define FF_ERR_UNICODE_INVALID_CODE 100 ///< An invalid Unicode charachter was provided!
#define FF_ERR_UNICODE_DEST_TOO_SMALL 101 ///< Not enough space in the UTF-16 buffer to encode the entire sequence as UTF-16.
#define FF_ERR_UNICODE_INVALID_SEQUENCE 102 ///< An invalid UTF-16 sequence was encountered.
#define FF_ERR_UNICODE_CONVERSION_EXCEEDED 103 ///< Filename exceeds MAX long-filename length when converted to UTF-16.
#ifdef FF_DEBUG #ifdef FF_DEBUG
const FF_T_INT8 *FF_GetErrMessage(FF_ERROR iErrorCode); const FF_T_INT8 *FF_GetErrMessage(FF_ERROR iErrorCode);

View file

@ -39,7 +39,7 @@
#define _FF_FAT_H_ #define _FF_FAT_H_
#include "ff_config.h" #include "ff_config.h"
#include "fat.h" #include "ff_fatdef.h"
#include "ff_ioman.h" #include "ff_ioman.h"
#include "ff_blk.h" #include "ff_blk.h"
#include "ff_types.h" #include "ff_types.h"
@ -52,24 +52,23 @@
FF_T_UINT32 FF_getRealLBA (FF_IOMAN *pIoman, FF_T_UINT32 LBA); FF_T_UINT32 FF_getRealLBA (FF_IOMAN *pIoman, FF_T_UINT32 LBA);
FF_T_UINT32 FF_Cluster2LBA (FF_IOMAN *pIoman, FF_T_UINT32 Cluster); FF_T_UINT32 FF_Cluster2LBA (FF_IOMAN *pIoman, FF_T_UINT32 Cluster);
FF_T_UINT32 FF_LBA2Cluster (FF_IOMAN *pIoman, FF_T_UINT32 Address); FF_T_UINT32 FF_LBA2Cluster (FF_IOMAN *pIoman, FF_T_UINT32 Address);
FF_T_SINT32 FF_getFatEntry (FF_IOMAN *pIoman, FF_T_UINT32 nCluster); FF_T_UINT32 FF_getFatEntry (FF_IOMAN *pIoman, FF_T_UINT32 nCluster, FF_ERROR *pError);
FF_ERROR FF_putFatEntry (FF_IOMAN *pIoman, FF_T_UINT32 nCluster, FF_T_UINT32 Value);
FF_T_BOOL FF_isEndOfChain (FF_IOMAN *pIoman, FF_T_UINT32 fatEntry); FF_T_BOOL FF_isEndOfChain (FF_IOMAN *pIoman, FF_T_UINT32 fatEntry);
FF_T_SINT8 FF_putFatEntry (FF_IOMAN *pIoman, FF_T_UINT32 nCluster, FF_T_UINT32 Value); FF_T_UINT32 FF_FindFreeCluster (FF_IOMAN *pIoman, FF_ERROR *pError);
FF_T_UINT32 FF_FindFreeCluster (FF_IOMAN *pIoman);
FF_T_UINT32 FF_ExtendClusterChain (FF_IOMAN *pIoman, FF_T_UINT32 StartCluster, FF_T_UINT32 Count); FF_T_UINT32 FF_ExtendClusterChain (FF_IOMAN *pIoman, FF_T_UINT32 StartCluster, FF_T_UINT32 Count);
FF_T_SINT8 FF_UnlinkClusterChain (FF_IOMAN *pIoman, FF_T_UINT32 StartCluster, FF_T_UINT16 Count); FF_ERROR FF_UnlinkClusterChain (FF_IOMAN *pIoman, FF_T_UINT32 StartCluster, FF_T_UINT16 Count);
FF_T_UINT32 FF_TraverseFAT (FF_IOMAN *pIoman, FF_T_UINT32 Start, FF_T_UINT32 Count); FF_T_UINT32 FF_TraverseFAT (FF_IOMAN *pIoman, FF_T_UINT32 Start, FF_T_UINT32 Count, FF_ERROR *pError);
FF_T_UINT32 FF_CreateClusterChain (FF_IOMAN *pIoman); FF_T_UINT32 FF_CreateClusterChain (FF_IOMAN *pIoman, FF_ERROR *pError);
FF_T_UINT32 FF_GetChainLength (FF_IOMAN *pIoman, FF_T_UINT32 pa_nStartCluster, FF_T_UINT32 *piEndOfChain); FF_T_UINT32 FF_GetChainLength (FF_IOMAN *pIoman, FF_T_UINT32 pa_nStartCluster, FF_T_UINT32 *piEndOfChain, FF_ERROR *pError);
FF_T_UINT32 FF_FindEndOfChain (FF_IOMAN *pIoman, FF_T_UINT32 Start); FF_T_UINT32 FF_FindEndOfChain (FF_IOMAN *pIoman, FF_T_UINT32 Start, FF_ERROR *pError);
FF_T_SINT8 FF_ClearCluster (FF_IOMAN *pIoman, FF_T_UINT32 nCluster); FF_ERROR FF_ClearCluster (FF_IOMAN *pIoman, FF_T_UINT32 nCluster);
#ifdef FF_64_NUM_SUPPORT #ifdef FF_64_NUM_SUPPORT
FF_T_UINT64 FF_GetFreeSize (FF_IOMAN *pIoman); FF_T_UINT64 FF_GetFreeSize (FF_IOMAN *pIoman, FF_ERROR *pError);
#else #else
FF_T_UINT32 FF_GetFreeSize (FF_IOMAN *pIoman); FF_T_UINT32 FF_GetFreeSize (FF_IOMAN *pIoman, FF_ERROR *pError);
#endif #endif
FF_T_UINT32 FF_FindFreeCluster (FF_IOMAN *pIoman); FF_T_UINT32 FF_CountFreeClusters (FF_IOMAN *pIoman, FF_ERROR *pError); // WARNING: If this protoype changes, it must be updated in ff_ioman.c also!
FF_T_UINT32 FF_CountFreeClusters (FF_IOMAN *pIoman);
void FF_lockFAT (FF_IOMAN *pIoman); void FF_lockFAT (FF_IOMAN *pIoman);
void FF_unlockFAT (FF_IOMAN *pIoman); void FF_unlockFAT (FF_IOMAN *pIoman);

View file

@ -0,0 +1,105 @@
/*****************************************************************************
* FullFAT - High Performance, Thread-Safe Embedded FAT File-System *
* Copyright (C) 2009 James Walmsley (james@worm.me.uk) *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
* IMPORTANT NOTICE: *
* ================= *
* Alternative Licensing is available directly from the Copyright holder, *
* (James Walmsley). For more information consult LICENSING.TXT to obtain *
* a Commercial license. *
* *
* See RESTRICTIONS.TXT for extra restrictions on the use of FullFAT. *
* *
* Removing the above notice is illegal and will invalidate this license. *
*****************************************************************************
* See http://worm.me.uk/fullfat for more information. *
* Or http://fullfat.googlecode.com/ for latest releases and the wiki. *
*****************************************************************************/
#ifndef _FF_FATDEF_H_
#define _FF_FATDEF_H_
/*
This file defines offsets to various data for the FAT specification.
*/
// MBR / PBR Offsets
#define FF_FAT_BYTES_PER_SECTOR 0x00B
#define FF_FAT_SECTORS_PER_CLUS 0x00D
#define FF_FAT_RESERVED_SECTORS 0x00E
#define FF_FAT_NUMBER_OF_FATS 0x010
#define FF_FAT_ROOT_ENTRY_COUNT 0x011
#define FF_FAT_16_TOTAL_SECTORS 0x013
#define FF_FAT_32_TOTAL_SECTORS 0x020
#define FF_FAT_16_SECTORS_PER_FAT 0x016
#define FF_FAT_32_SECTORS_PER_FAT 0x024
#define FF_FAT_ROOT_DIR_CLUSTER 0x02C
#define FF_FAT_16_VOL_LABEL 0x02B
#define FF_FAT_32_VOL_LABEL 0x047
#define FF_FAT_PTBL 0x1BE
#define FF_FAT_PTBL_LBA 0x008
#define FF_FAT_PTBL_ACTIVE 0x000
#define FF_FAT_PTBL_ID 0x004
#define FF_FAT_MBR_SIGNATURE 0x1FE
#define FF_FAT_DELETED 0xE5
// Directory Entry Offsets
#define FF_FAT_DIRENT_SHORTNAME 0x000
#define FF_FAT_DIRENT_ATTRIB 0x00B
#define FF_FAT_DIRENT_CREATE_TIME 0x00E ///< Creation Time.
#define FF_FAT_DIRENT_CREATE_DATE 0x010 ///< Creation Date.
#define FF_FAT_DIRENT_LASTACC_DATE 0x012 ///< Date of Last Access.
#define FF_FAT_DIRENT_CLUS_HIGH 0x014
#define FF_FAT_DIRENT_LASTMOD_TIME 0x016 ///< Time of Last modification.
#define FF_FAT_DIRENT_LASTMOD_DATE 0x018 ///< Date of Last modification.
#define FF_FAT_DIRENT_CLUS_LOW 0x01A
#define FF_FAT_DIRENT_FILESIZE 0x01C
#define FF_FAT_LFN_ORD 0x000
#define FF_FAT_LFN_NAME_1 0x001
#define FF_FAT_LFN_CHECKSUM 0x00D
#define FF_FAT_LFN_NAME_2 0x00E
#define FF_FAT_LFN_NAME_3 0x01C
// Dirent Attributes
#define FF_FAT_ATTR_READONLY 0x01
#define FF_FAT_ATTR_HIDDEN 0x02
#define FF_FAT_ATTR_SYSTEM 0x04
#define FF_FAT_ATTR_VOLID 0x08
#define FF_FAT_ATTR_DIR 0x10
#define FF_FAT_ATTR_ARCHIVE 0x20
#define FF_FAT_ATTR_LFN 0x0F
/**
* -- Hein_Tibosch additions for mixed case in shortnames --
*
* Specifically, bit 4 means lowercase extension and bit 3 lowercase basename,
* which allows for combinations such as "example.TXT" or "HELLO.txt" but not "Mixed.txt"
*/
#define FF_FAT_CASE_OFFS 0x0C ///< After NT/XP : 2 case bits
#define FF_FAT_CASE_ATTR_BASE 0x08
#define FF_FAT_CASE_ATTR_EXT 0x10
#if defined(FF_LFN_SUPPORT) && defined(FF_INCLUDE_SHORT_NAME)
#define FF_FAT_ATTR_IS_LFN 0x40 ///< artificial attribute, for debugging only
#endif
#endif

View file

@ -75,19 +75,29 @@ typedef struct _FF_FILE {
//---------- PROTOTYPES //---------- PROTOTYPES
// PUBLIC (Interfaces): // PUBLIC (Interfaces):
FF_FILE *FF_Open (FF_IOMAN *pIoman, const FF_T_INT8 *path, FF_T_UINT8 Mode, FF_ERROR *pError); #ifdef FF_UNICODE_SUPPORT
FF_FILE *FF_Open(FF_IOMAN *pIoman, const FF_T_WCHAR *path, FF_T_UINT8 Mode, FF_ERROR *pError);
FF_T_BOOL FF_isDirEmpty (FF_IOMAN *pIoman, const FF_T_WCHAR *Path);
FF_ERROR FF_RmFile (FF_IOMAN *pIoman, const FF_T_WCHAR *path);
FF_ERROR FF_RmDir (FF_IOMAN *pIoman, const FF_T_WCHAR *path);
FF_ERROR FF_Move (FF_IOMAN *pIoman, const FF_T_WCHAR *szSourceFile, const FF_T_WCHAR *szDestinationFile);
#else
FF_FILE *FF_Open(FF_IOMAN *pIoman, const FF_T_INT8 *path, FF_T_UINT8 Mode, FF_ERROR *pError);
FF_T_BOOL FF_isDirEmpty (FF_IOMAN *pIoman, const FF_T_INT8 *Path);
FF_ERROR FF_RmFile (FF_IOMAN *pIoman, const FF_T_INT8 *path);
FF_ERROR FF_RmDir (FF_IOMAN *pIoman, const FF_T_INT8 *path);
FF_ERROR FF_Move (FF_IOMAN *pIoman, const FF_T_INT8 *szSourceFile, const FF_T_INT8 *szDestinationFile);
#endif
FF_ERROR FF_Close (FF_FILE *pFile); FF_ERROR FF_Close (FF_FILE *pFile);
FF_T_SINT32 FF_GetC (FF_FILE *pFile); FF_T_SINT32 FF_GetC (FF_FILE *pFile);
FF_T_SINT32 FF_GetLine (FF_FILE *pFile, FF_T_INT8 *szLine, FF_T_UINT32 ulLimit);
FF_T_SINT32 FF_Read (FF_FILE *pFile, FF_T_UINT32 ElementSize, FF_T_UINT32 Count, FF_T_UINT8 *buffer); FF_T_SINT32 FF_Read (FF_FILE *pFile, FF_T_UINT32 ElementSize, FF_T_UINT32 Count, FF_T_UINT8 *buffer);
FF_T_SINT32 FF_Write (FF_FILE *pFile, FF_T_UINT32 ElementSize, FF_T_UINT32 Count, FF_T_UINT8 *buffer); FF_T_SINT32 FF_Write (FF_FILE *pFile, FF_T_UINT32 ElementSize, FF_T_UINT32 Count, FF_T_UINT8 *buffer);
FF_T_BOOL FF_isEOF (FF_FILE *pFile); FF_T_BOOL FF_isEOF (FF_FILE *pFile);
FF_ERROR FF_Seek (FF_FILE *pFile, FF_T_SINT32 Offset, FF_T_INT8 Origin); FF_ERROR FF_Seek (FF_FILE *pFile, FF_T_SINT32 Offset, FF_T_INT8 Origin);
FF_T_SINT32 FF_PutC (FF_FILE *pFile, FF_T_UINT8 Value); FF_T_SINT32 FF_PutC (FF_FILE *pFile, FF_T_UINT8 Value);
FF_T_UINT32 FF_Tell (FF_FILE *pFile); FF_T_UINT32 FF_Tell (FF_FILE *pFile);
FF_ERROR FF_RmFile (FF_IOMAN *pIoman, const FF_T_INT8 *path);
FF_ERROR FF_RmDir (FF_IOMAN *pIoman, const FF_T_INT8 *path);
FF_T_BOOL FF_isDirEmpty (FF_IOMAN *pIoman, const FF_T_INT8 *Path);
FF_ERROR FF_Move (FF_IOMAN *pIoman, const FF_T_INT8 *szSourceFile, const FF_T_INT8 *szDestinationFile);
FF_T_UINT8 FF_GetModeBits (FF_T_INT8 *Mode); FF_T_UINT8 FF_GetModeBits (FF_T_INT8 *Mode);
// Private : // Private :

View file

@ -0,0 +1,47 @@
/*****************************************************************************
* FullFAT - High Performance, Thread-Safe Embedded FAT File-System *
* Copyright (C) 2009 James Walmsley (james@worm.me.uk) *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
* IMPORTANT NOTICE: *
* ================= *
* Alternative Licensing is available directly from the Copyright holder, *
* (James Walmsley). For more information consult LICENSING.TXT to obtain *
* a Commercial license. *
* *
* See RESTRICTIONS.TXT for extra restrictions on the use of FullFAT. *
* *
* Removing the above notice is illegal and will invalidate this license. *
*****************************************************************************
* See http://worm.me.uk/fullfat for more information. *
* Or http://fullfat.googlecode.com/ for latest releases and the wiki. *
*****************************************************************************/
/**
* @file ff_format.c
* @author James Walmsley
* @ingroup FORMAT
*
**/
#ifndef _FF_FORMAT_H_
#define _FF_FORMAT_H_
#endif

View file

@ -87,8 +87,8 @@ typedef FF_T_SINT32 (*FF_READ_BLOCKS) (FF_T_UINT8 *pBuffer, FF_T_UINT32 SectorAd
* @brief Describes the block device driver interface to FullFAT. * @brief Describes the block device driver interface to FullFAT.
**/ **/
typedef struct { typedef struct {
FF_WRITE_BLOCKS fnWriteBlocks; ///< Function Pointer, to write a block(s) from a block device. FF_WRITE_BLOCKS fnpWriteBlocks; ///< Function Pointer, to write a block(s) from a block device.
FF_READ_BLOCKS fnReadBlocks; ///< Function Pointer, to read a block(s) from a block device. FF_READ_BLOCKS fnpReadBlocks; ///< Function Pointer, to read a block(s) from a block device.
FF_T_UINT16 devBlkSize; ///< Block size that the driver deals with. FF_T_UINT16 devBlkSize; ///< Block size that the driver deals with.
void *pParam; ///< Pointer to some parameters e.g. for a Low-Level Driver Handle void *pParam; ///< Pointer to some parameters e.g. for a Low-Level Driver Handle
} FF_BLK_DEVICE; } FF_BLK_DEVICE;
@ -100,24 +100,33 @@ typedef struct {
**/ **/
typedef struct { typedef struct {
FF_T_UINT32 Sector; ///< The LBA of the Cached sector. FF_T_UINT32 Sector; ///< The LBA of the Cached sector.
FF_T_UINT8 Mode; ///< Read or Write mode. FF_T_UINT32 LRU; ///< For the Least Recently Used algorithm.
FF_T_UINT16 NumHandles; ///< Number of objects using this buffer. FF_T_UINT16 NumHandles; ///< Number of objects using this buffer.
FF_T_UINT16 Persistance; ///< For the persistance algorithm. FF_T_UINT16 Persistance; ///< For the persistance algorithm.
FF_T_UINT32 LRU; ///< For the Least Recently Used algorithm. FF_T_UINT8 Mode; ///< Read or Write mode.
FF_T_BOOL Modified; ///< If the sector was modified since read. FF_T_BOOL Modified; ///< If the sector was modified since read.
FF_T_BOOL Valid; ///< Initially FALSE. FF_T_BOOL Valid; ///< Initially FALSE.
FF_T_UINT8 *pBuffer; ///< Pointer to the cache block. FF_T_UINT8 *pBuffer; ///< Pointer to the cache block.
} FF_BUFFER; } FF_BUFFER;
typedef struct { typedef struct {
#ifdef FF_UNICODE_SUPPORT
FF_T_WCHAR Path[FF_MAX_PATH];
#else
FF_T_INT8 Path[FF_MAX_PATH]; FF_T_INT8 Path[FF_MAX_PATH];
FF_T_UINT32 DirCluster;
#ifdef FF_HASH_TABLE_SUPPORT
FF_HASH_TABLE pHashTable;
FF_T_BOOL bHashed;
#endif #endif
FF_T_UINT32 DirCluster;
} FF_PATHCACHE; } FF_PATHCACHE;
#ifdef FF_HASH_CACHE
typedef struct {
FF_T_UINT32 ulDirCluster; ///< The Starting Cluster of the dir that the hash represents.
FF_HASH_TABLE pHashTable; ///< Pointer to the Hash Table object.
FF_T_UINT32 ulNumHandles; ///< Number of active Handles using this hash table.
FF_T_UINT32 ulMisses; ///< Number of times this Hash Table was missed, (i.e. how redundant it is).
} FF_HASHCACHE;
#endif
/** /**
* @private * @private
* @brief FullFAT identifies a partition with the following data. * @brief FullFAT identifies a partition with the following data.
@ -129,7 +138,7 @@ typedef struct {
FF_T_UINT16 BlkSize; ///< Size of a Sector Block in bytes. FF_T_UINT16 BlkSize; ///< Size of a Sector Block in bytes.
FF_T_UINT8 BlkFactor; ///< Scale Factor for blocksizes above 512! FF_T_UINT8 BlkFactor; ///< Scale Factor for blocksizes above 512!
//FF_T_INT8 Name[FF_MAX_PARTITION_NAME]; ///< Partition Identifier e.g. c: sd0: etc. //FF_T_INT8 Name[FF_MAX_PARTITION_NAME]; ///< Partition Identifier e.g. c: sd0: etc.
//FF_T_INT8 VolLabel[12]; ///< Volume Label of the partition. FF_T_INT8 VolLabel[12]; ///< Volume Label of the partition.
FF_T_UINT32 BeginLBA; ///< LBA start address of the partition. FF_T_UINT32 BeginLBA; ///< LBA start address of the partition.
FF_T_UINT32 PartSize; ///< Size of Partition in number of sectors. FF_T_UINT32 PartSize; ///< Size of Partition in number of sectors.
FF_T_UINT32 FatBeginLBA; ///< LBA of the FAT tables. FF_T_UINT32 FatBeginLBA; ///< LBA of the FAT tables.
@ -182,14 +191,21 @@ typedef struct {
FF_BLK_DEVICE *pBlkDevice; ///< Pointer to a Block device description. FF_BLK_DEVICE *pBlkDevice; ///< Pointer to a Block device description.
FF_PARTITION *pPartition; ///< Pointer to a partition description. FF_PARTITION *pPartition; ///< Pointer to a partition description.
FF_BUFFER *pBuffers; ///< Pointer to the first buffer description. FF_BUFFER *pBuffers; ///< Pointer to the first buffer description.
void *pSemaphore; ///< Pointer to a Semaphore object. (For buffer description modifications only!).
#ifdef FF_BLKDEV_USES_SEM
void *pBlkDevSemaphore; ///< Semaphore to guarantee Atomic access to the underlying block device, if required.
#endif
void *FirstFile; ///< Pointer to the first File object.
FF_T_UINT8 *pCacheMem; ///< Pointer to a block of memory for the cache.
FF_T_UINT32 LastReplaced; ///< Marks which sector was last replaced in the cache. FF_T_UINT32 LastReplaced; ///< Marks which sector was last replaced in the cache.
FF_T_UINT16 BlkSize; ///< The Block size that IOMAN is configured to. FF_T_UINT16 BlkSize; ///< The Block size that IOMAN is configured to.
FF_T_UINT8 *pCacheMem; ///< Pointer to a block of memory for the cache.
FF_T_UINT16 CacheSize; ///< Size of the cache in number of Sectors. FF_T_UINT16 CacheSize; ///< Size of the cache in number of Sectors.
FF_T_UINT8 PreventFlush; ///< Flushing to disk only allowed when 0
FF_T_UINT8 MemAllocation; ///< Bit-Mask identifying allocated pointers. FF_T_UINT8 MemAllocation; ///< Bit-Mask identifying allocated pointers.
FF_T_UINT8 Locks; ///< Lock Flag for FAT & DIR Locking etc (This must be accessed via a semaphore). FF_T_UINT8 Locks; ///< Lock Flag for FAT & DIR Locking etc (This must be accessed via a semaphore).
void *pSemaphore; ///< Pointer to a Semaphore object. (For buffer description modifications only!). #ifdef FF_HASH_CACHE
void *FirstFile; ///< Pointer to the first File object. FF_HASHCACHE HashCache[FF_HASH_CACHE_DEPTH];
#endif
} FF_IOMAN; } FF_IOMAN;
// Bit-Masks for Memory Allocation testing. // Bit-Masks for Memory Allocation testing.
@ -219,6 +235,8 @@ FF_T_UINT32 FF_GetVolumeSize(FF_IOMAN *pIoman);
#endif #endif
// PUBLIC (To FullFAT Only): // PUBLIC (To FullFAT Only):
FF_T_SINT32 FF_BlockRead (FF_IOMAN *pIoman, FF_T_UINT32 ulSectorLBA, FF_T_UINT32 ulNumSectors, void *pBuffer);
FF_T_SINT32 FF_BlockWrite (FF_IOMAN *pIoman, FF_T_UINT32 ulSectorLBA, FF_T_UINT32 ulNumSectors, void *pBuffer);
FF_ERROR FF_IncreaseFreeClusters (FF_IOMAN *pIoman, FF_T_UINT32 Count); FF_ERROR FF_IncreaseFreeClusters (FF_IOMAN *pIoman, FF_T_UINT32 Count);
FF_ERROR FF_DecreaseFreeClusters (FF_IOMAN *pIoman, FF_T_UINT32 Count); FF_ERROR FF_DecreaseFreeClusters (FF_IOMAN *pIoman, FF_T_UINT32 Count);
FF_BUFFER *FF_GetBuffer (FF_IOMAN *pIoman, FF_T_UINT32 Sector, FF_T_UINT8 Mode); FF_BUFFER *FF_GetBuffer (FF_IOMAN *pIoman, FF_T_UINT32 Sector, FF_T_UINT8 Mode);

View file

@ -41,19 +41,125 @@
#include "ff_config.h" #include "ff_config.h"
#include "ff_types.h" #include "ff_types.h"
#ifdef __REACTOS__
// defined in fullfat.c
void *FF_Malloc(FF_T_UINT32 allocSize);
void FF_Free(void *pBuffer);
#endif
/*
HT changed type of aOffset to u32
*/
//---------- PROTOTYPES //---------- PROTOTYPES
FF_T_UINT8 FF_getChar (FF_T_UINT8 *pBuffer, FF_T_UINT16 offset); #if defined(FF_LITTLE_ENDIAN)
FF_T_UINT16 FF_getShort (FF_T_UINT8 *pBuffer, FF_T_UINT16 offset);
FF_T_UINT32 FF_getLong (FF_T_UINT8 *pBuffer, FF_T_UINT16 offset);
void FF_putChar (FF_T_UINT8 *pBuffer, FF_T_UINT16 offset, FF_T_UINT8 Value); typedef struct {
void FF_putShort (FF_T_UINT8 *pBuffer, FF_T_UINT16 offset, FF_T_UINT16 Value); FF_T_UINT8 u8_0;
void FF_putLong (FF_T_UINT8 *pBuffer, FF_T_UINT16 offset, FF_T_UINT32 Value); FF_T_UINT8 u8_1;
} FF_T_SHORT;
void *FF_Malloc(FF_T_UINT32 allocSize); typedef struct {
void FF_Free(void *pBuffer); FF_T_UINT8 u8_0;
FF_T_UINT8 u8_1;
FF_T_UINT8 u8_2;
FF_T_UINT8 u8_3;
} FF_T_LONG;
#elif defined(FF_BIG_ENDIAN)
typedef struct {
FF_T_UINT8 u8_1;
FF_T_UINT8 u8_0;
} FF_T_SHORT;
typedef struct {
FF_T_UINT8 u8_3;
FF_T_UINT8 u8_2;
FF_T_UINT8 u8_1;
FF_T_UINT8 u8_0;
} FF_T_LONG;
#else
#error Little or Big Endian? - Please set an endianess in ff_config.h
#endif
//! 16-bit union.
typedef union {
FF_T_UINT16 u16;
FF_T_SHORT bytes;
} FF_T_UN16;
//! 32-bit union.
typedef union {
FF_T_UINT32 u32;
FF_T_LONG bytes;
} FF_T_UN32;
/* HT inlined these functions:
*/
#ifdef FF_INLINE_MEMORY_ACCESS
FF_INLINE FF_T_UINT8 FF_getChar(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset)
{
return (FF_T_UINT8) (pBuffer[aOffset]);
}
FF_INLINE FF_T_UINT16 FF_getShort(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset)
{
FF_T_UN16 u16;
pBuffer += aOffset;
u16.bytes.u8_1 = pBuffer[1];
u16.bytes.u8_0 = pBuffer[0];
return u16.u16;
}
FF_INLINE FF_T_UINT32 FF_getLong(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset) {
FF_T_UN32 u32;
pBuffer += aOffset;
u32.bytes.u8_3 = pBuffer[3];
u32.bytes.u8_2 = pBuffer[2];
u32.bytes.u8_1 = pBuffer[1];
u32.bytes.u8_0 = pBuffer[0];
return u32.u32;
}
FF_INLINE void FF_putChar(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset, FF_T_UINT8 Value) {
pBuffer[aOffset] = Value;
}
FF_INLINE void FF_putShort(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset, FF_T_UINT16 Value) {
FF_T_UN16 u16;
u16.u16 = Value;
pBuffer += aOffset;
pBuffer[0] = u16.bytes.u8_0;
pBuffer[1] = u16.bytes.u8_1;
}
FF_INLINE void FF_putLong(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset, FF_T_UINT32 Value) {
FF_T_UN32 u32;
u32.u32 = Value;
pBuffer += aOffset;
pBuffer[0] = u32.bytes.u8_0;
pBuffer[1] = u32.bytes.u8_1;
pBuffer[2] = u32.bytes.u8_2;
pBuffer[3] = u32.bytes.u8_3;
}
#else
FF_T_UINT8 FF_getChar(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset);
FF_T_UINT16 FF_getShort(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset);
FF_T_UINT32 FF_getLong(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset);
void FF_putChar(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset, FF_T_UINT8 Value);
void FF_putShort(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset, FF_T_UINT16 Value);
void FF_putLong(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset, FF_T_UINT32 Value);
#endif
#endif #endif

View file

@ -44,11 +44,35 @@
#define _FF_STRING_H_ #define _FF_STRING_H_
#include "ff_types.h" #include "ff_types.h"
#include "ff_config.h"
#include <string.h>
void FF_tolower (FF_T_INT8 *string, FF_T_UINT32 strLen); #ifdef WIN32
void FF_toupper (FF_T_INT8 *string, FF_T_UINT32 strLen); #define FF_stricmp stricmp
FF_T_BOOL FF_strmatch (const FF_T_INT8 *str1, const FF_T_INT8 *str2, FF_T_UINT16 len); #else
FF_T_INT8 *FF_strtok (const FF_T_INT8 *string, FF_T_INT8 *token, FF_T_UINT16 *tokenNumber, FF_T_BOOL *last, FF_T_UINT16 Length); #define FF_stricmp strcasecmp
FF_T_BOOL FF_wildcompare(const FF_T_INT8 *pszWildCard, const FF_T_INT8 *pszString); #endif
#ifdef FF_UNICODE_SUPPORT
void FF_tolower (FF_T_WCHAR *string, FF_T_UINT32 strLen);
void FF_toupper (FF_T_WCHAR *string, FF_T_UINT32 strLen);
FF_T_BOOL FF_strmatch (const FF_T_WCHAR *str1, const FF_T_WCHAR *str2, FF_T_UINT16 len);
FF_T_WCHAR *FF_strtok (const FF_T_WCHAR *string, FF_T_WCHAR *token, FF_T_UINT16 *tokenNumber, FF_T_BOOL *last, FF_T_UINT16 Length);
FF_T_BOOL FF_wildcompare (const FF_T_WCHAR *pszWildCard, const FF_T_WCHAR *pszString);
// ASCII to UTF16 and UTF16 to ASCII routines. -- These are lossy routines, and are only for converting ASCII to UTF-16
// and the equivalent back to ASCII. Do not use them for international text.
void FF_cstrtowcs(FF_T_WCHAR *wcsDest, const FF_T_INT8 *szpSource);
void FF_wcstocstr(FF_T_INT8 *szpDest, const FF_T_WCHAR *wcsSource);
void FF_cstrntowcs(FF_T_WCHAR *wcsDest, const FF_T_INT8 *szpSource, FF_T_UINT32 len);
void FF_wcsntocstr(FF_T_INT8 *szpDest, const FF_T_WCHAR *wcsSource, FF_T_UINT32 len);
#else
void FF_tolower (FF_T_INT8 *string, FF_T_UINT32 strLen);
void FF_toupper (FF_T_INT8 *string, FF_T_UINT32 strLen);
FF_T_BOOL FF_strmatch (const FF_T_INT8 *str1, const FF_T_INT8 *str2, FF_T_UINT16 len);
FF_T_INT8 *FF_strtok (const FF_T_INT8 *string, FF_T_INT8 *token, FF_T_UINT16 *tokenNumber, FF_T_BOOL *last, FF_T_UINT16 Length);
FF_T_BOOL FF_wildcompare (const FF_T_INT8 *pszWildCard, const FF_T_INT8 *pszString);
#endif
#endif #endif

View file

@ -61,6 +61,11 @@ typedef long FF_T_INT32; ///< 32 bit default integer.
typedef unsigned long FF_T_UINT32; ///< 32 bit unsigned integer. typedef unsigned long FF_T_UINT32; ///< 32 bit unsigned integer.
typedef signed long FF_T_SINT32; ///< 32 bit signed integer. typedef signed long FF_T_SINT32; ///< 32 bit signed integer.
//---------------- Platform Integer Sizes
typedef int FF_T_INT;
typedef unsigned int FF_T_UINT;
typedef signed int FF_T_SINT;
#ifdef FF_64_NUM_SUPPORT #ifdef FF_64_NUM_SUPPORT
//---------------- 64 BIT INTEGERS // If you cannot define these, then make sure you see ff_config.h //---------------- 64 BIT INTEGERS // If you cannot define these, then make sure you see ff_config.h
typedef long long FF_T_INT64; // about 64-bit number support. typedef long long FF_T_INT64; // about 64-bit number support.
@ -70,5 +75,9 @@ typedef signed long long FF_T_SINT64; // > 4GB in bytes if you cannot support 64
#endif #endif
typedef FF_T_SINT32 FF_ERROR; ///< A special error code type to ease some inconsistencies in Error reporting. typedef FF_T_SINT32 FF_ERROR; ///< A special error code type to ease some inconsistencies in Error reporting.
#ifdef FF_UNICODE_SUPPORT
#include <wchar.h>
typedef wchar_t FF_T_WCHAR; ///< Unicode UTF-16 Charachter type, for FullFAT when UNICODE is enabled.
#endif
#endif // end of include guard #endif // end of include guard

View file

@ -0,0 +1,60 @@
/*****************************************************************************
* FullFAT - High Performance, Thread-Safe Embedded FAT File-System *
* Copyright (C) 2009 James Walmsley (james@worm.me.uk) *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
* IMPORTANT NOTICE: *
* ================= *
* Alternative Licensing is available directly from the Copyright holder, *
* (James Walmsley). For more information consult LICENSING.TXT to obtain *
* a Commercial license. *
* *
* See RESTRICTIONS.TXT for extra restrictions on the use of FullFAT. *
* *
* Removing the above notice is illegal and will invalidate this license. *
*****************************************************************************
* See http://worm.me.uk/fullfat for more information. *
* Or http://fullfat.googlecode.com/ for latest releases and the wiki. *
*****************************************************************************/
/**
* @file ff_unicode.c
* @author James Walmsley
* @ingroup UNICODE
*
**/
#ifndef _FF_UNICODE_H_
#define _FF_UNICODE_H_
#include "ff_config.h"
#include "ff_types.h"
#include "ff_error.h"
// UTF8 / UTF16 Transformation Functions
FF_T_UINT FF_GetUtf16SequenceLen (FF_T_UINT16 usLeadChar);
FF_T_SINT32 FF_Utf8ctoUtf16c (FF_T_UINT16 *utf16Dest, const FF_T_UINT8 *utf8Source, FF_T_UINT32 ulSize);
FF_T_SINT32 FF_Utf16ctoUtf8c (FF_T_UINT8 *utf8Dest, const FF_T_UINT16 *utf16Source, FF_T_UINT32 ulSize);
// UTF16 / UTF32 Transformation Functions
FF_T_SINT32 FF_Utf16ctoUtf32c(FF_T_UINT32 *utf32Dest, const FF_T_UINT16 *utf16Source);
FF_T_SINT32 FF_Utf32ctoUtf16c(FF_T_UINT16 *utf16Dest, FF_T_UINT32 utf32char, FF_T_UINT32 ulSize);
// String transformations
FF_T_SINT32 FF_Utf32stoUtf8s(FF_T_UINT8 *Utf8String, FF_T_UINT32 *Utf32String);
#endif

View file

@ -32,6 +32,10 @@
#ifndef _FULLFAT_H_ #ifndef _FULLFAT_H_
#define _FULLFAT_H_ #define _FULLFAT_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "ff_config.h" #include "ff_config.h"
#include "ff_ioman.h" #include "ff_ioman.h"
#include "ff_fat.h" #include "ff_fat.h"
@ -41,6 +45,11 @@
#include "ff_crc.h" #include "ff_crc.h"
#include "ff_hash.h" #include "ff_hash.h"
#include "ff_string.h" #include "ff_string.h"
#include "ff_unicode.h"
//#include "ff_format.h"
#ifdef __cplusplus
} // extern "C"
#endif
#endif #endif

View file

@ -1761,18 +1761,11 @@ NtUserGetClassInfo(HINSTANCE hInstance,
LPWSTR *ppszMenuName, LPWSTR *ppszMenuName,
BOOL Ansi); BOOL Ansi);
INT
NTAPI
NtUserGetClassName(HWND hWnd,
PUNICODE_STRING ClassName,
BOOL Ansi);
#if 0 // Real NtUserGetClassName
INT INT
NTAPI NTAPI
NtUserGetClassName(HWND hWnd, NtUserGetClassName(HWND hWnd,
BOOL Real, // 0 GetClassNameW, 1 RealGetWindowClassA/W BOOL Real, // 0 GetClassNameW, 1 RealGetWindowClassA/W
PUNICODE_STRING ClassName); PUNICODE_STRING ClassName);
#endif
HANDLE HANDLE
NTAPI NTAPI
@ -2411,28 +2404,28 @@ NtUserQueryWindow(
HWND hWnd, HWND hWnd,
DWORD Index); DWORD Index);
DWORD BOOL
NTAPI NTAPI
NtUserRealInternalGetMessage( NtUserRealInternalGetMessage(
DWORD dwUnknown1, LPMSG lpMsg,
DWORD dwUnknown2, HWND hWnd,
DWORD dwUnknown3, UINT wMsgFilterMin,
DWORD dwUnknown4, UINT wMsgFilterMax,
DWORD dwUnknown5, UINT wRemoveMsg,
DWORD dwUnknown6); BOOL bGMSG);
DWORD HWND
NTAPI NTAPI
NtUserRealChildWindowFromPoint( NtUserRealChildWindowFromPoint(
DWORD Unknown0, HWND Parent,
DWORD Unknown1, LONG x,
DWORD Unknown2); LONG y);
DWORD BOOL
NTAPI NTAPI
NtUserRealWaitMessageEx( NtUserRealWaitMessageEx(
DWORD dwUnknown1, DWORD dwWakeMask,
DWORD dwUnknown2); UINT uTimeout);
BOOL BOOL
NTAPI NTAPI

View file

@ -41,7 +41,68 @@
#include "ff_crc.h" #include "ff_crc.h"
static const FF_T_UINT8 CRC16_Low[256] =
static const FF_T_UINT32 crc32_table[256] = {
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
};
FF_T_UINT32 FF_GetCRC32(FF_T_UINT8 *pbyData, FF_T_UINT32 stLength) {
register FF_T_UINT32 crc = 0xFFFFFFFF;
while(stLength--) {
crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32_table[(crc^*pbyData++) & 0x000000FF];
}
return (crc ^ 0xFFFFFFFF);
}
static const FF_T_UINT8 crc16_table_low[256] =
{ {
0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041,
0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040,
@ -77,7 +138,7 @@ static const FF_T_UINT8 CRC16_Low[256] =
0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040, 0x001, 0x0c0, 0x080, 0x041, 0x000, 0x0c1, 0x081, 0x040,
}; };
static const FF_T_UINT8 CRC16_High[256] = static const FF_T_UINT8 crc16_table_high[256] =
{ {
0x000, 0x0c0, 0x0c1, 0x001, 0x0c3, 0x003, 0x002, 0x0c2, 0x000, 0x0c0, 0x0c1, 0x001, 0x0c3, 0x003, 0x002, 0x0c2,
0x0c6, 0x006, 0x007, 0x0c7, 0x005, 0x0c5, 0x0c4, 0x004, 0x0c6, 0x006, 0x007, 0x0c7, 0x005, 0x0c5, 0x0c4, 0x004,
@ -130,15 +191,15 @@ FF_T_UINT16 FF_GetCRC16(FF_T_UINT8 *pbyData, FF_T_UINT32 stLength) {
while (stLength--) { while (stLength--) {
bTableValue = (FF_T_UINT8)((wCRC & 0x00FF) ^ *pbyData++); bTableValue = (FF_T_UINT8)((wCRC & 0x00FF) ^ *pbyData++);
wCRC = (FF_T_UINT16)(((CRC16_High[bTableValue]) << 8) wCRC = (FF_T_UINT16)(((crc16_table_high[bTableValue]) << 8)
+ (CRC16_Low[bTableValue] ^ ((wCRC >> 8) & 0x00FF))); + (crc16_table_low[bTableValue] ^ ((wCRC >> 8) & 0x00FF)));
} }
return wCRC; return wCRC;
} }
static const FF_T_UINT8 byCRCLookUpTable[256] = static const FF_T_UINT8 crc8_table[256] =
{ {
0, 94, 188, 226, 97, 63, 221, 131, 0, 94, 188, 226, 97, 63, 221, 131,
194, 156, 126, 32, 163, 253, 31, 65, 194, 156, 126, 32, 163, 253, 31, 65,
@ -188,7 +249,7 @@ FF_T_UINT8 FF_GetCRC8(FF_T_UINT8 *pbyData, FF_T_UINT32 stLength) {
FF_T_UINT8 byCRC = 0, byData; FF_T_UINT8 byCRC = 0, byData;
while (stLength--) { while (stLength--) {
byData = *pbyData++; byData = *pbyData++;
byCRC = byCRCLookUpTable[(byCRC ^ byData)]; byCRC = crc8_table[(byCRC ^ byData)];
} }
return byCRC; return byCRC;
} }

File diff suppressed because it is too large Load diff

View file

@ -1,105 +0,0 @@
/*****************************************************************************
* FullFAT - High Performance, Thread-Safe Embedded FAT File-System *
* Copyright (C) 2009 James Walmsley (james@worm.me.uk) *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
* IMPORTANT NOTICE: *
* ================= *
* Alternative Licensing is available directly from the Copyright holder, *
* (James Walmsley). For more information consult LICENSING.TXT to obtain *
* a Commercial license. *
* *
* See RESTRICTIONS.TXT for extra restrictions on the use of FullFAT. *
* *
* Removing the above notice is illegal and will invalidate this license. *
*****************************************************************************
* See http://worm.me.uk/fullfat for more information. *
* Or http://fullfat.googlecode.com/ for latest releases and the wiki. *
*****************************************************************************/
/**
* @file ff_dir.h
* @author James Walmsley
* @ingroup DIR
**/
#ifndef _FF_DIR_H_
#define _FF_DIR_H_
#include "ff_types.h"
#include "ff_config.h"
#include "ff_error.h"
#include "ff_ioman.h"
#include "ff_blk.h"
#include "ff_fat.h"
#include "fat.h"
#include "ff_memory.h"
#include "ff_time.h"
#include "ff_hash.h"
#include "ff_crc.h"
#include "ff_file.h"
#include <string.h>
typedef struct {
FF_T_INT8 FileName[FF_MAX_FILENAME];
FF_T_UINT8 Attrib;
FF_T_UINT32 Filesize;
FF_T_UINT32 ObjectCluster;
#ifdef FF_TIME_SUPPORT
FF_SYSTEMTIME CreateTime; ///< Date and Time Created.
FF_SYSTEMTIME ModifiedTime; ///< Date and Time Modified.
FF_SYSTEMTIME AccessedTime; ///< Date of Last Access.
#endif
//---- Book Keeping for FF_Find Functions
FF_T_UINT16 CurrentItem;
FF_T_UINT32 DirCluster;
FF_T_UINT32 CurrentCluster;
FF_T_UINT32 AddrCurrentCluster;
//FF_T_UINT8 NumLFNs;
} FF_DIRENT;
FF_ERROR FF_GetEntry (FF_IOMAN *pIoman, FF_T_UINT16 nEntry, FF_T_UINT32 DirCluster, FF_DIRENT *pDirent);
FF_T_SINT8 FF_PutEntry (FF_IOMAN *pIoman, FF_T_UINT16 Entry, FF_T_UINT32 DirCluster, FF_DIRENT *pDirent);
FF_T_SINT8 FF_FindEntry (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *Name, FF_DIRENT *pDirent, FF_T_BOOL LFNs);
FF_ERROR FF_FindFirst (FF_IOMAN *pIoman, FF_DIRENT *pDirent, const FF_T_INT8 *path);
FF_ERROR FF_FindNext (FF_IOMAN *pIoman, FF_DIRENT *pDirent);
void FF_PopulateShortDirent(FF_IOMAN *pIoman, FF_DIRENT *pDirent, FF_T_UINT8 *EntryBuffer);
FF_T_SINT8 FF_PopulateLongDirent(FF_IOMAN *pIoman, FF_DIRENT *pDirent, FF_T_UINT32 DirCluster, FF_T_UINT16 nEntry);
FF_T_SINT8 FF_FetchEntry (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT16 nEntry, FF_T_UINT8 *buffer);
FF_T_SINT8 FF_PushEntry (FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT16 nEntry, FF_T_UINT8 *buffer);
FF_T_BOOL FF_isEndOfDir (FF_T_UINT8 *EntryBuffer);
FF_T_SINT8 FF_FindNextInDir(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_DIRENT *pDirent);
FF_T_UINT32 FF_FindEntryInDir(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *name, FF_T_UINT8 pa_Attrib, FF_DIRENT *pDirent);
FF_T_SINT8 FF_CreateShortName(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *ShortName, FF_T_INT8 *LongName);
void FF_lockDIR (FF_IOMAN *pIoman);
void FF_unlockDIR (FF_IOMAN *pIoman);
FF_T_UINT32 FF_CreateFile(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_INT8 *FileName, FF_DIRENT *pDirent);
FF_ERROR FF_MkDir(FF_IOMAN *pIoman, const FF_T_INT8 *Path);
FF_T_SINT8 FF_CreateDirent(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_DIRENT *pDirent);
FF_T_SINT8 FF_ExtendDirectory(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster);
FF_T_UINT32 FF_FindDir(FF_IOMAN *pIoman, const FF_T_INT8 *path, FF_T_UINT16 pathLen);
FF_T_BOOL FF_CheckDirentHash(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT32 nHash);
FF_T_BOOL FF_DirHashed(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster);
FF_ERROR FF_AddDirentHash(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT32 nHash);
void FF_SetDirHashed(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster);
void FF_RmLFNs(FF_IOMAN *pIoman, FF_T_UINT32 DirCluster, FF_T_UINT16 DirEntry);
#endif

View file

@ -56,7 +56,7 @@ const struct _FFERRTAB
{"Not enough memory (malloc() returned NULL).", FF_ERR_NOT_ENOUGH_MEMORY}, {"Not enough memory (malloc() returned NULL).", FF_ERR_NOT_ENOUGH_MEMORY},
{"Device Driver returned a FATAL error!.", FF_ERR_DEVICE_DRIVER_FAILED}, {"Device Driver returned a FATAL error!.", FF_ERR_DEVICE_DRIVER_FAILED},
{"The blocksize is not 512 multiple.", FF_ERR_IOMAN_BAD_BLKSIZE}, {"The blocksize is not 512 multiple.", FF_ERR_IOMAN_BAD_BLKSIZE},
{"The provided memory size, is not a multiple of the blocksize.", FF_ERR_IOMAN_BAD_MEMSIZE}, {"The memory size, is not a multiple of the blocksize. (Atleast 2 Blocks).", FF_ERR_IOMAN_BAD_MEMSIZE},
{"Device is already registered, use FF_UnregisterBlkDevice() first.", FF_ERR_IOMAN_DEV_ALREADY_REGD}, {"Device is already registered, use FF_UnregisterBlkDevice() first.", FF_ERR_IOMAN_DEV_ALREADY_REGD},
{"No mountable partition was found on the specified device.", FF_ERR_IOMAN_NO_MOUNTABLE_PARTITION}, {"No mountable partition was found on the specified device.", FF_ERR_IOMAN_NO_MOUNTABLE_PARTITION},
{"The format of the MBR was unrecognised.", FF_ERR_IOMAN_INVALID_FORMAT}, {"The format of the MBR was unrecognised.", FF_ERR_IOMAN_INVALID_FORMAT},
@ -65,6 +65,7 @@ const struct _FFERRTAB
{"Cannot register device. (BlkSize not a multiple of 512).", FF_ERR_IOMAN_DEV_INVALID_BLKSIZE}, {"Cannot register device. (BlkSize not a multiple of 512).", FF_ERR_IOMAN_DEV_INVALID_BLKSIZE},
{"Cannot unregister device, a partition is still mounted.", FF_ERR_IOMAN_PARTITION_MOUNTED}, {"Cannot unregister device, a partition is still mounted.", FF_ERR_IOMAN_PARTITION_MOUNTED},
{"Cannot unmount the partition while there are active FILE handles.", FF_ERR_IOMAN_ACTIVE_HANDLES}, {"Cannot unmount the partition while there are active FILE handles.", FF_ERR_IOMAN_ACTIVE_HANDLES},
{"The GPT partition header appears to be corrupt, refusing to mount.", FF_ERR_IOMAN_GPT_HEADER_CORRUPT},
{"Cannot open the file, file already in use.", FF_ERR_FILE_ALREADY_OPEN}, {"Cannot open the file, file already in use.", FF_ERR_FILE_ALREADY_OPEN},
{"The specified file could not be found.", FF_ERR_FILE_NOT_FOUND}, {"The specified file could not be found.", FF_ERR_FILE_NOT_FOUND},
{"Cannot open a Directory.", FF_ERR_FILE_OBJECT_IS_A_DIR}, {"Cannot open a Directory.", FF_ERR_FILE_OBJECT_IS_A_DIR},
@ -84,6 +85,9 @@ const struct _FFERRTAB
{"Source file was not found.", FF_ERR_FILE_SOURCE_NOT_FOUND}, {"Source file was not found.", FF_ERR_FILE_SOURCE_NOT_FOUND},
{"Destination path (dir) was not found.", FF_ERR_FILE_DIR_NOT_FOUND}, {"Destination path (dir) was not found.", FF_ERR_FILE_DIR_NOT_FOUND},
{"Failed to create the directory Entry.", FF_ERR_FILE_COULD_NOT_CREATE_DIRENT}, {"Failed to create the directory Entry.", FF_ERR_FILE_COULD_NOT_CREATE_DIRENT},
{"Not enough free disk space to complete the disk transaction.", FF_ERR_IOMAN_NOT_ENOUGH_FREE_SPACE},
{"Attempted to Read a sector out of bounds.", FF_ERR_IOMAN_OUT_OF_BOUNDS_READ},
{"Attempted to Write a sector out of bounds.", FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE},
}; };
/** /**

View file

@ -110,7 +110,7 @@ FF_T_UINT32 FF_LBA2Cluster(FF_IOMAN *pIoman, FF_T_UINT32 Address) {
/** /**
* @private * @private
**/ **/
FF_T_SINT32 FF_getFatEntry(FF_IOMAN *pIoman, FF_T_UINT32 nCluster) { FF_T_UINT32 FF_getFatEntry(FF_IOMAN *pIoman, FF_T_UINT32 nCluster, FF_ERROR *pError) {
FF_BUFFER *pBuffer; FF_BUFFER *pBuffer;
FF_T_UINT32 FatOffset; FF_T_UINT32 FatOffset;
@ -136,19 +136,20 @@ FF_T_SINT32 FF_getFatEntry(FF_IOMAN *pIoman, FF_T_UINT32 nCluster) {
FatSectorEntry = FatOffset % pIoman->pPartition->BlkSize; FatSectorEntry = FatOffset % pIoman->pPartition->BlkSize;
LBAadjust = (FF_T_UINT8) (FatSectorEntry / pIoman->BlkSize); LBAadjust = (FF_T_UINT8) (FatSectorEntry / pIoman->BlkSize);
relClusterEntry = (FF_T_UINT16) (FatSectorEntry % pIoman->BlkSize); relClusterEntry = (FF_T_UINT32) (FatSectorEntry % pIoman->BlkSize);
FatSector = FF_getRealLBA(pIoman, FatSector); FatSector = FF_getRealLBA(pIoman, FatSector);
#ifdef FF_FAT12_SUPPORT #ifdef FF_FAT12_SUPPORT
if(pIoman->pPartition->Type == FF_T_FAT12) { if(pIoman->pPartition->Type == FF_T_FAT12) {
if(relClusterEntry == (pIoman->BlkSize - 1)) { if(relClusterEntry == (FF_T_UINT32)(pIoman->BlkSize - 1)) {
// Fat Entry SPANS a Sector! // Fat Entry SPANS a Sector!
// First Buffer get the last Byte in buffer (first byte of our address)! // First Buffer get the last Byte in buffer (first byte of our address)!
pBuffer = FF_GetBuffer(pIoman, FatSector + LBAadjust, FF_MODE_READ); pBuffer = FF_GetBuffer(pIoman, FatSector + LBAadjust, FF_MODE_READ);
{ {
if(!pBuffer) { if(!pBuffer) {
return FF_ERR_DEVICE_DRIVER_FAILED; *pError = FF_ERR_DEVICE_DRIVER_FAILED;
return 0;
} }
F12short[0] = FF_getChar(pBuffer->pBuffer, (FF_T_UINT16)(pIoman->BlkSize - 1)); F12short[0] = FF_getChar(pBuffer->pBuffer, (FF_T_UINT16)(pIoman->BlkSize - 1));
} }
@ -157,7 +158,8 @@ FF_T_SINT32 FF_getFatEntry(FF_IOMAN *pIoman, FF_T_UINT32 nCluster) {
pBuffer = FF_GetBuffer(pIoman, FatSector + LBAadjust + 1, FF_MODE_READ); pBuffer = FF_GetBuffer(pIoman, FatSector + LBAadjust + 1, FF_MODE_READ);
{ {
if(!pBuffer) { if(!pBuffer) {
return FF_ERR_DEVICE_DRIVER_FAILED; *pError = FF_ERR_DEVICE_DRIVER_FAILED;
return 0;
} }
F12short[1] = FF_getChar(pBuffer->pBuffer, 0); F12short[1] = FF_getChar(pBuffer->pBuffer, 0);
} }
@ -176,7 +178,8 @@ FF_T_SINT32 FF_getFatEntry(FF_IOMAN *pIoman, FF_T_UINT32 nCluster) {
pBuffer = FF_GetBuffer(pIoman, FatSector + LBAadjust, FF_MODE_READ); pBuffer = FF_GetBuffer(pIoman, FatSector + LBAadjust, FF_MODE_READ);
{ {
if(!pBuffer) { if(!pBuffer) {
return FF_ERR_DEVICE_DRIVER_FAILED; *pError = FF_ERR_DEVICE_DRIVER_FAILED;
return 0;
} }
switch(pIoman->pPartition->Type) { switch(pIoman->pPartition->Type) {
@ -208,11 +211,10 @@ FF_T_SINT32 FF_getFatEntry(FF_IOMAN *pIoman, FF_T_UINT32 nCluster) {
return (FF_T_SINT32) FatEntry; return (FF_T_SINT32) FatEntry;
} }
FF_T_SINT8 FF_ClearCluster(FF_IOMAN *pIoman, FF_T_UINT32 nCluster) { FF_ERROR FF_ClearCluster(FF_IOMAN *pIoman, FF_T_UINT32 nCluster) {
FF_BUFFER *pBuffer; FF_BUFFER *pBuffer;
FF_T_UINT16 i; FF_T_UINT16 i;
FF_T_UINT32 BaseLBA; FF_T_UINT32 BaseLBA;
FF_T_SINT8 RetVal = 0;
BaseLBA = FF_Cluster2LBA(pIoman, nCluster); BaseLBA = FF_Cluster2LBA(pIoman, nCluster);
BaseLBA = FF_getRealLBA(pIoman, BaseLBA); BaseLBA = FF_getRealLBA(pIoman, BaseLBA);
@ -220,16 +222,15 @@ FF_T_SINT8 FF_ClearCluster(FF_IOMAN *pIoman, FF_T_UINT32 nCluster) {
for(i = 0; i < pIoman->pPartition->SectorsPerCluster; i++) { for(i = 0; i < pIoman->pPartition->SectorsPerCluster; i++) {
pBuffer = FF_GetBuffer(pIoman, BaseLBA++, FF_MODE_WRITE); pBuffer = FF_GetBuffer(pIoman, BaseLBA++, FF_MODE_WRITE);
{ {
if(pBuffer) { if(!pBuffer) {
memset(pBuffer->pBuffer, 0x00, 512); return FF_ERR_DEVICE_DRIVER_FAILED;
} else {
RetVal = FF_ERR_DEVICE_DRIVER_FAILED;
} }
memset(pBuffer->pBuffer, 0x00, 512);
} }
FF_ReleaseBuffer(pIoman, pBuffer); FF_ReleaseBuffer(pIoman, pBuffer);
} }
return RetVal; return FF_ERR_NONE;
} }
/** /**
@ -240,17 +241,19 @@ FF_T_SINT8 FF_ClearCluster(FF_IOMAN *pIoman, FF_T_UINT32 nCluster) {
* @param Start Cluster address of the first cluster in the chain. * @param Start Cluster address of the first cluster in the chain.
* @param Count Number of Cluster in the chain, * @param Count Number of Cluster in the chain,
* *
* @return FF_TRUE if it is an end of chain, otherwise FF_FALSE. *
* *
**/ **/
FF_T_UINT32 FF_TraverseFAT(FF_IOMAN *pIoman, FF_T_UINT32 Start, FF_T_UINT32 Count) { FF_T_UINT32 FF_TraverseFAT(FF_IOMAN *pIoman, FF_T_UINT32 Start, FF_T_UINT32 Count, FF_ERROR *pError) {
FF_T_UINT32 i; FF_T_UINT32 i;
FF_T_UINT32 fatEntry = Start, currentCluster = Start; FF_T_UINT32 fatEntry = Start, currentCluster = Start;
*pError = FF_ERR_NONE;
for(i = 0; i < Count; i++) { for(i = 0; i < Count; i++) {
fatEntry = FF_getFatEntry(pIoman, currentCluster); fatEntry = FF_getFatEntry(pIoman, currentCluster, pError);
if(fatEntry == (FF_T_UINT32) FF_ERR_DEVICE_DRIVER_FAILED) { if(*pError) {
return 0; return 0;
} }
@ -264,13 +267,14 @@ FF_T_UINT32 FF_TraverseFAT(FF_IOMAN *pIoman, FF_T_UINT32 Start, FF_T_UINT32 Coun
return fatEntry; return fatEntry;
} }
FF_T_UINT32 FF_FindEndOfChain(FF_IOMAN *pIoman, FF_T_UINT32 Start) { FF_T_UINT32 FF_FindEndOfChain(FF_IOMAN *pIoman, FF_T_UINT32 Start, FF_ERROR *pError) {
FF_T_UINT32 fatEntry = Start, currentCluster = Start; FF_T_UINT32 fatEntry = Start, currentCluster = Start;
*pError = FF_ERR_NONE;
while(!FF_isEndOfChain(pIoman, fatEntry)) { while(!FF_isEndOfChain(pIoman, fatEntry)) {
fatEntry = FF_getFatEntry(pIoman, currentCluster); fatEntry = FF_getFatEntry(pIoman, currentCluster, pError);
if(fatEntry == (FF_T_UINT32) FF_ERR_DEVICE_DRIVER_FAILED) { if(*pError) {
return 0; return 0;
} }
@ -325,7 +329,7 @@ FF_T_BOOL FF_isEndOfChain(FF_IOMAN *pIoman, FF_T_UINT32 fatEntry) {
* @param nCluster Cluster Number to be modified. * @param nCluster Cluster Number to be modified.
* @param Value The Value to store. * @param Value The Value to store.
**/ **/
FF_T_SINT8 FF_putFatEntry(FF_IOMAN *pIoman, FF_T_UINT32 nCluster, FF_T_UINT32 Value) { FF_ERROR FF_putFatEntry(FF_IOMAN *pIoman, FF_T_UINT32 nCluster, FF_T_UINT32 Value) {
FF_BUFFER *pBuffer; FF_BUFFER *pBuffer;
FF_T_UINT32 FatOffset; FF_T_UINT32 FatOffset;
@ -333,7 +337,7 @@ FF_T_SINT8 FF_putFatEntry(FF_IOMAN *pIoman, FF_T_UINT32 nCluster, FF_T_UINT32 Va
FF_T_UINT32 FatSectorEntry; FF_T_UINT32 FatSectorEntry;
FF_T_UINT32 FatEntry; FF_T_UINT32 FatEntry;
FF_T_UINT8 LBAadjust; FF_T_UINT8 LBAadjust;
FF_T_UINT16 relClusterEntry; FF_T_UINT32 relClusterEntry;
#ifdef FF_FAT12_SUPPORT #ifdef FF_FAT12_SUPPORT
FF_T_UINT8 F12short[2]; // For FAT12 FAT Table Across sector boundary traversal. FF_T_UINT8 F12short[2]; // For FAT12 FAT Table Across sector boundary traversal.
#endif #endif
@ -350,13 +354,13 @@ FF_T_SINT8 FF_putFatEntry(FF_IOMAN *pIoman, FF_T_UINT32 nCluster, FF_T_UINT32 Va
FatSectorEntry = FatOffset % pIoman->pPartition->BlkSize; FatSectorEntry = FatOffset % pIoman->pPartition->BlkSize;
LBAadjust = (FF_T_UINT8) (FatSectorEntry / pIoman->BlkSize); LBAadjust = (FF_T_UINT8) (FatSectorEntry / pIoman->BlkSize);
relClusterEntry = (FF_T_UINT16)(FatSectorEntry % pIoman->BlkSize); relClusterEntry = (FF_T_UINT32)(FatSectorEntry % pIoman->BlkSize);
FatSector = FF_getRealLBA(pIoman, FatSector); FatSector = FF_getRealLBA(pIoman, FatSector);
#ifdef FF_FAT12_SUPPORT #ifdef FF_FAT12_SUPPORT
if(pIoman->pPartition->Type == FF_T_FAT12) { if(pIoman->pPartition->Type == FF_T_FAT12) {
if(relClusterEntry == (FF_T_UINT16) (pIoman->BlkSize - 1)) { if(relClusterEntry == (FF_T_UINT32)(pIoman->BlkSize - 1)) {
// Fat Entry SPANS a Sector! // Fat Entry SPANS a Sector!
// First Buffer get the last Byte in buffer (first byte of our address)! // First Buffer get the last Byte in buffer (first byte of our address)!
pBuffer = FF_GetBuffer(pIoman, FatSector + LBAadjust, FF_MODE_READ); pBuffer = FF_GetBuffer(pIoman, FatSector + LBAadjust, FF_MODE_READ);
@ -439,7 +443,7 @@ FF_T_SINT8 FF_putFatEntry(FF_IOMAN *pIoman, FF_T_UINT32 nCluster, FF_T_UINT32 Va
} }
FF_ReleaseBuffer(pIoman, pBuffer); FF_ReleaseBuffer(pIoman, pBuffer);
return 0; return FF_ERR_NONE;
} }
@ -454,12 +458,17 @@ FF_T_SINT8 FF_putFatEntry(FF_IOMAN *pIoman, FF_T_UINT32 nCluster, FF_T_UINT32 Va
* @return 0 on error. * @return 0 on error.
**/ **/
#ifdef FF_FAT12_SUPPORT #ifdef FF_FAT12_SUPPORT
FF_T_UINT32 FF_FindFreeClusterOLD(FF_IOMAN *pIoman) { static FF_T_UINT32 FF_FindFreeClusterOLD(FF_IOMAN *pIoman, FF_ERROR *pError) {
FF_T_UINT32 nCluster; FF_T_UINT32 nCluster;
FF_T_UINT32 fatEntry; FF_T_UINT32 fatEntry;
*pError = FF_ERR_NONE;
for(nCluster = pIoman->pPartition->LastFreeCluster; nCluster < pIoman->pPartition->NumClusters; nCluster++) { for(nCluster = pIoman->pPartition->LastFreeCluster; nCluster < pIoman->pPartition->NumClusters; nCluster++) {
fatEntry = FF_getFatEntry(pIoman, nCluster); fatEntry = FF_getFatEntry(pIoman, nCluster, pError);
if(*pError) {
return 0;
}
if(fatEntry == 0x00000000) { if(fatEntry == 0x00000000) {
pIoman->pPartition->LastFreeCluster = nCluster; pIoman->pPartition->LastFreeCluster = nCluster;
return nCluster; return nCluster;
@ -469,7 +478,7 @@ FF_T_UINT32 FF_FindFreeClusterOLD(FF_IOMAN *pIoman) {
} }
#endif #endif
FF_T_UINT32 FF_FindFreeCluster(FF_IOMAN *pIoman) { FF_T_UINT32 FF_FindFreeCluster(FF_IOMAN *pIoman, FF_ERROR *pError) {
FF_BUFFER *pBuffer; FF_BUFFER *pBuffer;
FF_T_UINT32 i, x, nCluster = pIoman->pPartition->LastFreeCluster; FF_T_UINT32 i, x, nCluster = pIoman->pPartition->LastFreeCluster;
FF_T_UINT32 FatOffset; FF_T_UINT32 FatOffset;
@ -478,9 +487,11 @@ FF_T_UINT32 FF_FindFreeCluster(FF_IOMAN *pIoman) {
FF_T_UINT32 EntriesPerSector; FF_T_UINT32 EntriesPerSector;
FF_T_UINT32 FatEntry = 1; FF_T_UINT32 FatEntry = 1;
*pError = FF_ERR_NONE;
#ifdef FF_FAT12_SUPPORT #ifdef FF_FAT12_SUPPORT
if(pIoman->pPartition->Type == FF_T_FAT12) { // FAT12 tables are too small to optimise, and would make it very complicated! if(pIoman->pPartition->Type == FF_T_FAT12) { // FAT12 tables are too small to optimise, and would make it very complicated!
return FF_FindFreeClusterOLD(pIoman); return FF_FindFreeClusterOLD(pIoman, pError);
} }
#endif #endif
@ -492,11 +503,21 @@ FF_T_UINT32 FF_FindFreeCluster(FF_IOMAN *pIoman) {
FatOffset = nCluster * 2; FatOffset = nCluster * 2;
} }
// HT addition: don't use non-existing clusters
if (nCluster >= pIoman->pPartition->NumClusters) {
*pError = FF_ERR_FAT_NO_FREE_CLUSTERS;
return 0;
}
FatSector = (FatOffset / pIoman->pPartition->BlkSize); FatSector = (FatOffset / pIoman->pPartition->BlkSize);
for(i = FatSector; i < pIoman->pPartition->SectorsPerFAT; i++) { for(i = FatSector; i < pIoman->pPartition->SectorsPerFAT; i++) {
pBuffer = FF_GetBuffer(pIoman, pIoman->pPartition->FatBeginLBA + i, FF_MODE_READ); pBuffer = FF_GetBuffer(pIoman, pIoman->pPartition->FatBeginLBA + i, FF_MODE_READ);
{ {
if(!pBuffer) {
*pError = FF_ERR_DEVICE_DRIVER_FAILED;
return 0;
}
for(x = nCluster % EntriesPerSector; x < EntriesPerSector; x++) { for(x = nCluster % EntriesPerSector; x < EntriesPerSector; x++) {
if(pIoman->pPartition->Type == FF_T_FAT32) { if(pIoman->pPartition->Type == FF_T_FAT32) {
FatOffset = x * 4; FatOffset = x * 4;
@ -528,24 +549,54 @@ FF_T_UINT32 FF_FindFreeCluster(FF_IOMAN *pIoman) {
* @private * @private
* @brief Create's a Cluster Chain * @brief Create's a Cluster Chain
**/ **/
FF_T_UINT32 FF_CreateClusterChain(FF_IOMAN *pIoman) { FF_T_UINT32 FF_CreateClusterChain(FF_IOMAN *pIoman, FF_ERROR *pError) {
FF_T_UINT32 iStartCluster; FF_T_UINT32 iStartCluster;
FF_ERROR Error;
*pError = FF_ERR_NONE;
FF_lockFAT(pIoman); FF_lockFAT(pIoman);
{ {
iStartCluster = FF_FindFreeCluster(pIoman); iStartCluster = FF_FindFreeCluster(pIoman, &Error);
FF_putFatEntry(pIoman, iStartCluster, 0xFFFFFFFF); // Mark the cluster as EOC if(Error) {
*pError = Error;
FF_unlockFAT(pIoman);
return 0;
}
if(iStartCluster) {
Error = FF_putFatEntry(pIoman, iStartCluster, 0xFFFFFFFF); // Mark the cluster as End-Of-Chain
if(Error) {
*pError = Error;
FF_unlockFAT(pIoman);
return 0;
}
}
} }
FF_unlockFAT(pIoman); FF_unlockFAT(pIoman);
if(iStartCluster) {
Error = FF_DecreaseFreeClusters(pIoman, 1);
if(Error) {
*pError = Error;
return 0;
}
}
return iStartCluster; return iStartCluster;
} }
FF_T_UINT32 FF_GetChainLength(FF_IOMAN *pIoman, FF_T_UINT32 pa_nStartCluster, FF_T_UINT32 *piEndOfChain) { FF_T_UINT32 FF_GetChainLength(FF_IOMAN *pIoman, FF_T_UINT32 pa_nStartCluster, FF_T_UINT32 *piEndOfChain, FF_ERROR *pError) {
FF_T_UINT32 iLength = 0; FF_T_UINT32 iLength = 0;
*pError = FF_ERR_NONE;
FF_lockFAT(pIoman); FF_lockFAT(pIoman);
{ {
while(!FF_isEndOfChain(pIoman, pa_nStartCluster)) { while(!FF_isEndOfChain(pIoman, pa_nStartCluster)) {
pa_nStartCluster = FF_getFatEntry(pIoman, pa_nStartCluster); pa_nStartCluster = FF_getFatEntry(pIoman, pa_nStartCluster, pError);
if(*pError) {
return 0;
}
iLength++; iLength++;
} }
if(piEndOfChain) { if(piEndOfChain) {
@ -607,11 +658,13 @@ FF_T_UINT32 FF_ExtendClusterChain(FF_IOMAN *pIoman, FF_T_UINT32 StartCluster, FF
* @return -1 If the device driver failed to provide access. * @return -1 If the device driver failed to provide access.
* *
**/ **/
FF_T_SINT8 FF_UnlinkClusterChain(FF_IOMAN *pIoman, FF_T_UINT32 StartCluster, FF_T_UINT16 Count) { FF_ERROR FF_UnlinkClusterChain(FF_IOMAN *pIoman, FF_T_UINT32 StartCluster, FF_T_UINT16 Count) {
FF_T_UINT32 fatEntry; FF_T_UINT32 fatEntry;
FF_T_UINT32 currentCluster, chainLength = 0; FF_T_UINT32 currentCluster, chainLength = 0;
FF_T_UINT32 iLen = 0; FF_T_UINT32 iLen = 0;
FF_T_UINT32 lastFree = StartCluster; /* HT addition : reset LastFreeCluster */
FF_ERROR Error;
fatEntry = StartCluster; fatEntry = StartCluster;
@ -620,16 +673,35 @@ FF_T_SINT8 FF_UnlinkClusterChain(FF_IOMAN *pIoman, FF_T_UINT32 StartCluster, FF_
currentCluster = StartCluster; currentCluster = StartCluster;
fatEntry = currentCluster; fatEntry = currentCluster;
do { do {
fatEntry = FF_getFatEntry(pIoman, fatEntry); fatEntry = FF_getFatEntry(pIoman, fatEntry, &Error);
FF_putFatEntry(pIoman, currentCluster, 0x00000000); if(Error) {
return Error;
}
Error = FF_putFatEntry(pIoman, currentCluster, 0x00000000);
if(Error) {
return Error;
}
if (lastFree > currentCluster) {
lastFree = currentCluster;
}
currentCluster = fatEntry; currentCluster = fatEntry;
iLen ++; iLen ++;
}while(!FF_isEndOfChain(pIoman, fatEntry)); }while(!FF_isEndOfChain(pIoman, fatEntry));
FF_IncreaseFreeClusters(pIoman, iLen); if (pIoman->pPartition->LastFreeCluster > lastFree) {
pIoman->pPartition->LastFreeCluster = lastFree;
}
Error = FF_IncreaseFreeClusters(pIoman, iLen);
if(Error) {
return Error;
}
} else { } else {
// Truncation - This is quite hard, because we can only do it backwards. // Truncation - This is quite hard, because we can only do it backwards.
do { do {
fatEntry = FF_getFatEntry(pIoman, fatEntry); fatEntry = FF_getFatEntry(pIoman, fatEntry, &Error);
if(Error) {
return Error;
}
chainLength++; chainLength++;
}while(!FF_isEndOfChain(pIoman, fatEntry)); }while(!FF_isEndOfChain(pIoman, fatEntry));
} }
@ -638,14 +710,19 @@ FF_T_SINT8 FF_UnlinkClusterChain(FF_IOMAN *pIoman, FF_T_UINT32 StartCluster, FF_
} }
#ifdef FF_FAT12_SUPPORT #ifdef FF_FAT12_SUPPORT
FF_T_UINT32 FF_CountFreeClustersOLD(FF_IOMAN *pIoman) { FF_T_UINT32 FF_CountFreeClustersOLD(FF_IOMAN *pIoman, FF_ERROR *pError) {
FF_T_UINT32 i; FF_T_UINT32 i;
FF_T_UINT32 TotalClusters = pIoman->pPartition->DataSectors / pIoman->pPartition->SectorsPerCluster; FF_T_UINT32 TotalClusters = pIoman->pPartition->DataSectors / pIoman->pPartition->SectorsPerCluster;
FF_T_UINT32 FatEntry; FF_T_UINT32 FatEntry;
FF_T_UINT32 FreeClusters = 0; FF_T_UINT32 FreeClusters = 0;
*pError = FF_ERR_NONE;
for(i = 0; i < TotalClusters; i++) { for(i = 0; i < TotalClusters; i++) {
FatEntry = FF_getFatEntry(pIoman, i); FatEntry = FF_getFatEntry(pIoman, i, pError);
if(*pError) {
return 0;
}
if(!FatEntry) { if(!FatEntry) {
FreeClusters++; FreeClusters++;
} }
@ -656,7 +733,7 @@ FF_T_UINT32 FF_CountFreeClustersOLD(FF_IOMAN *pIoman) {
#endif #endif
FF_T_UINT32 FF_CountFreeClusters(FF_IOMAN *pIoman) { FF_T_UINT32 FF_CountFreeClusters(FF_IOMAN *pIoman, FF_ERROR *pError) {
FF_BUFFER *pBuffer; FF_BUFFER *pBuffer;
FF_T_UINT32 i, x, nCluster = 0; FF_T_UINT32 i, x, nCluster = 0;
FF_T_UINT32 FatOffset; FF_T_UINT32 FatOffset;
@ -666,9 +743,14 @@ FF_T_UINT32 FF_CountFreeClusters(FF_IOMAN *pIoman) {
FF_T_UINT32 FatEntry = 1; FF_T_UINT32 FatEntry = 1;
FF_T_UINT32 FreeClusters = 0; FF_T_UINT32 FreeClusters = 0;
*pError = FF_ERR_NONE;
#ifdef FF_FAT12_SUPPORT #ifdef FF_FAT12_SUPPORT
if(pIoman->pPartition->Type == FF_T_FAT12) { // FAT12 tables are too small to optimise, and would make it very complicated! if(pIoman->pPartition->Type == FF_T_FAT12) { // FAT12 tables are too small to optimise, and would make it very complicated!
return FF_CountFreeClustersOLD(pIoman); FreeClusters = FF_CountFreeClustersOLD(pIoman, pError);
if(*pError) {
return 0;
}
} }
#endif #endif
@ -685,6 +767,10 @@ FF_T_UINT32 FF_CountFreeClusters(FF_IOMAN *pIoman) {
for(i = 0; i < pIoman->pPartition->SectorsPerFAT; i++) { for(i = 0; i < pIoman->pPartition->SectorsPerFAT; i++) {
pBuffer = FF_GetBuffer(pIoman, pIoman->pPartition->FatBeginLBA + i, FF_MODE_READ); pBuffer = FF_GetBuffer(pIoman, pIoman->pPartition->FatBeginLBA + i, FF_MODE_READ);
{ {
if(!pBuffer) {
*pError = FF_ERR_DEVICE_DRIVER_FAILED;
return 0;
}
for(x = nCluster % EntriesPerSector; x < EntriesPerSector; x++) { for(x = nCluster % EntriesPerSector; x < EntriesPerSector; x++) {
if(pIoman->pPartition->Type == FF_T_FAT32) { if(pIoman->pPartition->Type == FF_T_FAT32) {
FatOffset = x * 4; FatOffset = x * 4;
@ -694,7 +780,7 @@ FF_T_UINT32 FF_CountFreeClusters(FF_IOMAN *pIoman) {
} else { } else {
FatOffset = x * 2; FatOffset = x * 2;
FatSectorEntry = FatOffset % pIoman->pPartition->BlkSize; FatSectorEntry = FatOffset % pIoman->pPartition->BlkSize;
FatEntry = (FF_T_UINT32) FF_getShort(pBuffer->pBuffer, (FF_T_UINT16)FatSectorEntry); FatEntry = (FF_T_UINT32) FF_getShort(pBuffer->pBuffer, FatSectorEntry);
} }
if(FatEntry == 0x00000000) { if(FatEntry == 0x00000000) {
FreeClusters += 1; FreeClusters += 1;
@ -706,19 +792,27 @@ FF_T_UINT32 FF_CountFreeClusters(FF_IOMAN *pIoman) {
FF_ReleaseBuffer(pIoman, pBuffer); FF_ReleaseBuffer(pIoman, pBuffer);
} }
return FreeClusters; return FreeClusters <= pIoman->pPartition->NumClusters ? FreeClusters : pIoman->pPartition->NumClusters;
} }
#ifdef FF_64_NUM_SUPPORT #ifdef FF_64_NUM_SUPPORT
FF_T_UINT64 FF_GetFreeSize(FF_IOMAN *pIoman) { FF_T_UINT64 FF_GetFreeSize(FF_IOMAN *pIoman, FF_ERROR *pError) {
FF_T_UINT32 FreeClusters; FF_T_UINT32 FreeClusters;
FF_T_UINT64 FreeSize; FF_T_UINT64 FreeSize;
FF_ERROR Error;
if(pIoman) { if(pIoman) {
FF_lockFAT(pIoman); FF_lockFAT(pIoman);
{ {
if(!pIoman->pPartition->FreeClusterCount) { if(!pIoman->pPartition->FreeClusterCount) {
pIoman->pPartition->FreeClusterCount = FF_CountFreeClusters(pIoman); pIoman->pPartition->FreeClusterCount = FF_CountFreeClusters(pIoman, &Error);
if(Error) {
if(pError) {
*pError = Error;
}
FF_unlockFAT(pIoman);
return 0;
}
} }
FreeClusters = pIoman->pPartition->FreeClusterCount; FreeClusters = pIoman->pPartition->FreeClusterCount;
} }

File diff suppressed because it is too large Load diff

132
lib/3rdparty/fullfat/ff_format.c vendored Normal file
View file

@ -0,0 +1,132 @@
/*****************************************************************************
* FullFAT - High Performance, Thread-Safe Embedded FAT File-System *
* Copyright (C) 2009 James Walmsley (james@worm.me.uk) *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
* IMPORTANT NOTICE: *
* ================= *
* Alternative Licensing is available directly from the Copyright holder, *
* (James Walmsley). For more information consult LICENSING.TXT to obtain *
* a Commercial license. *
* *
* See RESTRICTIONS.TXT for extra restrictions on the use of FullFAT. *
* *
* Removing the above notice is illegal and will invalidate this license. *
*****************************************************************************
* See http://worm.me.uk/fullfat for more information. *
* Or http://fullfat.googlecode.com/ for latest releases and the wiki. *
*****************************************************************************/
/**
* @file ff_format.c
* @author James Walmsley
* @ingroup FORMAT
*
* @defgroup FORMAT Independent FAT Formatter
* @brief Provides an interface to format a partition with FAT.
*
*
*
**/
#include "ff_format.h"
#include "ff_types.h"
#include "ff_ioman.h"
#include "ff_fatdef.h"
static FF_T_SINT8 FF_PartitionCount (FF_T_UINT8 *pBuffer)
{
FF_T_SINT8 count = 0;
FF_T_SINT8 part;
// Check PBR or MBR signature
if (FF_getChar(pBuffer, FF_FAT_MBR_SIGNATURE) != 0x55 &&
FF_getChar(pBuffer, FF_FAT_MBR_SIGNATURE) != 0xAA ) {
// No MBR, but is it a PBR ?
if (FF_getChar(pBuffer, 0) == 0xEB && // PBR Byte 0
FF_getChar(pBuffer, 2) == 0x90 && // PBR Byte 2
(FF_getChar(pBuffer, 21) & 0xF0) == 0xF0) {// PBR Byte 21 : Media byte
return 1; // No MBR but PBR exist then only one partition
}
return 0; // No MBR and no PBR then no partition found
}
for (part = 0; part < 4; part++) {
FF_T_UINT8 active = FF_getChar(pBuffer, FF_FAT_PTBL + FF_FAT_PTBL_ACTIVE + (16 * part));
FF_T_UINT8 part_id = FF_getChar(pBuffer, FF_FAT_PTBL + FF_FAT_PTBL_ID + (16 * part));
// The first sector must be a MBR, then check the partition entry in the MBR
if (active != 0x80 && (active != 0 || part_id == 0)) {
break;
}
count++;
}
return count;
}
FF_ERROR FF_FormatPartition(FF_IOMAN *pIoman, FF_T_UINT32 ulPartitionNumber, FF_T_UINT32 ulClusterSize) {
FF_BUFFER *pBuffer;
FF_T_UINT8 ucPartitionType;
FF_T_SINT8 scPartitionCount;
FF_T_UINT32 /*ulPartitionBeginLBA, ulPartitionLength,*/ ulPnum;
FF_ERROR Error = FF_ERR_NONE;
ulClusterSize = 0;
// Get Partition Metrics, and pass on to FF_Format() function
pBuffer = FF_GetBuffer(pIoman, 0, FF_MODE_READ);
{
if(!pBuffer) {
return FF_ERR_DEVICE_DRIVER_FAILED;
}
scPartitionCount = FF_PartitionCount(pBuffer->pBuffer);
ucPartitionType = FF_getChar(pBuffer->pBuffer, FF_FAT_PTBL + FF_FAT_PTBL_ID);
if(ucPartitionType == 0xEE) {
// Handle Extended Partitions
ulPnum = 0;
} else {
if(ulPartitionNumber > (FF_T_UINT32) scPartitionCount) {
FF_ReleaseBuffer(pIoman, pBuffer);
return FF_ERR_IOMAN_INVALID_PARTITION_NUM;
}
ulPnum = ulPartitionNumber;
}
}
FF_ReleaseBuffer(pIoman, pBuffer);
return Error;
}
FF_ERROR FF_Format(FF_IOMAN *pIoman, FF_T_UINT32 ulStartLBA, FF_T_UINT32 ulEndLBA, FF_T_UINT32 ulClusterSize) {
FF_T_UINT32 ulTotalSectors;
FF_T_UINT32 ulTotalClusters;
ulTotalSectors = ulEndLBA - ulStartLBA;
ulTotalClusters = ulTotalSectors / (ulClusterSize / pIoman->BlkSize);
return -1;
}

View file

@ -43,7 +43,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#ifdef FF_HASH_TABLE_SUPPORT #ifdef FF_HASH_CACHE
struct _FF_HASH_TABLE { struct _FF_HASH_TABLE {
FF_T_UINT8 bitTable[FF_HASH_TABLE_SIZE]; FF_T_UINT8 bitTable[FF_HASH_TABLE_SIZE];
}; };
@ -53,7 +53,7 @@ struct _FF_HASH_TABLE {
* *
**/ **/
FF_HASH_TABLE FF_CreateHashTable() { FF_HASH_TABLE FF_CreateHashTable() {
FF_HASH_TABLE pHash = (FF_HASH_TABLE) FF_Malloc(sizeof(struct _FF_HASH_TABLE)); FF_HASH_TABLE pHash = (FF_HASH_TABLE) FF_MALLOC(sizeof(struct _FF_HASH_TABLE));
if(pHash) { if(pHash) {
FF_ClearHashTable(pHash); FF_ClearHashTable(pHash);
@ -110,7 +110,7 @@ FF_T_BOOL FF_isHashSet(FF_HASH_TABLE pHash, FF_T_UINT32 nHash) {
FF_ERROR FF_DestroyHashTable(FF_HASH_TABLE pHash) { FF_ERROR FF_DestroyHashTable(FF_HASH_TABLE pHash) {
if(pHash) { if(pHash) {
free(pHash); FF_FREE(pHash);
return FF_ERR_NONE; return FF_ERR_NONE;
} }
return FF_ERR_NULL_POINTER; return FF_ERR_NULL_POINTER;

View file

@ -42,11 +42,14 @@
* Destroying a FullFAT IO object. * Destroying a FullFAT IO object.
**/ **/
#include "ff_ioman.h" // Includes ff_types.h, ff_safety.h, <stdio.h> #include <string.h>
#include "fat.h"
extern FF_T_UINT32 FF_FindFreeCluster (FF_IOMAN *pIoman); #include "ff_ioman.h" // Includes ff_types.h, ff_safety.h, <stdio.h>
extern FF_T_UINT32 FF_CountFreeClusters (FF_IOMAN *pIoman); #include "ff_fatdef.h"
#include "ff_crc.h"
//extern FF_T_UINT32 FF_FindFreeCluster (FF_IOMAN *pIoman);
extern FF_T_UINT32 FF_CountFreeClusters (FF_IOMAN *pIoman, FF_ERROR *pError);
static void FF_IOMAN_InitBufferDescriptors(FF_IOMAN *pIoman); static void FF_IOMAN_InitBufferDescriptors(FF_IOMAN *pIoman);
@ -55,7 +58,7 @@ static void FF_IOMAN_InitBufferDescriptors(FF_IOMAN *pIoman);
* @brief Creates an FF_IOMAN object, to initialise FullFAT * @brief Creates an FF_IOMAN object, to initialise FullFAT
* *
* @param pCacheMem Pointer to a buffer for the cache. (NULL if ok to Malloc). * @param pCacheMem Pointer to a buffer for the cache. (NULL if ok to Malloc).
* @param Size The size of the provided buffer, or size of the cache to be created. * @param Size The size of the provided buffer, or size of the cache to be created. (Must be atleast 2 * BlkSize). Always a multiple of BlkSize.
* @param BlkSize The block size of devices to be attached. If in doubt use 512. * @param BlkSize The block size of devices to be attached. If in doubt use 512.
* @param pError Pointer to a signed byte for error checking. Can be NULL if not required. * @param pError Pointer to a signed byte for error checking. Can be NULL if not required.
* @param pError To be checked when a NULL pointer is returned. * @param pError To be checked when a NULL pointer is returned.
@ -75,85 +78,99 @@ FF_IOMAN *FF_CreateIOMAN(FF_T_UINT8 *pCacheMem, FF_T_UINT32 Size, FF_T_UINT16 Bl
*pError = FF_ERR_NONE; *pError = FF_ERR_NONE;
} }
if((BlkSize % 512) != 0 || Size == 0) { if((BlkSize % 512) != 0 || BlkSize == 0) {
if(pError) { if(pError) {
*pError = FF_ERR_IOMAN_BAD_BLKSIZE; *pError = FF_ERR_IOMAN_BAD_BLKSIZE | FF_CREATEIOMAN;
} }
return NULL; // BlkSize Size not a multiple of 512 > 0 return NULL; // BlkSize Size not a multiple of 512 > 0
} }
if((Size % BlkSize) != 0 || Size == 0) { if((Size % BlkSize) != 0 || Size == 0 || Size == BlkSize) { // Size must now be atleast 2 * BlkSize (or a deadlock will occur).
if(pError) { if(pError) {
*pError = FF_ERR_IOMAN_BAD_MEMSIZE; *pError = FF_ERR_IOMAN_BAD_MEMSIZE | FF_CREATEIOMAN;
} }
return NULL; // Memory Size not a multiple of BlkSize > 0 return NULL; // Memory Size not a multiple of BlkSize > 0
} }
pIoman = (FF_IOMAN *) FF_Malloc(sizeof(FF_IOMAN)); pIoman = (FF_IOMAN *) FF_MALLOC(sizeof(FF_IOMAN));
if(!pIoman) { // Ensure malloc() succeeded. if(!pIoman) { // Ensure malloc() succeeded.
if(pError) { if(pError) {
*pError = FF_ERR_NOT_ENOUGH_MEMORY; *pError = FF_ERR_NOT_ENOUGH_MEMORY | FF_CREATEIOMAN;
} }
return NULL; return NULL;
} }
memset (pIoman, '\0', sizeof(FF_IOMAN));
// This is just a bit-mask, to use a byte to keep track of memory. // This is just a bit-mask, to use a byte to keep track of memory.
// pIoman->MemAllocation = 0x00; // Unset all allocation identifiers. // pIoman->MemAllocation = 0x00; // Unset all allocation identifiers.
pIoman->pBlkDevice = NULL; pIoman->pPartition = (FF_PARTITION *) FF_MALLOC(sizeof(FF_PARTITION));
pIoman->pBuffers = NULL; if(!pIoman->pPartition) {
pIoman->pCacheMem = NULL; if(pError) {
pIoman->pPartition = NULL; *pError = FF_ERR_NOT_ENOUGH_MEMORY | FF_CREATEIOMAN;
pIoman->pSemaphore = NULL;
pIoman->pPartition = (FF_PARTITION *) FF_Malloc(sizeof(FF_PARTITION));
if(pIoman->pPartition) { // If succeeded, flag that allocation.
pIoman->MemAllocation |= FF_IOMAN_ALLOC_PART;
pIoman->pPartition->LastFreeCluster = 0;
pIoman->pPartition->PartitionMounted = FF_FALSE; // This should be checked by FF_Open();
#ifdef FF_PATH_CACHE
pIoman->pPartition->PCIndex = 0;
for(i = 0; i < FF_PATH_CACHE_DEPTH; i++) {
pIoman->pPartition->PathCache[i].DirCluster = 0;
pIoman->pPartition->PathCache[i].Path[0] = '\0';
#ifdef FF_HASH_TABLE_SUPPORT
pIoman->pPartition->PathCache[i].pHashTable = FF_CreateHashTable();
pIoman->pPartition->PathCache[i].bHashed = FF_FALSE;
#endif
} }
FF_DestroyIOMAN(pIoman);
return NULL;
}
memset (pIoman->pPartition, '\0', sizeof(FF_PARTITION));
pIoman->MemAllocation |= FF_IOMAN_ALLOC_PART; // If succeeded, flag that allocation.
pIoman->pPartition->LastFreeCluster = 0;
pIoman->pPartition->PartitionMounted = FF_FALSE; // This should be checked by FF_Open();
#ifdef FF_PATH_CACHE
pIoman->pPartition->PCIndex = 0;
for(i = 0; i < FF_PATH_CACHE_DEPTH; i++) {
pIoman->pPartition->PathCache[i].DirCluster = 0;
pIoman->pPartition->PathCache[i].Path[0] = '\0';
/*#ifdef FF_HASH_TABLE_SUPPORT
pIoman->pPartition->PathCache[i].pHashTable = FF_CreateHashTable();
pIoman->pPartition->PathCache[i].bHashed = FF_FALSE;
#endif*/
}
#endif #endif
} else {
#ifdef FF_HASH_CACHE
for(i = 0; i < FF_HASH_CACHE_DEPTH; i++) {
pIoman->HashCache[i].pHashTable = FF_CreateHashTable();
pIoman->HashCache[i].ulDirCluster = 0;
pIoman->HashCache[i].ulMisses = 100;
}
#endif
pIoman->pBlkDevice = (FF_BLK_DEVICE *) FF_MALLOC(sizeof(FF_BLK_DEVICE));
if(!pIoman->pBlkDevice) { // If succeeded, flag that allocation.
if(pError) {
*pError = FF_ERR_NOT_ENOUGH_MEMORY | FF_CREATEIOMAN;
}
FF_DestroyIOMAN(pIoman); FF_DestroyIOMAN(pIoman);
return NULL; return NULL;
} }
memset (pIoman->pBlkDevice, '\0', sizeof(FF_BLK_DEVICE));
pIoman->MemAllocation |= FF_IOMAN_ALLOC_BLKDEV;
pIoman->pBlkDevice = (FF_BLK_DEVICE *) FF_Malloc(sizeof(FF_BLK_DEVICE)); // Make sure all pointers are NULL
if(pIoman->pBlkDevice) { // If succeeded, flag that allocation. pIoman->pBlkDevice->fnpReadBlocks = NULL;
pIoman->MemAllocation |= FF_IOMAN_ALLOC_BLKDEV; pIoman->pBlkDevice->fnpWriteBlocks = NULL;
pIoman->pBlkDevice->pParam = NULL;
// Make sure all pointers are NULL
pIoman->pBlkDevice->fnReadBlocks = NULL;
pIoman->pBlkDevice->fnWriteBlocks = NULL;
pIoman->pBlkDevice->pParam = NULL;
} else {
FF_DestroyIOMAN(pIoman);
return NULL;
}
// Organise the memory provided, or create our own! // Organise the memory provided, or create our own!
if(pCacheMem) { if(pCacheMem) {
pIoman->pCacheMem = pCacheMem; pIoman->pCacheMem = pCacheMem;
}else { // No-Cache buffer provided (malloc) }else { // No-Cache buffer provided (malloc)
pLong = (FF_T_UINT32 *) FF_Malloc(Size); pLong = (FF_T_UINT32 *) FF_MALLOC(Size);
pIoman->pCacheMem = (FF_T_UINT8 *) pLong; pIoman->pCacheMem = (FF_T_UINT8 *) pLong;
if(!pIoman->pCacheMem) { if(!pIoman->pCacheMem) {
pIoman->MemAllocation |= FF_IOMAN_ALLOC_BUFFERS; if(pError) {
*pError = FF_ERR_NOT_ENOUGH_MEMORY | FF_CREATEIOMAN;
}
FF_DestroyIOMAN(pIoman); FF_DestroyIOMAN(pIoman);
return NULL; return NULL;
} }
pIoman->MemAllocation |= FF_IOMAN_ALLOC_BUFFERS;
} }
memset (pIoman->pCacheMem, '\0', Size);
pIoman->BlkSize = BlkSize; pIoman->BlkSize = BlkSize;
pIoman->CacheSize = (FF_T_UINT16) (Size / BlkSize); pIoman->CacheSize = (FF_T_UINT16) (Size / BlkSize);
@ -163,18 +180,27 @@ FF_IOMAN *FF_CreateIOMAN(FF_T_UINT8 *pCacheMem, FF_T_UINT32 Size, FF_T_UINT16 Bl
/* Malloc() memory for buffer objects. (FullFAT never refers to a buffer directly /* Malloc() memory for buffer objects. (FullFAT never refers to a buffer directly
but uses buffer objects instead. Allows us to provide thread safety. but uses buffer objects instead. Allows us to provide thread safety.
*/ */
pIoman->pBuffers = (FF_BUFFER *) FF_Malloc(sizeof(FF_BUFFER) * pIoman->CacheSize); pIoman->pBuffers = (FF_BUFFER *) FF_MALLOC(sizeof(FF_BUFFER) * pIoman->CacheSize);
if(pIoman->pBuffers) { if(!pIoman->pBuffers) {
pIoman->MemAllocation |= FF_IOMAN_ALLOC_BUFDESCR; if(pError) {
FF_IOMAN_InitBufferDescriptors(pIoman); *pError = FF_ERR_NOT_ENOUGH_MEMORY | FF_CREATEIOMAN;
} else { }
FF_DestroyIOMAN(pIoman); FF_DestroyIOMAN(pIoman);
return NULL; // HT added
} }
memset (pIoman->pBuffers, '\0', sizeof(FF_BUFFER) * pIoman->CacheSize);
pIoman->MemAllocation |= FF_IOMAN_ALLOC_BUFDESCR;
FF_IOMAN_InitBufferDescriptors(pIoman);
// Finally create a Semaphore for Buffer Description modifications. // Finally create a Semaphore for Buffer Description modifications.
pIoman->pSemaphore = FF_CreateSemaphore(); pIoman->pSemaphore = FF_CreateSemaphore();
#ifdef FF_BLKDEV_USES_SEM
pIoman->pBlkDevSemaphore = FF_CreateSemaphore();
#endif
return pIoman; // Sucess, return the created object. return pIoman; // Sucess, return the created object.
} }
@ -189,38 +215,54 @@ FF_IOMAN *FF_CreateIOMAN(FF_T_UINT8 *pCacheMem, FF_T_UINT32 Size, FF_T_UINT16 Bl
**/ **/
FF_ERROR FF_DestroyIOMAN(FF_IOMAN *pIoman) { FF_ERROR FF_DestroyIOMAN(FF_IOMAN *pIoman) {
#ifdef FF_HASH_CACHE
FF_T_UINT32 i;
#endif
// Ensure no NULL pointer was provided. // Ensure no NULL pointer was provided.
if(!pIoman) { if(!pIoman) {
return FF_ERR_NULL_POINTER; return FF_ERR_NULL_POINTER | FF_DESTROYIOMAN;
} }
// Ensure pPartition pointer was allocated. // Ensure pPartition pointer was allocated.
if((pIoman->MemAllocation & FF_IOMAN_ALLOC_PART)) { if((pIoman->MemAllocation & FF_IOMAN_ALLOC_PART)) {
FF_Free(pIoman->pPartition); FF_FREE(pIoman->pPartition);
} }
// Ensure pBlkDevice pointer was allocated. // Ensure pBlkDevice pointer was allocated.
if((pIoman->MemAllocation & FF_IOMAN_ALLOC_BLKDEV)) { if((pIoman->MemAllocation & FF_IOMAN_ALLOC_BLKDEV)) {
FF_Free(pIoman->pBlkDevice); FF_FREE(pIoman->pBlkDevice);
} }
// Ensure pBuffers pointer was allocated. // Ensure pBuffers pointer was allocated.
if((pIoman->MemAllocation & FF_IOMAN_ALLOC_BUFDESCR)) { if((pIoman->MemAllocation & FF_IOMAN_ALLOC_BUFDESCR)) {
FF_Free(pIoman->pBuffers); FF_FREE(pIoman->pBuffers);
} }
// Ensure pCacheMem pointer was allocated. // Ensure pCacheMem pointer was allocated.
if((pIoman->MemAllocation & FF_IOMAN_ALLOC_BUFFERS)) { if((pIoman->MemAllocation & FF_IOMAN_ALLOC_BUFFERS)) {
FF_Free(pIoman->pCacheMem); FF_FREE(pIoman->pCacheMem);
} }
// Destroy any Semaphore that was created. // Destroy any Semaphore that was created.
if(pIoman->pSemaphore) { if(pIoman->pSemaphore) {
FF_DestroySemaphore(pIoman->pSemaphore); FF_DestroySemaphore(pIoman->pSemaphore);
} }
#ifdef FF_BLKDEV_USES_SEM
if(pIoman->pBlkDevSemaphore) {
FF_DestroySemaphore(pIoman->pBlkDevSemaphore);
}
#endif
// Destroy HashCache
#ifdef FF_HASH_CACHE
for(i = 0; i < FF_HASH_CACHE_DEPTH; i++) {
FF_DestroyHashTable(pIoman->HashCache[i].pHashTable);
}
#endif
// Finally free the FF_IOMAN object. // Finally free the FF_IOMAN object.
FF_Free(pIoman); FF_FREE(pIoman);
return FF_ERR_NONE; return FF_ERR_NONE;
} }
@ -236,100 +278,13 @@ static void FF_IOMAN_InitBufferDescriptors(FF_IOMAN *pIoman) {
FF_T_UINT16 i; FF_T_UINT16 i;
FF_BUFFER *pBuffer = pIoman->pBuffers; FF_BUFFER *pBuffer = pIoman->pBuffers;
pIoman->LastReplaced = 0; pIoman->LastReplaced = 0;
// HT : it is assmued that pBuffer was cleared by memset ()
for(i = 0; i < pIoman->CacheSize; i++) { for(i = 0; i < pIoman->CacheSize; i++) {
pBuffer->Mode = 0;
pBuffer->NumHandles = 0;
pBuffer->Persistance = 0;
pBuffer->LRU = 0;
pBuffer->Sector = 0;
pBuffer->pBuffer = (FF_T_UINT8 *)((pIoman->pCacheMem) + (pIoman->BlkSize * i)); pBuffer->pBuffer = (FF_T_UINT8 *)((pIoman->pCacheMem) + (pIoman->BlkSize * i));
pBuffer->Modified = FF_FALSE;
pBuffer->Valid = FF_FALSE;
pBuffer++; pBuffer++;
} }
} }
/**
* @private
* @brief Tests the Mode for validity.
*
* @param Mode Mode of buffer to check.
*
* @return FF_TRUE when valid, else FF_FALSE.
**/
/*static FF_T_BOOL FF_IOMAN_ModeValid(FF_T_UINT8 Mode) {
if(Mode == FF_MODE_READ || Mode == FF_MODE_WRITE) {
return FF_TRUE;
}
return FF_FALSE;
}*/
/**
* @private
* @brief Fills a buffer with the appropriate sector via the device driver.
*
* @param pIoman FF_IOMAN object.
* @param Sector LBA address of the sector to fetch.
* @param pBuffer Pointer to a byte-wise buffer to store the fetched data.
*
* @return FF_TRUE when valid, else FF_FALSE.
**/
static FF_ERROR FF_IOMAN_FillBuffer(FF_IOMAN *pIoman, FF_T_UINT32 Sector, FF_T_UINT8 *pBuffer) {
FF_T_SINT32 retVal = 0;
if(pIoman->pBlkDevice->fnReadBlocks) { // Make sure we don't execute a NULL.
do{
retVal = pIoman->pBlkDevice->fnReadBlocks(pBuffer, Sector, 1, pIoman->pBlkDevice->pParam);
if(retVal == FF_ERR_DRIVER_BUSY) {
FF_Sleep(FF_DRIVER_BUSY_SLEEP);
}
} while(retVal == FF_ERR_DRIVER_BUSY);
if(retVal < 0) {
return -1; // FF_ERR_DRIVER_FATAL_ERROR was returned Fail!
} else {
if(retVal == 1) {
return 0; // 1 Block was sucessfully read.
} else {
return -1; // 0 Blocks we're read, Error!
}
}
}
return -1; // error no device diver registered.
}
/**
* @private
* @brief Flushes a buffer to the device driver.
*
* @param pIoman FF_IOMAN object.
* @param Sector LBA address of the sector to fetch.
* @param pBuffer Pointer to a byte-wise buffer to store the fetched data.
*
* @return FF_TRUE when valid, else FF_FALSE.
**/
static FF_ERROR FF_IOMAN_FlushBuffer(FF_IOMAN *pIoman, FF_T_UINT32 Sector, FF_T_UINT8 *pBuffer) {
FF_T_SINT32 retVal = 0;
if(pIoman->pBlkDevice->fnWriteBlocks) { // Make sure we don't execute a NULL.
do{
retVal = pIoman->pBlkDevice->fnWriteBlocks(pBuffer, Sector, 1, pIoman->pBlkDevice->pParam);
if(retVal == FF_ERR_DRIVER_BUSY) {
FF_Sleep(FF_DRIVER_BUSY_SLEEP);
}
} while(retVal == FF_ERR_DRIVER_BUSY);
if(retVal < 0) {
return -1; // FF_ERR_DRIVER_FATAL_ERROR was returned Fail!
} else {
if(retVal == 1) {
return FF_ERR_NONE; // 1 Block was sucessfully written.
} else {
return -1; // 0 Blocks we're written, Error!
}
}
}
return -1; // error no device diver registered.
}
/** /**
* @private * @private
@ -344,7 +299,7 @@ FF_ERROR FF_FlushCache(FF_IOMAN *pIoman) {
FF_T_UINT16 i,x; FF_T_UINT16 i,x;
if(!pIoman) { if(!pIoman) {
return FF_ERR_NULL_POINTER; return FF_ERR_NULL_POINTER | FF_FLUSHCACHE;
} }
FF_PendSemaphore(pIoman->pSemaphore); FF_PendSemaphore(pIoman->pSemaphore);
@ -352,7 +307,7 @@ FF_ERROR FF_FlushCache(FF_IOMAN *pIoman) {
for(i = 0; i < pIoman->CacheSize; i++) { for(i = 0; i < pIoman->CacheSize; i++) {
if((pIoman->pBuffers + i)->NumHandles == 0 && (pIoman->pBuffers + i)->Modified == FF_TRUE) { if((pIoman->pBuffers + i)->NumHandles == 0 && (pIoman->pBuffers + i)->Modified == FF_TRUE) {
FF_IOMAN_FlushBuffer(pIoman, (pIoman->pBuffers + i)->Sector, (pIoman->pBuffers + i)->pBuffer); FF_BlockWrite(pIoman, (pIoman->pBuffers + i)->Sector, 1, (pIoman->pBuffers + i)->pBuffer);
// Buffer has now been flushed, mark it as a read buffer and unmodified. // Buffer has now been flushed, mark it as a read buffer and unmodified.
(pIoman->pBuffers + i)->Mode = FF_MODE_READ; (pIoman->pBuffers + i)->Mode = FF_MODE_READ;
@ -375,13 +330,6 @@ FF_ERROR FF_FlushCache(FF_IOMAN *pIoman) {
return FF_ERR_NONE; return FF_ERR_NONE;
} }
/*static FF_T_BOOL FF_isFATSector(FF_IOMAN *pIoman, FF_T_UINT32 Sector) {
if(Sector >= pIoman->pPartition->FatBeginLBA && Sector < (pIoman->pPartition->FatBeginLBA + pIoman->pPartition->ReservedSectors)) {
return FF_TRUE;
}
return FF_FALSE;
}*/
FF_BUFFER *FF_GetBuffer(FF_IOMAN *pIoman, FF_T_UINT32 Sector, FF_T_UINT8 Mode) { FF_BUFFER *FF_GetBuffer(FF_IOMAN *pIoman, FF_T_UINT32 Sector, FF_T_UINT8 Mode) {
FF_BUFFER *pBuffer; FF_BUFFER *pBuffer;
FF_BUFFER *pBufLRU = NULL; FF_BUFFER *pBufLRU = NULL;
@ -393,35 +341,13 @@ FF_BUFFER *FF_GetBuffer(FF_IOMAN *pIoman, FF_T_UINT32 Sector, FF_T_UINT8 Mode) {
while(!pBufMatch) { while(!pBufMatch) {
FF_PendSemaphore(pIoman->pSemaphore); FF_PendSemaphore(pIoman->pSemaphore);
{ {
for(i = 0; i < pIoman->CacheSize; i++) { pBuffer = pIoman->pBuffers;
// HT if a perfect match has priority, find that first
for(i = 0; i < pIoman->CacheSize; i++, pBuffer++) {
pBuffer = (pIoman->pBuffers + i); pBuffer = (pIoman->pBuffers + i);
if(pBuffer->Sector == Sector && pBuffer->Valid == FF_TRUE) { if(pBuffer->Sector == Sector && pBuffer->Valid == FF_TRUE) {
pBufMatch = pBuffer; pBufMatch = pBuffer;
} else { break; // Why look further if you found a perfect match?
if(pBuffer->NumHandles == 0) {
pBuffer->LRU += 1;
if(!pBufLRU) {
pBufLRU = pBuffer;
}
if(!pBufLHITS) {
pBufLHITS = pBuffer;
}
if(pBuffer->LRU >= pBufLRU->LRU) {
if(pBuffer->LRU == pBufLRU->LRU) {
if(pBuffer->Persistance > pBufLRU->Persistance) {
pBufLRU = pBuffer;
}
} else {
pBufLRU = pBuffer;
}
}
if(pBuffer->Persistance < pBufLHITS->Persistance) {
pBufLHITS = pBuffer;
}
}
} }
} }
@ -454,11 +380,38 @@ FF_BUFFER *FF_GetBuffer(FF_IOMAN *pIoman, FF_T_UINT32 Sector, FF_T_UINT8 Mode) {
pBufMatch = NULL; // Sector is already in use, keep yielding until its available! pBufMatch = NULL; // Sector is already in use, keep yielding until its available!
} else { } else {
// Choose a suitable buffer! pBuffer = pIoman->pBuffers;
for(i = 0; i < pIoman->CacheSize; i++, pBuffer++) {
if(pBuffer->NumHandles == 0) {
pBuffer->LRU += 1;
if(!pBufLRU) {
pBufLRU = pBuffer;
}
if(!pBufLHITS) {
pBufLHITS = pBuffer;
}
if(pBuffer->LRU >= pBufLRU->LRU) {
if(pBuffer->LRU == pBufLRU->LRU) {
if(pBuffer->Persistance > pBufLRU->Persistance) {
pBufLRU = pBuffer;
}
} else {
pBufLRU = pBuffer;
}
}
if(pBuffer->Persistance < pBufLHITS->Persistance) {
pBufLHITS = pBuffer;
}
}
}
if(pBufLRU) { if(pBufLRU) {
// Process the suitable candidate. // Process the suitable candidate.
if(pBufLRU->Modified == FF_TRUE) { if(pBufLRU->Modified == FF_TRUE) {
FF_IOMAN_FlushBuffer(pIoman, pBufLRU->Sector, pBufLRU->pBuffer); FF_BlockWrite(pIoman, pBufLRU->Sector, 1, pBufLRU->pBuffer);
} }
pBufLRU->Mode = Mode; pBufLRU->Mode = Mode;
pBufLRU->Persistance = 1; pBufLRU->Persistance = 1;
@ -472,7 +425,7 @@ FF_BUFFER *FF_GetBuffer(FF_IOMAN *pIoman, FF_T_UINT32 Sector, FF_T_UINT8 Mode) {
pBufLRU->Modified = FF_FALSE; pBufLRU->Modified = FF_FALSE;
} }
FF_IOMAN_FillBuffer(pIoman, Sector, pBufLRU->pBuffer); FF_BlockRead(pIoman, Sector, 1, pBufLRU->pBuffer);
pBufLRU->Valid = FF_TRUE; pBufLRU->Valid = FF_TRUE;
FF_ReleaseSemaphore(pIoman->pSemaphore); FF_ReleaseSemaphore(pIoman->pSemaphore);
return pBufLRU; return pBufLRU;
@ -481,7 +434,7 @@ FF_BUFFER *FF_GetBuffer(FF_IOMAN *pIoman, FF_T_UINT32 Sector, FF_T_UINT8 Mode) {
} }
} }
FF_ReleaseSemaphore(pIoman->pSemaphore); FF_ReleaseSemaphore(pIoman->pSemaphore);
FF_Yield(); FF_Yield(); // Better to go asleep to give low-priority task a chance to release buffer(s)
} }
return pBufMatch; // Return the Matched Buffer! return pBufMatch; // Return the Matched Buffer!
@ -500,7 +453,11 @@ void FF_ReleaseBuffer(FF_IOMAN *pIoman, FF_BUFFER *pBuffer) {
// Protect description changes with a semaphore. // Protect description changes with a semaphore.
FF_PendSemaphore(pIoman->pSemaphore); FF_PendSemaphore(pIoman->pSemaphore);
{ {
pBuffer->NumHandles--; if (pBuffer->NumHandles) {
pBuffer->NumHandles--;
} else {
//printf ("FF_ReleaseBuffer: buffer not claimed\n");
}
} }
FF_ReleaseSemaphore(pIoman->pSemaphore); FF_ReleaseSemaphore(pIoman->pSemaphore);
} }
@ -522,39 +479,94 @@ void FF_ReleaseBuffer(FF_IOMAN *pIoman, FF_BUFFER *pBuffer) {
**/ **/
FF_ERROR FF_RegisterBlkDevice(FF_IOMAN *pIoman, FF_T_UINT16 BlkSize, FF_WRITE_BLOCKS fnWriteBlocks, FF_READ_BLOCKS fnReadBlocks, void *pParam) { FF_ERROR FF_RegisterBlkDevice(FF_IOMAN *pIoman, FF_T_UINT16 BlkSize, FF_WRITE_BLOCKS fnWriteBlocks, FF_READ_BLOCKS fnReadBlocks, void *pParam) {
if(!pIoman) { // We can't do anything without an IOMAN object. if(!pIoman) { // We can't do anything without an IOMAN object.
return FF_ERR_NULL_POINTER; return FF_ERR_NULL_POINTER | FF_REGISTERBLKDEVICE;
} }
if((BlkSize % 512) != 0 || BlkSize == 0) { if((BlkSize % 512) != 0 || BlkSize == 0) {
return FF_ERR_IOMAN_DEV_INVALID_BLKSIZE; // BlkSize Size not a multiple of IOMAN's Expected BlockSize > 0 return FF_ERR_IOMAN_DEV_INVALID_BLKSIZE | FF_REGISTERBLKDEVICE; // BlkSize Size not a multiple of IOMAN's Expected BlockSize > 0
} }
if((BlkSize % pIoman->BlkSize) != 0 || BlkSize == 0) { if((BlkSize % pIoman->BlkSize) != 0 || BlkSize == 0) {
return FF_ERR_IOMAN_DEV_INVALID_BLKSIZE; // BlkSize Size not a multiple of IOMAN's Expected BlockSize > 0 return FF_ERR_IOMAN_DEV_INVALID_BLKSIZE | FF_REGISTERBLKDEVICE; // BlkSize Size not a multiple of IOMAN's Expected BlockSize > 0
} }
// Ensure that a device cannot be re-registered "mid-flight" // Ensure that a device cannot be re-registered "mid-flight"
// Doing so would corrupt the context of FullFAT // Doing so would corrupt the context of FullFAT
if(pIoman->pBlkDevice->fnReadBlocks) { if(pIoman->pBlkDevice->fnpReadBlocks) {
return FF_ERR_IOMAN_DEV_ALREADY_REGD; return FF_ERR_IOMAN_DEV_ALREADY_REGD | FF_REGISTERBLKDEVICE;
} }
if(pIoman->pBlkDevice->fnWriteBlocks) { if(pIoman->pBlkDevice->fnpWriteBlocks) {
return FF_ERR_IOMAN_DEV_ALREADY_REGD; return FF_ERR_IOMAN_DEV_ALREADY_REGD | FF_REGISTERBLKDEVICE;
} }
if(pIoman->pBlkDevice->pParam) { if(pIoman->pBlkDevice->pParam) {
return FF_ERR_IOMAN_DEV_ALREADY_REGD; return FF_ERR_IOMAN_DEV_ALREADY_REGD | FF_REGISTERBLKDEVICE;
} }
// Here we shall just set the values. // Here we shall just set the values.
// FullFAT checks before using any of these values. // FullFAT checks before using any of these values.
pIoman->pBlkDevice->devBlkSize = BlkSize; pIoman->pBlkDevice->devBlkSize = BlkSize;
pIoman->pBlkDevice->fnReadBlocks = fnReadBlocks; pIoman->pBlkDevice->fnpReadBlocks = fnReadBlocks;
pIoman->pBlkDevice->fnWriteBlocks = fnWriteBlocks; pIoman->pBlkDevice->fnpWriteBlocks = fnWriteBlocks;
pIoman->pBlkDevice->pParam = pParam; pIoman->pBlkDevice->pParam = pParam;
return FF_ERR_NONE; // Success return FF_ERR_NONE; // Success
} }
/*
New Interface for FullFAT to read blocks.
*/
FF_T_SINT32 FF_BlockRead(FF_IOMAN *pIoman, FF_T_UINT32 ulSectorLBA, FF_T_UINT32 ulNumSectors, void *pBuffer) {
FF_T_SINT32 slRetVal = 0;
if(pIoman->pPartition->TotalSectors) {
if((ulSectorLBA + ulNumSectors) > (pIoman->pPartition->TotalSectors + pIoman->pPartition->BeginLBA)) {
return -(FF_ERR_IOMAN_OUT_OF_BOUNDS_READ | FF_BLOCKREAD);
}
}
if(pIoman->pBlkDevice->fnpReadBlocks) { // Make sure we don't execute a NULL.
#ifdef FF_BLKDEV_USES_SEM
FF_PendSemaphore(pIoman->pBlkDevSemaphore);
#endif
slRetVal = pIoman->pBlkDevice->fnpReadBlocks(pBuffer, ulSectorLBA, ulNumSectors, pIoman->pBlkDevice->pParam);
#ifdef FF_BLKDEV_USES_SEM
FF_ReleaseSemaphore(pIoman->pBlkDevSemaphore);
#endif
if(FF_GETERROR(slRetVal) == FF_ERR_DRIVER_BUSY) {
FF_Sleep(FF_DRIVER_BUSY_SLEEP);
}
} while(FF_GETERROR(slRetVal) == FF_ERR_DRIVER_BUSY);
return slRetVal;
}
FF_T_SINT32 FF_BlockWrite(FF_IOMAN *pIoman, FF_T_UINT32 ulSectorLBA, FF_T_UINT32 ulNumSectors, void *pBuffer) {
FF_T_SINT32 slRetVal = 0;
if(pIoman->pPartition->TotalSectors) {
if((ulSectorLBA + ulNumSectors) > (pIoman->pPartition->TotalSectors + pIoman->pPartition->BeginLBA)) {
return -(FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE | FF_BLOCKWRITE);
}
}
if(pIoman->pBlkDevice->fnpWriteBlocks) { // Make sure we don't execute a NULL.
#ifdef FF_BLKDEV_USES_SEM
FF_PendSemaphore(pIoman->pBlkDevSemaphore);
#endif
slRetVal = pIoman->pBlkDevice->fnpWriteBlocks(pBuffer, ulSectorLBA, ulNumSectors, pIoman->pBlkDevice->pParam);
#ifdef FF_BLKDEV_USES_SEM
FF_ReleaseSemaphore(pIoman->pBlkDevSemaphore);
#endif
if(FF_GETERROR(slRetVal) == FF_ERR_DRIVER_BUSY) {
FF_Sleep(FF_DRIVER_BUSY_SLEEP);
}
} while(FF_GETERROR(slRetVal) == FF_ERR_DRIVER_BUSY);
return slRetVal;
}
/** /**
* @private * @private
**/ **/
@ -620,7 +632,7 @@ static FF_ERROR FF_DetermineFatType(FF_IOMAN *pIoman) {
testLong = FF_getLong(pBuffer->pBuffer, 0x0000); testLong = FF_getLong(pBuffer->pBuffer, 0x0000);
} }
FF_ReleaseBuffer(pIoman, pBuffer); FF_ReleaseBuffer(pIoman, pBuffer);
if((testLong & 0x0FFFFFF8) != 0x0FFFFFF8) { if((testLong & 0x0FFFFFF8) != 0x0FFFFFF8 && (testLong & 0x0FFFFFF8) != 0x0FFFFFF0) {
return FF_ERR_IOMAN_NOT_FAT_FORMATTED; return FF_ERR_IOMAN_NOT_FAT_FORMATTED;
} }
#endif #endif
@ -630,6 +642,119 @@ static FF_ERROR FF_DetermineFatType(FF_IOMAN *pIoman) {
return FF_ERR_IOMAN_NOT_FAT_FORMATTED; return FF_ERR_IOMAN_NOT_FAT_FORMATTED;
} }
static FF_T_SINT8 FF_PartitionCount (FF_T_UINT8 *pBuffer)
{
FF_T_SINT8 count = 0;
FF_T_SINT8 part;
// Check PBR or MBR signature
if (FF_getChar(pBuffer, FF_FAT_MBR_SIGNATURE) != 0x55 &&
FF_getChar(pBuffer, FF_FAT_MBR_SIGNATURE) != 0xAA ) {
// No MBR, but is it a PBR ?
if (FF_getChar(pBuffer, 0) == 0xEB && // PBR Byte 0
FF_getChar(pBuffer, 2) == 0x90 && // PBR Byte 2
(FF_getChar(pBuffer, 21) & 0xF0) == 0xF0) {// PBR Byte 21 : Media byte
return 1; // No MBR but PBR exist then only one partition
}
return 0; // No MBR and no PBR then no partition found
}
for (part = 0; part < 4; part++) {
FF_T_UINT8 active = FF_getChar(pBuffer, FF_FAT_PTBL + FF_FAT_PTBL_ACTIVE + (16 * part));
FF_T_UINT8 part_id = FF_getChar(pBuffer, FF_FAT_PTBL + FF_FAT_PTBL_ID + (16 * part));
// The first sector must be a MBR, then check the partition entry in the MBR
if (active != 0x80 && (active != 0 || part_id == 0)) {
break;
}
count++;
}
return count;
}
/*
Mount GPT Partition Tables
*/
#define FF_GPT_HEAD_ENTRY_SIZE 0x54
#define FF_GPT_HEAD_TOTAL_ENTRIES 0x50
#define FF_GPT_HEAD_PART_ENTRY_LBA 0x48
#define FF_GPT_ENTRY_FIRST_SECTOR_LBA 0x20
#define FF_GPT_HEAD_CRC 0x10
#define FF_GPT_HEAD_LENGTH 0x0C
static FF_ERROR FF_GetEfiPartitionEntry(FF_IOMAN *pIoman, FF_T_UINT32 ulPartitionNumber) {
// Continuing on from FF_MountPartition() pPartition->BeginLBA should be the sector of the GPT Header
FF_BUFFER *pBuffer;
FF_PARTITION *pPart = pIoman->pPartition;
FF_T_UINT32 ulBeginGPT;
FF_T_UINT32 ulEntrySector;
FF_T_UINT32 ulSectorOffset;
FF_T_UINT32 ulTotalPartitionEntries;
FF_T_UINT32 ulPartitionEntrySize;
FF_T_UINT32 ulGPTHeadCRC, ulGPTCrcCheck, ulGPTHeadLength;
if(ulPartitionNumber >= 128) {
return FF_ERR_IOMAN_INVALID_PARTITION_NUM;
}
pBuffer = FF_GetBuffer(pIoman, pPart->BeginLBA, FF_MODE_READ);
{
if(!pBuffer) {
return FF_ERR_DEVICE_DRIVER_FAILED;
}
// Verify this is an EFI header
if(memcmp(pBuffer->pBuffer, "EFI PART", 8) != 0) {
FF_ReleaseBuffer(pIoman, pBuffer);
return FF_ERR_IOMAN_INVALID_FORMAT;
}
ulBeginGPT = FF_getLong(pBuffer->pBuffer, FF_GPT_HEAD_PART_ENTRY_LBA);
ulTotalPartitionEntries = FF_getLong(pBuffer->pBuffer, FF_GPT_HEAD_TOTAL_ENTRIES);
ulPartitionEntrySize = FF_getLong(pBuffer->pBuffer, FF_GPT_HEAD_ENTRY_SIZE);
ulGPTHeadCRC = FF_getLong(pBuffer->pBuffer, FF_GPT_HEAD_CRC);
ulGPTHeadLength = FF_getLong(pBuffer->pBuffer, FF_GPT_HEAD_LENGTH);
// Calculate Head CRC
// Blank CRC field
FF_putLong(pBuffer->pBuffer, FF_GPT_HEAD_CRC, 0x00000000);
// Calculate CRC
ulGPTCrcCheck = FF_GetCRC32(pBuffer->pBuffer, ulGPTHeadLength);
// Restore The CRC field
FF_putLong(pBuffer->pBuffer, FF_GPT_HEAD_CRC, ulGPTHeadCRC);
}
FF_ReleaseBuffer(pIoman, pBuffer);
// Check CRC
if(ulGPTHeadCRC != ulGPTCrcCheck) {
return FF_ERR_IOMAN_GPT_HEADER_CORRUPT;
}
// Calculate Sector Containing the Partition Entry we want to use.
ulEntrySector = ((ulPartitionNumber * ulPartitionEntrySize) / pIoman->BlkSize) + ulBeginGPT;
ulSectorOffset = (ulPartitionNumber % (pIoman->BlkSize / ulPartitionEntrySize)) * ulPartitionEntrySize;
pBuffer = FF_GetBuffer(pIoman, ulEntrySector, FF_MODE_READ);
{
if(!pBuffer) {
return FF_ERR_DEVICE_DRIVER_FAILED;
}
pPart->BeginLBA = FF_getLong(pBuffer->pBuffer, ulSectorOffset + FF_GPT_ENTRY_FIRST_SECTOR_LBA);
}
FF_ReleaseBuffer(pIoman, pBuffer);
if(!pPart->BeginLBA) {
return FF_ERR_IOMAN_INVALID_PARTITION_NUM;
}
return FF_ERR_NONE;
}
/** /**
* @public * @public
* @brief Mounts the Specified partition, the volume specified by the FF_IOMAN object provided. * @brief Mounts the Specified partition, the volume specified by the FF_IOMAN object provided.
@ -651,31 +776,67 @@ static FF_ERROR FF_DetermineFatType(FF_IOMAN *pIoman) {
FF_ERROR FF_MountPartition(FF_IOMAN *pIoman, FF_T_UINT8 PartitionNumber) { FF_ERROR FF_MountPartition(FF_IOMAN *pIoman, FF_T_UINT8 PartitionNumber) {
FF_PARTITION *pPart; FF_PARTITION *pPart;
FF_BUFFER *pBuffer = 0; FF_BUFFER *pBuffer = 0;
FF_ERROR Error;
FF_T_UINT8 ucPartitionType;
int partCount;
if(!pIoman) { if(!pIoman) {
return FF_ERR_NULL_POINTER; return FF_ERR_NULL_POINTER;
} }
if(PartitionNumber > 3) { /*if(PartitionNumber > 3) {
return FF_ERR_IOMAN_INVALID_PARTITION_NUM; return FF_ERR_IOMAN_INVALID_PARTITION_NUM;
} }*/
pPart = pIoman->pPartition; pPart = pIoman->pPartition;
memset (pIoman->pBuffers, '\0', sizeof(FF_BUFFER) * pIoman->CacheSize);
memset (pIoman->pCacheMem, '\0', pIoman->BlkSize * pIoman->CacheSize);
FF_IOMAN_InitBufferDescriptors(pIoman);
pIoman->FirstFile = 0;
pBuffer = FF_GetBuffer(pIoman, 0, FF_MODE_READ); pBuffer = FF_GetBuffer(pIoman, 0, FF_MODE_READ);
if(!pBuffer) { if(!pBuffer) {
return FF_ERR_DEVICE_DRIVER_FAILED; return FF_ERR_DEVICE_DRIVER_FAILED;
} }
partCount = FF_PartitionCount (pBuffer->pBuffer);
pPart->BlkSize = FF_getShort(pBuffer->pBuffer, FF_FAT_BYTES_PER_SECTOR); pPart->BlkSize = FF_getShort(pBuffer->pBuffer, FF_FAT_BYTES_PER_SECTOR);
if((pPart->BlkSize % 512) == 0 && pPart->BlkSize > 0) { if (partCount == 0) { //(pPart->BlkSize % 512) == 0 && pPart->BlkSize > 0) {
// Volume is not partitioned (MBR Found) // Volume is not partitioned (MBR Found)
pPart->BeginLBA = 0; pPart->BeginLBA = 0;
} else { } else {
// Primary Partitions to deal with!
pPart->BeginLBA = FF_getLong(pBuffer->pBuffer, (FF_T_UINT16)(FF_FAT_PTBL + FF_FAT_PTBL_LBA + (16 * PartitionNumber))); ucPartitionType = FF_getChar(pBuffer->pBuffer, FF_FAT_PTBL + FF_FAT_PTBL_ID); // Ensure its not an EFI partition!
if(ucPartitionType != 0xEE) {
if(PartitionNumber > 3) {
FF_ReleaseBuffer(pIoman, pBuffer);
return FF_ERR_IOMAN_INVALID_PARTITION_NUM;
}
// Primary Partitions to deal with!
pPart->BeginLBA = FF_getLong(pBuffer->pBuffer, FF_FAT_PTBL + FF_FAT_PTBL_LBA + (16 * PartitionNumber));
}
FF_ReleaseBuffer(pIoman, pBuffer); FF_ReleaseBuffer(pIoman, pBuffer);
if(ucPartitionType == 0xEE) {
pPart->BeginLBA = FF_getLong(pBuffer->pBuffer, FF_FAT_PTBL + FF_FAT_PTBL_LBA);
Error = FF_GetEfiPartitionEntry(pIoman, PartitionNumber);
if(Error) {
return Error;
}
}
if(!pPart->BeginLBA) { if(!pPart->BeginLBA) {
return FF_ERR_IOMAN_NO_MOUNTABLE_PARTITION; return FF_ERR_IOMAN_NO_MOUNTABLE_PARTITION;
} }
@ -690,6 +851,7 @@ FF_ERROR FF_MountPartition(FF_IOMAN *pIoman, FF_T_UINT8 PartitionNumber) {
return FF_ERR_IOMAN_INVALID_FORMAT; return FF_ERR_IOMAN_INVALID_FORMAT;
} }
} }
// Assume FAT16, then we'll adjust if its FAT32 // Assume FAT16, then we'll adjust if its FAT32
pPart->ReservedSectors = FF_getShort(pBuffer->pBuffer, FF_FAT_RESERVED_SECTORS); pPart->ReservedSectors = FF_getShort(pBuffer->pBuffer, FF_FAT_RESERVED_SECTORS);
pPart->FatBeginLBA = pPart->BeginLBA + pPart->ReservedSectors; pPart->FatBeginLBA = pPart->BeginLBA + pPart->ReservedSectors;
@ -709,6 +871,7 @@ FF_ERROR FF_MountPartition(FF_IOMAN *pIoman, FF_T_UINT8 PartitionNumber) {
if(pPart->TotalSectors == 0) { if(pPart->TotalSectors == 0) {
pPart->TotalSectors = FF_getLong(pBuffer->pBuffer, FF_FAT_32_TOTAL_SECTORS); pPart->TotalSectors = FF_getLong(pBuffer->pBuffer, FF_FAT_32_TOTAL_SECTORS);
} }
memcpy (pPart->VolLabel, pBuffer->pBuffer + FF_FAT_32_VOL_LABEL, sizeof pPart->VolLabel);
} else { // FAT16 } else { // FAT16
pPart->ClusterBeginLBA = pPart->BeginLBA + pPart->ReservedSectors + (pPart->NumFATS * pPart->SectorsPerFAT); pPart->ClusterBeginLBA = pPart->BeginLBA + pPart->ReservedSectors + (pPart->NumFATS * pPart->SectorsPerFAT);
pPart->TotalSectors = (FF_T_UINT32) FF_getShort(pBuffer->pBuffer, FF_FAT_16_TOTAL_SECTORS); pPart->TotalSectors = (FF_T_UINT32) FF_getShort(pBuffer->pBuffer, FF_FAT_16_TOTAL_SECTORS);
@ -716,16 +879,29 @@ FF_ERROR FF_MountPartition(FF_IOMAN *pIoman, FF_T_UINT8 PartitionNumber) {
if(pPart->TotalSectors == 0) { if(pPart->TotalSectors == 0) {
pPart->TotalSectors = FF_getLong(pBuffer->pBuffer, FF_FAT_32_TOTAL_SECTORS); pPart->TotalSectors = FF_getLong(pBuffer->pBuffer, FF_FAT_32_TOTAL_SECTORS);
} }
memcpy (pPart->VolLabel, pBuffer->pBuffer + FF_FAT_16_VOL_LABEL, sizeof pPart->VolLabel);
} }
FF_ReleaseBuffer(pIoman, pBuffer); // Release the buffer finally! FF_ReleaseBuffer(pIoman, pBuffer); // Release the buffer finally!
if(!pPart->BlkSize) {
return FF_ERR_IOMAN_INVALID_FORMAT;
}
pPart->RootDirSectors = ((FF_getShort(pBuffer->pBuffer, FF_FAT_ROOT_ENTRY_COUNT) * 32) + pPart->BlkSize - 1) / pPart->BlkSize; pPart->RootDirSectors = ((FF_getShort(pBuffer->pBuffer, FF_FAT_ROOT_ENTRY_COUNT) * 32) + pPart->BlkSize - 1) / pPart->BlkSize;
pPart->FirstDataSector = pPart->ClusterBeginLBA + pPart->RootDirSectors; pPart->FirstDataSector = pPart->ClusterBeginLBA + pPart->RootDirSectors;
pPart->DataSectors = pPart->TotalSectors - (pPart->ReservedSectors + (pPart->NumFATS * pPart->SectorsPerFAT) + pPart->RootDirSectors); pPart->DataSectors = pPart->TotalSectors - (pPart->ReservedSectors + (pPart->NumFATS * pPart->SectorsPerFAT) + pPart->RootDirSectors);
if(!pPart->SectorsPerCluster) {
return FF_ERR_IOMAN_INVALID_FORMAT;
}
pPart->NumClusters = pPart->DataSectors / pPart->SectorsPerCluster; pPart->NumClusters = pPart->DataSectors / pPart->SectorsPerCluster;
if(FF_DetermineFatType(pIoman)) { Error = FF_DetermineFatType(pIoman);
return FF_ERR_IOMAN_NOT_FAT_FORMATTED;
if(Error) {
return Error;
} }
#ifdef FF_MOUNT_FIND_FREE #ifdef FF_MOUNT_FIND_FREE
@ -761,8 +937,8 @@ FF_ERROR FF_UnregisterBlkDevice(FF_IOMAN *pIoman) {
{ {
if(pIoman->pPartition->PartitionMounted == FF_FALSE) { if(pIoman->pPartition->PartitionMounted == FF_FALSE) {
pIoman->pBlkDevice->devBlkSize = 0; pIoman->pBlkDevice->devBlkSize = 0;
pIoman->pBlkDevice->fnReadBlocks = NULL; pIoman->pBlkDevice->fnpReadBlocks = NULL;
pIoman->pBlkDevice->fnWriteBlocks = NULL; pIoman->pBlkDevice->fnpWriteBlocks = NULL;
pIoman->pBlkDevice->pParam = NULL; pIoman->pBlkDevice->pParam = NULL;
} else { } else {
RetVal = FF_ERR_IOMAN_PARTITION_MOUNTED; RetVal = FF_ERR_IOMAN_PARTITION_MOUNTED;
@ -817,7 +993,11 @@ FF_ERROR FF_UnmountPartition(FF_IOMAN *pIoman) {
{ {
if(!FF_ActiveHandles(pIoman)) { if(!FF_ActiveHandles(pIoman)) {
if(pIoman->FirstFile == NULL) { if(pIoman->FirstFile == NULL) {
// Release Semaphore to call this function!
FF_ReleaseSemaphore(pIoman->pSemaphore);
FF_FlushCache(pIoman); // Flush any unwritten sectors to disk. FF_FlushCache(pIoman); // Flush any unwritten sectors to disk.
// Reclaim Semaphore
FF_PendSemaphore(pIoman->pSemaphore);
pIoman->pPartition->PartitionMounted = FF_FALSE; pIoman->pPartition->PartitionMounted = FF_FALSE;
} else { } else {
RetVal = FF_ERR_IOMAN_ACTIVE_HANDLES; RetVal = FF_ERR_IOMAN_ACTIVE_HANDLES;
@ -834,12 +1014,17 @@ FF_ERROR FF_UnmountPartition(FF_IOMAN *pIoman) {
FF_ERROR FF_IncreaseFreeClusters(FF_IOMAN *pIoman, FF_T_UINT32 Count) { FF_ERROR FF_IncreaseFreeClusters(FF_IOMAN *pIoman, FF_T_UINT32 Count) {
FF_ERROR Error;
//FF_PendSemaphore(pIoman->pSemaphore); //FF_PendSemaphore(pIoman->pSemaphore);
//{ //{
if(!pIoman->pPartition->FreeClusterCount) { if(!pIoman->pPartition->FreeClusterCount) {
pIoman->pPartition->FreeClusterCount = FF_CountFreeClusters(pIoman); pIoman->pPartition->FreeClusterCount = FF_CountFreeClusters(pIoman, &Error);
if(Error) {
return Error;
}
} else {
pIoman->pPartition->FreeClusterCount += Count;
} }
pIoman->pPartition->FreeClusterCount += Count;
//} //}
//FF_ReleaseSemaphore(pIoman->pSemaphore); //FF_ReleaseSemaphore(pIoman->pSemaphore);
@ -848,12 +1033,18 @@ FF_ERROR FF_IncreaseFreeClusters(FF_IOMAN *pIoman, FF_T_UINT32 Count) {
FF_ERROR FF_DecreaseFreeClusters(FF_IOMAN *pIoman, FF_T_UINT32 Count) { FF_ERROR FF_DecreaseFreeClusters(FF_IOMAN *pIoman, FF_T_UINT32 Count) {
FF_ERROR Error;
//FF_lockFAT(pIoman); //FF_lockFAT(pIoman);
//{ //{
if(!pIoman->pPartition->FreeClusterCount) { if(!pIoman->pPartition->FreeClusterCount) {
pIoman->pPartition->FreeClusterCount = FF_CountFreeClusters(pIoman); pIoman->pPartition->FreeClusterCount = FF_CountFreeClusters(pIoman, &Error);
if(Error) {
return Error;
}
} else {
pIoman->pPartition->FreeClusterCount -= Count;
} }
pIoman->pPartition->FreeClusterCount -= Count;
//} //}
//FF_unlockFAT(pIoman); //FF_unlockFAT(pIoman);

View file

@ -48,87 +48,55 @@
#include "ff_memory.h" #include "ff_memory.h"
#include "ff_config.h" #include "ff_config.h"
#ifdef FF_LITTLE_ENDIAN
/**
* @public
* @brief 8 bit memory access routines.
**/
/* /*
These functions swap the byte-orders of shorts and longs. A getChar function is provided * HT inlined these functions
incase there is a system that doesn't have byte-wise access to all memory. *
* Not much left for the C-module
*/
These functions can be replaced with your own platform specific byte-order swapping routines
for more efficiency.
The provided functions should work on almost all platforms. #ifndef FF_INLINE_MEMORY_ACCESS
*/ FF_T_UINT8 FF_getChar(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset) {
FF_T_UINT8 FF_getChar(FF_T_UINT8 *pBuffer, FF_T_UINT16 offset) { return (FF_T_UINT8) (pBuffer[aOffset]);
return (FF_T_UINT8) (pBuffer[offset]);
} }
FF_T_UINT16 FF_getShort(FF_T_UINT8 *pBuffer, FF_T_UINT16 offset) { FF_T_UINT16 FF_getShort(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset) {
return (FF_T_UINT16) (pBuffer[offset] & 0x00FF) | ((FF_T_UINT16) (pBuffer[offset+1] << 8) & 0xFF00); FF_T_UN16 u16;
pBuffer += aOffset;
u16.bytes.u8_1 = pBuffer[1];
u16.bytes.u8_0 = pBuffer[0];
return u16.u16;
} }
FF_T_UINT32 FF_getLong(FF_T_UINT8 *pBuffer, FF_T_UINT16 offset) { FF_T_UINT32 FF_getLong(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset) {
return (FF_T_UINT32) (pBuffer[offset] & 0x000000FF) | ((FF_T_UINT32) (pBuffer[offset+1] << 8) & 0x0000FF00) | ((FF_T_UINT32) (pBuffer[offset+2] << 16) & 0x00FF0000) | ((FF_T_UINT32) (pBuffer[offset+3] << 24) & 0xFF000000); FF_T_UN32 u32;
pBuffer += aOffset;
u32.bytes.u8_3 = pBuffer[3];
u32.bytes.u8_2 = pBuffer[2];
u32.bytes.u8_1 = pBuffer[1];
u32.bytes.u8_0 = pBuffer[0];
return u32.u32;
} }
void FF_putChar(FF_T_UINT8 *pBuffer, FF_T_UINT16 offset, FF_T_UINT8 Value) { void FF_putChar(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset, FF_T_UINT8 Value) {
pBuffer[offset] = Value; pBuffer[aOffset] = Value;
} }
void FF_putShort(FF_T_UINT8 *pBuffer, FF_T_UINT16 offset, FF_T_UINT16 Value) { void FF_putShort(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset, FF_T_UINT16 Value) {
FF_T_UINT8 *Val = (FF_T_UINT8 *) &Value; FF_T_UN16 u16;
pBuffer[offset] = Val[0]; u16.u16 = Value;
pBuffer[offset + 1] = Val[1]; pBuffer += aOffset;
pBuffer[0] = u16.bytes.u8_0;
pBuffer[1] = u16.bytes.u8_1;
} }
void FF_putLong(FF_T_UINT8 *pBuffer, FF_T_UINT16 offset, FF_T_UINT32 Value) { void FF_putLong(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset, FF_T_UINT32 Value) {
FF_T_UINT8 *Val = (FF_T_UINT8 *) &Value; FF_T_UN32 u32;
pBuffer[offset] = Val[0]; u32.u32 = Value;
pBuffer[offset + 1] = Val[1]; pBuffer += aOffset;
pBuffer[offset + 2] = Val[2]; pBuffer[0] = u32.bytes.u8_0;
pBuffer[offset + 3] = Val[3]; pBuffer[1] = u32.bytes.u8_1;
} pBuffer[2] = u32.bytes.u8_2;
pBuffer[3] = u32.bytes.u8_3;
#endif
#ifdef FF_BIG_ENDIAN
/*
These haven't been tested or checked. They should work in theory :)
Please contact james@worm.me.uk if they don't work, and also any fix.
*/
FF_T_UINT8 FF_getChar(FF_T_UINT8 *pBuffer, FF_T_UINT16 offset) {
return (FF_T_UINT8) (pBuffer[offset]);
}
FF_T_UINT16 FF_getShort(FF_T_UINT8 *pBuffer, FF_T_UINT16 offset) {
return (FF_T_UINT16) ((pBuffer[offset] & 0xFF00) << 8) | ((FF_T_UINT16) (pBuffer[offset+1]) & 0x00FF);
}
FF_T_UINT32 FF_getLong(FF_T_UINT8 *pBuffer, FF_T_UINT16 offset) {
return (FF_T_UINT32) ((pBuffer[offset] << 24) & 0xFF0000) | ((FF_T_UINT32) (pBuffer[offset+1] << 16) & 0x00FF0000) | ((FF_T_UINT32) (pBuffer[offset+2] << 8) & 0x0000FF00) | ((FF_T_UINT32) (pBuffer[offset+3]) & 0x000000FF);
}
void FF_putChar(FF_T_UINT8 *pBuffer, FF_T_UINT16 offset, FF_T_UINT8 Value) {
pBuffer[offset] = Value;
}
void FF_putShort(FF_T_UINT8 *pBuffer, FF_T_UINT16 offset, FF_T_UINT16 Value) {
FF_T_UINT8 *Val = (FF_T_UINT8 *) &Value;
pBuffer[offset] = Val[1];
pBuffer[offset + 1] = Val[0];
}
void FF_putLong(FF_T_UINT8 *pBuffer, FF_T_UINT16 offset, FF_T_UINT32 Value) {
FF_T_UINT8 *Val = (FF_T_UINT8 *) &Value;
pBuffer[offset] = Val[3];
pBuffer[offset + 1] = Val[2];
pBuffer[offset + 2] = Val[1];
pBuffer[offset + 3] = Val[0];
} }
#endif #endif

View file

@ -55,50 +55,113 @@
**/ **/
#include "ff_safety.h" // Íncludes ff_types.h #include "ff_safety.h" // Íncludes ff_types.h
#include <ntifs.h>
#define TAG_FULLFAT 'FLUF'
// Call your OS's CreateSemaphore function
//
void *FF_CreateSemaphore(void) { void *FF_CreateSemaphore(void) {
// Call your OS's CreateSemaphore function PKSEMAPHORE ProcessSemaphore;
//
// return pointer to semaphore /* Allocate some memory to store the semaphore */
return NULL; // Comment this out for your implementation. ProcessSemaphore = ExAllocatePoolWithTag(NonPagedPool,
sizeof(KSEMAPHORE),
TAG_FULLFAT);
if (ProcessSemaphore)
{
/* Initialize it */
KeInitializeSemaphore(ProcessSemaphore,
0,
MAXLONG);
}
return ProcessSemaphore;
} }
// Call your OS's PendSemaphore with the provided pSemaphore pointer.
//
// This should block indefinitely until the Semaphore
// becomes available. (No timeout!)
// If your OS doesn't do it for you, you should sleep
// this thread until the Semaphore is available.
void FF_PendSemaphore(void *pSemaphore) { void FF_PendSemaphore(void *pSemaphore) {
// Call your OS's PendSemaphore with the provided pSemaphore pointer. NTSTATUS Status;
//
// This should block indefinitely until the Semaphore /* Sanity check */
// becomes available. (No timeout!) if (pSemaphore)
// If your OS doesn't do it for you, you should sleep {
// this thread until the Semaphore is available. /* Wait for the sempaphore to become signaled */
pSemaphore = 0; Status = KeWaitForSingleObject(pSemaphore,
Executive,
KernelMode,
FALSE,
NULL);
if (NT_SUCCESS(Status))
{
if (Status != STATUS_SUCCESS)
{
// log an error?
}
}
else
{
// log an error?
}
}
} }
// Call your OS's ReleaseSemaphore with the provided pSemaphore pointer.
//
void FF_ReleaseSemaphore(void *pSemaphore) { void FF_ReleaseSemaphore(void *pSemaphore) {
// Call your OS's ReleaseSemaphore with the provided pSemaphore pointer.
//
// /* Sanity check */
pSemaphore = 0; if (pSemaphore)
{
/* Increment the semaphore */
KeReleaseSemaphore(pSemaphore,
0,
1,
FALSE);
}
} }
// Call your OS's DestroySemaphore with the provided pSemaphore pointer.
//
void FF_DestroySemaphore(void *pSemaphore) { void FF_DestroySemaphore(void *pSemaphore) {
// Call your OS's DestroySemaphore with the provided pSemaphore pointer.
//
// /* Sanity check */
pSemaphore = 0; if (pSemaphore)
{
/* Free the semaphore memory */
ExFreePoolWithTag(pSemaphore,
TAG_FULLFAT);
}
} }
// FIXME: what do we do with this?
void FF_Yield(void) { void FF_Yield(void) {
// Call your OS's thread Yield function. // Call your OS's thread Yield function.
// If this doesn't work, then a deadlock will occur // If this doesn't work, then a deadlock will occur
} }
// Call your OS's thread sleep function,
// Sleep for TimeMs milliseconds
void FF_Sleep(FF_T_UINT32 TimeMs) { void FF_Sleep(FF_T_UINT32 TimeMs) {
// Call your OS's thread sleep function, LARGE_INTEGER Interval;
// Sleep for TimeMs milliseconds NTSTATUS Status;
TimeMs = 0;
/* Calculate the interval */
Interval.QuadPart = -((LONGLONG)TimeMs * 10000);
/* Do the wait */
Status = KeDelayExecutionThread(KernelMode,
FALSE,
&Interval);
if (!NT_SUCCESS(Status))
{
// log an error?
}
} }

View file

@ -42,27 +42,57 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h>
#include "ff_string.h" #include "ff_string.h"
#include "ff_error.h"
#ifdef FF_UNICODE_SUPPORT
#include <wchar.h>
#include <wctype.h>
#endif
/* /*
* These will eventually be moved into a platform independent string * These will eventually be moved into a platform independent string
* library. Which will be optional. (To allow the use of system specific versions). * library. Which will be optional. (To allow the use of system specific versions).
*/ */
#ifdef FF_UNICODE_SUPPORT
void FF_cstrntowcs(FF_T_WCHAR *wcsDest, const FF_T_INT8 *szpSource, FF_T_UINT32 len) {
while(*szpSource && len--) {
*wcsDest++ = *szpSource++;
}
*wcsDest = '\0';
}
void FF_cstrtowcs(FF_T_WCHAR *wcsDest, const FF_T_INT8 *szpSource) {
while(*szpSource) {
*wcsDest++ = (FF_T_WCHAR) *szpSource++;
}
*wcsDest = '\0';
}
void FF_wcstocstr(FF_T_INT8 *szpDest, const FF_T_WCHAR *wcsSource) {
while(*wcsSource) {
*szpDest++ = (FF_T_INT8) *wcsSource++;
}
*szpDest = '\0';
}
void FF_wcsntocstr(FF_T_INT8 *szpDest, const FF_T_WCHAR *wcsSource, FF_T_UINT32 len) {
while(*wcsSource && len--) {
*szpDest++ = (FF_T_INT8) *wcsSource++;
}
*szpDest = '\0';
}
#endif
/** /**
* @private * @private
* @brief Converts an ASCII string to lowercase. * @brief Converts an ASCII string to lowercase.
**/ **/
void FF_tolower(FF_T_INT8 *string, FF_T_UINT32 strLen) { #ifndef FF_UNICODE_SUPPORT
FF_T_UINT32 i;
for(i = 0; i < strLen; i++) {
if(string[i] >= 'A' && string[i] <= 'Z')
string[i] += 32;
if(string[i] == '\0')
break;
}
}
/** /**
* @private * @private
* @brief Converts an ASCII string to uppercase. * @brief Converts an ASCII string to uppercase.
@ -76,6 +106,32 @@ void FF_toupper(FF_T_INT8 *string, FF_T_UINT32 strLen) {
break; break;
} }
} }
void FF_tolower(FF_T_INT8 *string, FF_T_UINT32 strLen) {
FF_T_UINT32 i;
for(i = 0; i < strLen; i++) {
if(string[i] >= 'A' && string[i] <= 'Z')
string[i] += 32;
if(string[i] == '\0')
break;
}
}
#else
void FF_toupper(FF_T_WCHAR *string, FF_T_UINT32 strLen) {
FF_T_UINT32 i;
for(i = 0; i < strLen; i++) {
string[i] = towupper(string[i]);
}
}
void FF_tolower(FF_T_WCHAR *string, FF_T_UINT32 strLen) {
FF_T_UINT32 i;
for(i = 0; i < strLen; i++) {
string[i] = towlower(string[i]);
}
}
#endif
/** /**
@ -84,6 +140,8 @@ void FF_toupper(FF_T_INT8 *string, FF_T_UINT32 strLen) {
* otherwise FF_FALSE is returned. * otherwise FF_FALSE is returned.
* *
**/ **/
#ifndef FF_UNICODE_SUPPORT
FF_T_BOOL FF_strmatch(const FF_T_INT8 *str1, const FF_T_INT8 *str2, FF_T_UINT16 len) { FF_T_BOOL FF_strmatch(const FF_T_INT8 *str1, const FF_T_INT8 *str2, FF_T_UINT16 len) {
register FF_T_UINT16 i; register FF_T_UINT16 i;
register FF_T_INT8 char1, char2; register FF_T_INT8 char1, char2;
@ -112,12 +170,38 @@ FF_T_BOOL FF_strmatch(const FF_T_INT8 *str1, const FF_T_INT8 *str2, FF_T_UINT16
return FF_TRUE; return FF_TRUE;
} }
#else
FF_T_BOOL FF_strmatch(const FF_T_WCHAR *str1, const FF_T_WCHAR *str2, FF_T_UINT16 len) {
register FF_T_UINT16 i;
register FF_T_WCHAR char1, char2;
if(!len) {
if(wcslen(str1) != wcslen(str2)) {
return FF_FALSE;
}
len = (FF_T_UINT16) wcslen(str1);
}
for(i = 0; i < len; i++) {
char1 = towlower(str1[i]);
char2 = towlower(str2[i]);
if(char1 != char2) {
return FF_FALSE;
}
}
return FF_TRUE;
}
#endif
/** /**
* @private * @private
* @brief A re-entrant Strtok function. No documentation is provided :P * @brief A re-entrant Strtok function. No documentation is provided :P
* Use at your own risk. (This is for FullFAT's use only). * Use at your own risk. (This is for FullFAT's use only).
**/ **/
#ifndef FF_UNICODE_SUPPORT
FF_T_INT8 *FF_strtok(const FF_T_INT8 *string, FF_T_INT8 *token, FF_T_UINT16 *tokenNumber, FF_T_BOOL *last, FF_T_UINT16 Length) { FF_T_INT8 *FF_strtok(const FF_T_INT8 *string, FF_T_INT8 *token, FF_T_UINT16 *tokenNumber, FF_T_BOOL *last, FF_T_UINT16 Length) {
FF_T_UINT16 strLen = Length; FF_T_UINT16 strLen = Length;
FF_T_UINT16 i,y, tokenStart, tokenEnd = 0; FF_T_UINT16 i,y, tokenStart, tokenEnd = 0;
@ -153,20 +237,80 @@ FF_T_INT8 *FF_strtok(const FF_T_INT8 *string, FF_T_INT8 *token, FF_T_UINT16 *tok
} }
tokenEnd = i; tokenEnd = i;
} }
if((tokenEnd - tokenStart) < FF_MAX_FILENAME) {
memcpy(token, (string + tokenStart), (FF_T_UINT32)(tokenEnd - tokenStart)); memcpy(token, (string + tokenStart), (FF_T_UINT32)(tokenEnd - tokenStart));
token[tokenEnd - tokenStart] = '\0'; token[tokenEnd - tokenStart] = '\0';
} else {
memcpy(token, (string + tokenStart), (FF_T_UINT32)(FF_MAX_FILENAME));
token[FF_MAX_FILENAME-1] = '\0';
}
//token[tokenEnd - tokenStart] = '\0';
*tokenNumber += 1; *tokenNumber += 1;
return token; return token;
} }
#else
FF_T_WCHAR *FF_strtok(const FF_T_WCHAR *string, FF_T_WCHAR *token, FF_T_UINT16 *tokenNumber, FF_T_BOOL *last, FF_T_UINT16 Length) {
FF_T_UINT16 strLen = Length;
FF_T_UINT16 i,y, tokenStart, tokenEnd = 0;
FF_T_BOOL FF_wildcompare(const FF_T_INT8 *pszWildCard, const FF_T_INT8 *pszString) { i = 0;
/* Check to see if the string contains the wild card */ y = 0;
if(string[i] == '\\' || string[i] == '/') {
i++;
}
tokenStart = i;
while(i < strLen) {
if(string[i] == '\\' || string[i] == '/') {
y++;
if(y == *tokenNumber) {
tokenStart = (FF_T_UINT16)(i + 1);
}
if(y == (*tokenNumber + 1)) {
tokenEnd = i;
break;
}
}
i++;
}
if(!tokenEnd) {
if(*last == FF_TRUE) {
return NULL;
} else {
*last = FF_TRUE;
}
tokenEnd = i;
}
if((tokenEnd - tokenStart) < FF_MAX_FILENAME) {
memcpy(token, (string + tokenStart), (FF_T_UINT32)(tokenEnd - tokenStart) * sizeof(FF_T_WCHAR));
token[tokenEnd - tokenStart] = '\0';
} else {
memcpy(token, (string + tokenStart), (FF_T_UINT32)(FF_MAX_FILENAME) * sizeof(FF_T_WCHAR));
token[FF_MAX_FILENAME-1] = '\0';
}
//token[tokenEnd - tokenStart] = '\0';
*tokenNumber += 1;
return token;
}
#endif
/*
A Wild-Card Comparator Library function, Provided by Adam Fullerton.
This can be extended or altered to improve or advance wildCard matching
of the FF_FindFirst() and FF_FindNext() API's.
*/
#ifdef FF_FINDAPI_ALLOW_WILDCARDS
/*FF_T_BOOL FF_wildcompare(const FF_T_INT8 *pszWildCard, const FF_T_INT8 *pszString) {
// Check to see if the string contains the wild card
if (!memchr(pszWildCard, '*', strlen(pszWildCard))) if (!memchr(pszWildCard, '*', strlen(pszWildCard)))
{ {
/* if it does not then do a straight string compare */ // if it does not then do a straight string compare
if (strcmp(pszWildCard, pszString)) if (strcmp(pszWildCard, pszString))
{ {
return FF_FALSE; return FF_FALSE;
@ -177,20 +321,20 @@ FF_T_BOOL FF_wildcompare(const FF_T_INT8 *pszWildCard, const FF_T_INT8 *pszStrin
while ((*pszWildCard) while ((*pszWildCard)
&& (*pszString)) && (*pszString))
{ {
/* Test for the wild card */ // Test for the wild card
if (*pszWildCard == '*') if (*pszWildCard == '*')
{ {
/* Eat more than one */ // Eat more than one
while (*pszWildCard == '*') while (*pszWildCard == '*')
{ {
pszWildCard++; pszWildCard++;
} }
/* If there are more chars in the string */ // If there are more chars in the string
if (*pszWildCard) if (*pszWildCard)
{ {
/* Search for the next char */ // Search for the next char
pszString = memchr(pszString, (int)*pszWildCard, strlen(pszString)); pszString = memchr(pszString, (int)*pszWildCard, strlen(pszString));
/* if it does not exist then the strings don't match */ // if it does not exist then the strings don't match
if (!pszString) if (!pszString)
{ {
return FF_FALSE; return FF_FALSE;
@ -201,7 +345,7 @@ FF_T_BOOL FF_wildcompare(const FF_T_INT8 *pszWildCard, const FF_T_INT8 *pszStrin
{ {
if (*pszWildCard) if (*pszWildCard)
{ {
/* continue */ // continue
break; break;
} }
else else
@ -212,17 +356,17 @@ FF_T_BOOL FF_wildcompare(const FF_T_INT8 *pszWildCard, const FF_T_INT8 *pszStrin
} }
else else
{ {
/* Fail if they don't match */ // Fail if they don't match
if (*pszWildCard != *pszString) if (*pszWildCard != *pszString)
{ {
return FF_FALSE; return FF_FALSE;
} }
} }
/* Bump both pointers */ // Bump both pointers
pszWildCard++; pszWildCard++;
pszString++; pszString++;
} }
/* fail if different lengths */ // fail if different lengths
if (*pszWildCard != *pszString) if (*pszWildCard != *pszString)
{ {
return FF_FALSE; return FF_FALSE;
@ -230,5 +374,83 @@ FF_T_BOOL FF_wildcompare(const FF_T_INT8 *pszWildCard, const FF_T_INT8 *pszStrin
} }
return FF_TRUE; return FF_TRUE;
} }*/
/*
This is a better Wild-card compare function, that works perfectly, and is much more efficient.
This function was contributed by one of our commercial customers.
*/
#ifdef FF_UNICODE_SUPPORT
FF_T_BOOL FF_wildcompare(const FF_T_WCHAR *pszWildCard, const FF_T_WCHAR *pszString) {
register const FF_T_WCHAR *pszWc = NULL;
register const FF_T_WCHAR *pszStr = NULL; // Encourage the string pointers to be placed in memory.
do {
if ( *pszWildCard == '*' ) {
while(*(1 + pszWildCard++) == '*'); // Eat up multiple '*''s
pszWc = (pszWildCard - 1);
pszStr = pszString;
}
if (*pszWildCard == '?' && !*pszString) {
return FF_FALSE; // False when the string is ended, yet a ? charachter is demanded.
}
#ifdef FF_WILDCARD_CASE_INSENSITIVE
if (*pszWildCard != '?' && tolower(*pszWildCard) != tolower(*pszString)) {
#else
if (*pszWildCard != '?' && *pszWildCard != *pszString) {
#endif
if (pszWc == NULL) {
return FF_FALSE;
}
pszWildCard = pszWc;
pszString = pszStr++;
}
} while ( *pszWildCard++ && *pszString++ );
while(*pszWildCard == '*') {
pszWildCard++;
}
if(!*(pszWildCard - 1)) { // WildCard is at the end. (Terminated)
return FF_TRUE; // Therefore this must be a match.
}
return FF_FALSE; // If not, then return FF_FALSE!
}
#else
FF_T_BOOL FF_wildcompare(const FF_T_INT8 *pszWildCard, const FF_T_INT8 *pszString) {
register const FF_T_INT8 *pszWc = NULL;
register const FF_T_INT8 *pszStr = NULL; // Encourage the string pointers to be placed in memory.
do {
if ( *pszWildCard == '*' ) {
while(*(1 + pszWildCard++) == '*'); // Eat up multiple '*''s
pszWc = (pszWildCard - 1);
pszStr = pszString;
}
if (*pszWildCard == '?' && !*pszString) {
return FF_FALSE; // False when the string is ended, yet a ? charachter is demanded.
}
#ifdef FF_WILDCARD_CASE_INSENSITIVE
if (*pszWildCard != '?' && tolower(*pszWildCard) != tolower(*pszString)) {
#else
if (*pszWildCard != '?' && *pszWildCard != *pszString) {
#endif
if (pszWc == NULL) {
return FF_FALSE;
}
pszWildCard = pszWc;
pszString = pszStr++;
}
} while ( *pszWildCard++ && *pszString++ );
while(*pszWildCard == '*') {
pszWildCard++;
}
if(!*(pszWildCard - 1)) { // WildCard is at the end. (Terminated)
return FF_TRUE; // Therefore this must be a match.
}
return FF_FALSE; // If not, then return FF_FALSE!
}
#endif
#endif

294
lib/3rdparty/fullfat/ff_unicode.c vendored Normal file
View file

@ -0,0 +1,294 @@
/*****************************************************************************
* FullFAT - High Performance, Thread-Safe Embedded FAT File-System *
* Copyright (C) 2009 James Walmsley (james@worm.me.uk) *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
* IMPORTANT NOTICE: *
* ================= *
* Alternative Licensing is available directly from the Copyright holder, *
* (James Walmsley). For more information consult LICENSING.TXT to obtain *
* a Commercial license. *
* *
* See RESTRICTIONS.TXT for extra restrictions on the use of FullFAT. *
* *
* Removing the above notice is illegal and will invalidate this license. *
*****************************************************************************
* See http://worm.me.uk/fullfat for more information. *
* Or http://fullfat.googlecode.com/ for latest releases and the wiki. *
*****************************************************************************/
/**
* @file ff_unicode.c
* @author James Walmsley
* @ingroup UNICODE
*
* @defgroup UNICODE FullFAT UNICODE Library
* @brief Portable UNICODE Transformation Library for FullFAT
*
**/
#include "ff_unicode.h"
#include "string.h"
// UTF-8 Routines
/*
UCS-4 range (hex.) UTF-8 octet sequence (binary)
0000 0000-0000 007F 0xxxxxxx
0000 0080-0000 07FF 110xxxxx 10xxxxxx
0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx -- We don't encode these because we won't receive them. (Invalid UNICODE).
0400 0000-7FFF FFFF 1111110x 10xxxxxx ... 10xxxxxx -- We don't encode these because we won't receive them. (Invalid UNICODE).
*/
FF_T_UINT FF_GetUtf16SequenceLen(FF_T_UINT16 usLeadChar) {
if((usLeadChar & 0xFC00) == 0xD800) {
return 2;
}
return 1;
}
/*
Returns the number of UTF-8 units read.
Will not exceed ulSize UTF-16 units. (ulSize * 2 bytes).
*/
/*
UCS-4 range (hex.) UTF-8 octet sequence (binary)
0000 0000-0000 007F 0xxxxxxx
0000 0080-0000 07FF 110xxxxx 10xxxxxx
0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx -- We don't encode these because we won't receive them. (Invalid UNICODE).
0400 0000-7FFF FFFF 1111110x 10xxxxxx ... 10xxxxxx -- We don't encode these because we won't receive them. (Invalid UNICODE).
*/
FF_T_SINT32 FF_Utf8ctoUtf16c(FF_T_UINT16 *utf16Dest, const FF_T_UINT8 *utf8Source, FF_T_UINT32 ulSize) {
FF_T_UINT32 ulUtf32char;
FF_T_UINT16 utf16Source = 0;
register FF_T_INT uiSequenceNumber = 0;
while((*utf8Source & (0x80 >> (uiSequenceNumber)))) { // Count number of set bits before a zero.
uiSequenceNumber++;
}
if(!uiSequenceNumber) {
uiSequenceNumber++;
}
if(!ulSize) {
return FF_ERR_UNICODE_DEST_TOO_SMALL;
}
switch(uiSequenceNumber) {
case 1:
utf16Source = (FF_T_UINT16) *utf8Source;
memcpy(utf16Dest,&utf16Source,sizeof(FF_T_UINT16));
//bobtntfullfat *utf16Dest = (FF_T_UINT16) *utf8Source;
break;
case 2:
utf16Source =(FF_T_UINT16) ((*utf8Source & 0x1F) << 6) | ((*(utf8Source + 1) & 0x3F));
memcpy(utf16Dest,&utf16Source,sizeof(FF_T_UINT16));
//bobtntfullfat *utf16Dest = (FF_T_UINT16) ((*utf8Source & 0x1F) << 6) | ((*(utf8Source + 1) & 0x3F));
break;
case 3:
utf16Source =(FF_T_UINT16) ((*utf8Source & 0x0F) << 12) | ((*(utf8Source + 1) & 0x3F) << 6) | ((*(utf8Source + 2) & 0x3F));
memcpy(utf16Dest,&utf16Source,sizeof(FF_T_UINT16));
//bobtntfullfat *utf16Dest = (FF_T_UINT16) ((*utf8Source & 0x0F) << 12) | ((*(utf8Source + 1) & 0x3F) << 6) | ((*(utf8Source + 2) & 0x3F));
break;
case 4:
// Convert to UTF-32 and then into UTF-16
if(ulSize < 2) {
return FF_ERR_UNICODE_DEST_TOO_SMALL;
}
ulUtf32char = (FF_T_UINT16) ((*utf8Source & 0x0F) << 18) | ((*(utf8Source + 1) & 0x3F) << 12) | ((*(utf8Source + 2) & 0x3F) << 6) | ((*(utf8Source + 3) & 0x3F));
utf16Source = (FF_T_UINT16) (((ulUtf32char - 0x10000) & 0xFFC00) >> 10) | 0xD800;
memcpy(utf16Dest,&utf16Source,sizeof(FF_T_UINT16));
utf16Source = (FF_T_UINT16) (((ulUtf32char - 0x10000) & 0x003FF) >> 00) | 0xDC00;
memcpy(utf16Dest+1,&utf16Source,sizeof(FF_T_UINT16));
//bobtntfullfat *(utf16Dest + 0) = (FF_T_UINT16) (((ulUtf32char - 0x10000) & 0xFFC00) >> 10) | 0xD800;
//bobtntfullfat *(utf16Dest + 1) = (FF_T_UINT16) (((ulUtf32char - 0x10000) & 0x003FF) >> 00) | 0xDC00;
break;
default:
break;
}
return uiSequenceNumber;
}
/*
Returns the number of UTF-8 units required to encode the UTF-16 sequence.
Will not exceed ulSize UTF-8 units. (ulSize * 1 bytes).
*/
FF_T_SINT32 FF_Utf16ctoUtf8c(FF_T_UINT8 *utf8Dest, const FF_T_UINT16 *utf16Source, FF_T_UINT32 ulSize) {
FF_T_UINT32 ulUtf32char;
FF_T_UINT16 ulUtf16char;
if(!ulSize) {
return FF_ERR_UNICODE_DEST_TOO_SMALL;
}
memcpy(&ulUtf16char, utf16Source, sizeof(FF_T_UINT16));
if((/*bobtntfullfat *utf16Source*/ulUtf16char & 0xF800) == 0xD800) { // A surrogate sequence was encountered. Must transform to UTF32 first.
ulUtf32char = ((FF_T_UINT32) (ulUtf16char & 0x003FF) << 10) + 0x10000;
//bobtntfullfat ulUtf32char = ((FF_T_UINT32) (*(utf16Source + 0) & 0x003FF) << 10) + 0x10000;
memcpy(&ulUtf16char, utf16Source + 1, sizeof(FF_T_UINT16));
if((/*bobtntfullfat *(utf16Source + 1)*/ulUtf16char & 0xFC00) != 0xDC00) {
return FF_ERR_UNICODE_INVALID_SEQUENCE; // Invalid UTF-16 sequence.
}
ulUtf32char |= ((FF_T_UINT32) (/*bobtntfullfat *(utf16Source + 1)*/ulUtf16char & 0x003FF));
} else {
ulUtf32char = (FF_T_UINT32) /*bobtntfullfat *utf16Source*/ulUtf16char;
}
// Now convert to the UTF-8 sequence.
if(ulUtf32char < 0x00000080) { // Single byte UTF-8 sequence.
*(utf8Dest + 0) = (FF_T_UINT8) ulUtf32char;
return 1;
}
if(ulUtf32char < 0x00000800) { // Double byte UTF-8 sequence.
if(ulSize < 2) {
return FF_ERR_UNICODE_DEST_TOO_SMALL;
}
*(utf8Dest + 0) = (FF_T_UINT8) (0xC0 | ((ulUtf32char >> 6) & 0x1F));
*(utf8Dest + 1) = (FF_T_UINT8) (0x80 | ((ulUtf32char >> 0) & 0x3F));
return 2;
}
if(ulUtf32char < 0x00010000) { // Triple byte UTF-8 sequence.
if(ulSize < 3) {
return FF_ERR_UNICODE_DEST_TOO_SMALL;
}
*(utf8Dest + 0) = (FF_T_UINT8) (0xE0 | ((ulUtf32char >> 12) & 0x0F));
*(utf8Dest + 1) = (FF_T_UINT8) (0x80 | ((ulUtf32char >> 6 ) & 0x3F));
*(utf8Dest + 2) = (FF_T_UINT8) (0x80 | ((ulUtf32char >> 0 ) & 0x3F));
return 3;
}
if(ulUtf32char < 0x00200000) { // Quadruple byte UTF-8 sequence.
if(ulSize < 4) {
return FF_ERR_UNICODE_DEST_TOO_SMALL;
}
*(utf8Dest + 0) = (FF_T_UINT8) (0xF0 | ((ulUtf32char >> 18) & 0x07));
*(utf8Dest + 1) = (FF_T_UINT8) (0x80 | ((ulUtf32char >> 12) & 0x3F));
*(utf8Dest + 2) = (FF_T_UINT8) (0x80 | ((ulUtf32char >> 6 ) & 0x3F));
*(utf8Dest + 3) = (FF_T_UINT8) (0x80 | ((ulUtf32char >> 0 ) & 0x3F));
return 4;
}
return FF_ERR_UNICODE_INVALID_CODE; // Invalid Charachter
}
// UTF-16 Support Functions
// Converts a UTF-32 Charachter into its equivalent UTF-16 sequence.
FF_T_SINT32 FF_Utf32ctoUtf16c(FF_T_UINT16 *utf16Dest, FF_T_UINT32 utf32char, FF_T_UINT32 ulSize) {
// Check that its a valid UTF-32 wide-char!
if(utf32char >= 0xD800 && utf32char <= 0xDFFF) { // This range is not a valid Unicode code point.
return FF_ERR_UNICODE_INVALID_CODE; // Invalid charachter.
}
if(utf32char < 0x10000) {
*utf16Dest = (FF_T_UINT16) utf32char; // Simple conversion! Char comes within UTF-16 space (without surrogates).
return 1;
}
if(ulSize < 2) {
return FF_ERR_UNICODE_DEST_TOO_SMALL; // Not enough UTF-16 units to record this charachter.
}
if(utf32char < 0x00200000) {
// Conversion to a UTF-16 Surrogate pair!
//valueImage = utf32char - 0x10000;
*(utf16Dest + 0) = (FF_T_UINT16) (((utf32char - 0x10000) & 0xFFC00) >> 10) | 0xD800;
*(utf16Dest + 1) = (FF_T_UINT16) (((utf32char - 0x10000) & 0x003FF) >> 00) | 0xDC00;
return 2; // Surrogate pair encoded value.
}
return FF_ERR_UNICODE_INVALID_CODE; // Invalid Charachter
}
// Converts a UTF-16 sequence into its equivalent UTF-32 code point.
FF_T_SINT32 FF_Utf16ctoUtf32c(FF_T_UINT32 *utf32Dest, const FF_T_UINT16 *utf16Source) {
if((*utf16Source & 0xFC00) != 0xD800) { // Not a surrogate sequence.
*utf32Dest = (FF_T_UINT32) *utf16Source;
return 1; // A single UTF-16 item was used to represent the charachter.
}
*utf32Dest = ((FF_T_UINT32) (*(utf16Source + 0) & 0x003FF) << 10) + 0x10000;
if((*(utf16Source + 1) & 0xFC00) != 0xDC00) {
return FF_ERR_UNICODE_INVALID_SEQUENCE; // Invalid UTF-16 sequence.
}
*utf32Dest |= ((FF_T_UINT32) (*(utf16Source + 1) & 0x003FF));
return 2; // 2 utf-16 units make up the Unicode code-point.
}
/*
Returns the total number of UTF-16 items required to represent
the provided UTF-32 string in UTF-16 form.
*/
/*
FF_T_UINT FF_Utf32GetUtf16Len(const FF_T_UINT32 *utf32String) {
FF_T_UINT utf16len = 0;
while(*utf32String) {
if(*utf32String++ <= 0xFFFF) {
utf16len++;
} else {
utf16len += 2;
}
}
return utf16len;
}*/
// String conversions
FF_T_SINT32 FF_Utf32stoUtf8s(FF_T_UINT8 *Utf8String, FF_T_UINT32 *Utf32String) {
int i = 0,y = 0;
FF_T_UINT16 utf16buffer[2];
while(Utf32String[i]) {
// Convert to a UTF16 char.
FF_Utf32ctoUtf16c(utf16buffer, Utf32String[i], 2);
// Now convert the UTF16 to UTF8 sequence.
y += FF_Utf16ctoUtf8c(&Utf8String[y], utf16buffer, 4);
i++;
}
Utf8String[y] = '\0';
return 0;
}

View file

@ -46,6 +46,7 @@ LdrVerifyMappedImageMatchesChecksum(
IN ULONG ImageSize, IN ULONG ImageSize,
IN ULONG FileLength) IN ULONG FileLength)
{ {
#if 0
PIMAGE_NT_HEADERS Header; PIMAGE_NT_HEADERS Header;
PUSHORT Ptr; PUSHORT Ptr;
ULONG Sum; ULONG Sum;
@ -118,6 +119,9 @@ LdrVerifyMappedImageMatchesChecksum(
DPRINT1("Image %p checksum mismatches! 0x%x != 0x%x, ImageSize %x, FileLen %x\n", BaseAddress, CalcSum, HeaderSum, ImageSize, FileLength); DPRINT1("Image %p checksum mismatches! 0x%x != 0x%x, ImageSize %x, FileLen %x\n", BaseAddress, CalcSum, HeaderSum, ImageSize, FileLength);
return (BOOLEAN)(CalcSum == HeaderSum); return (BOOLEAN)(CalcSum == HeaderSum);
#else
return TRUE;
#endif
} }
/* /*

View file

@ -340,6 +340,9 @@ KiDeliverApc(IN KPROCESSOR_MODE DeliveryMode,
break; break;
} }
/* Kernel APC is not pending anymore */
Thread->ApcState.KernelApcPending = FALSE;
/* Get the next Entry */ /* Get the next Entry */
ApcListEntry = Thread->ApcState.ApcListHead[KernelMode].Flink; ApcListEntry = Thread->ApcState.ApcListHead[KernelMode].Flink;
Apc = CONTAINING_RECORD(ApcListEntry, KAPC, ApcListEntry); Apc = CONTAINING_RECORD(ApcListEntry, KAPC, ApcListEntry);

View file

@ -1059,7 +1059,7 @@ MiResolveImageReferences(IN PVOID ImageBase,
{ {
/* It's not, it's importing stuff it shouldn't be! */ /* It's not, it's importing stuff it shouldn't be! */
MiDereferenceImports(LoadedImports); MiDereferenceImports(LoadedImports);
if (LoadedImports) ExFreePool(LoadedImports); if (LoadedImports) ExFreePoolWithTag(LoadedImports, 'TDmM');
return STATUS_PROCEDURE_NOT_FOUND; return STATUS_PROCEDURE_NOT_FOUND;
} }
@ -1073,7 +1073,7 @@ MiResolveImageReferences(IN PVOID ImageBase,
{ {
/* This is not kernel code */ /* This is not kernel code */
MiDereferenceImports(LoadedImports); MiDereferenceImports(LoadedImports);
if (LoadedImports) ExFreePool(LoadedImports); if (LoadedImports) ExFreePoolWithTag(LoadedImports, 'TDmM');
return STATUS_PROCEDURE_NOT_FOUND; return STATUS_PROCEDURE_NOT_FOUND;
} }
@ -1098,7 +1098,7 @@ MiResolveImageReferences(IN PVOID ImageBase,
{ {
/* Failed */ /* Failed */
MiDereferenceImports(LoadedImports); MiDereferenceImports(LoadedImports);
if (LoadedImports) ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR); if (LoadedImports) ExFreePoolWithTag(LoadedImports, 'TDmM');
return Status; return Status;
} }
@ -1219,7 +1219,7 @@ CheckDllState:
/* Cleanup and return */ /* Cleanup and return */
RtlFreeUnicodeString(&NameString); RtlFreeUnicodeString(&NameString);
MiDereferenceImports(LoadedImports); MiDereferenceImports(LoadedImports);
if (LoadedImports) ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR); if (LoadedImports) ExFreePoolWithTag(LoadedImports, 'TDmM');
return Status; return Status;
} }
@ -1252,7 +1252,7 @@ CheckDllState:
{ {
/* Cleanup and return */ /* Cleanup and return */
MiDereferenceImports(LoadedImports); MiDereferenceImports(LoadedImports);
if (LoadedImports) ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR); if (LoadedImports) ExFreePoolWithTag(LoadedImports, 'TDmM');
DPRINT1("Warning: Driver failed to load, %S not found\n", *MissingDriver); DPRINT1("Warning: Driver failed to load, %S not found\n", *MissingDriver);
return STATUS_DRIVER_ENTRYPOINT_NOT_FOUND; return STATUS_DRIVER_ENTRYPOINT_NOT_FOUND;
} }
@ -1282,7 +1282,7 @@ CheckDllState:
{ {
/* Cleanup and return */ /* Cleanup and return */
MiDereferenceImports(LoadedImports); MiDereferenceImports(LoadedImports);
if (LoadedImports) ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR); if (LoadedImports) ExFreePoolWithTag(LoadedImports, 'TDmM');
return Status; return Status;
} }
@ -1315,13 +1315,13 @@ CheckDllState:
if (!ImportCount) if (!ImportCount)
{ {
/* Free the list and set it to no imports */ /* Free the list and set it to no imports */
ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR); ExFreePoolWithTag(LoadedImports, 'TDmM');
LoadedImports = MM_SYSLDR_NO_IMPORTS; LoadedImports = MM_SYSLDR_NO_IMPORTS;
} }
else if (ImportCount == 1) else if (ImportCount == 1)
{ {
/* Just one entry, we can free the table and only use our entry */ /* Just one entry, we can free the table and only use our entry */
ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR); ExFreePoolWithTag(LoadedImports, 'TDmM');
LoadedImports = (PLOAD_IMPORTS)ImportEntry; LoadedImports = (PLOAD_IMPORTS)ImportEntry;
} }
else if (ImportCount != LoadedImports->Count) else if (ImportCount != LoadedImports->Count)
@ -1349,7 +1349,7 @@ CheckDllState:
} }
/* Free the old copy */ /* Free the old copy */
ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR); ExFreePoolWithTag(LoadedImports, 'TDmM');
LoadedImports = NewImports; LoadedImports = NewImports;
} }
} }
@ -3004,7 +3004,7 @@ Quickie:
/* if (NamePrefix) ExFreePool(PrefixName.Buffer); */ /* if (NamePrefix) ExFreePool(PrefixName.Buffer); */
/* Free the name buffer and return status */ /* Free the name buffer and return status */
ExFreePoolWithTag(Buffer, TAG_LDR_WSTR); ExFreePoolWithTag(Buffer, 'nLmM');
return Status; return Status;
} }

View file

@ -4326,14 +4326,11 @@ MmUnmapViewOfSection(PEPROCESS Process,
* and calculate the image base address */ * and calculate the image base address */
for (i = 0; i < NrSegments; i++) for (i = 0; i < NrSegments; i++)
{ {
if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) if (Segment == &SectionSegments[i])
{ {
if (Segment == &SectionSegments[i]) ImageBaseAddress = (char*)BaseAddress - (ULONG_PTR)SectionSegments[i].VirtualAddress;
{ break;
ImageBaseAddress = (char*)BaseAddress - (ULONG_PTR)SectionSegments[i].VirtualAddress; }
break;
}
}
} }
if (i >= NrSegments) if (i >= NrSegments)
{ {
@ -4342,13 +4339,10 @@ MmUnmapViewOfSection(PEPROCESS Process,
for (i = 0; i < NrSegments; i++) for (i = 0; i < NrSegments; i++)
{ {
if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) PVOID SBaseAddress = (PVOID)
{ ((char*)ImageBaseAddress + (ULONG_PTR)SectionSegments[i].VirtualAddress);
PVOID SBaseAddress = (PVOID)
((char*)ImageBaseAddress + (ULONG_PTR)SectionSegments[i].VirtualAddress);
Status = MmUnmapViewOfSegment(AddressSpace, SBaseAddress); Status = MmUnmapViewOfSegment(AddressSpace, SBaseAddress);
}
} }
} }
else else
@ -4571,6 +4565,7 @@ MmMapViewOfSection(IN PVOID SectionObject,
PMMSUPPORT AddressSpace; PMMSUPPORT AddressSpace;
ULONG ViewOffset; ULONG ViewOffset;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
BOOLEAN NotAtBase = FALSE;
if ((ULONG_PTR)SectionObject & 1) if ((ULONG_PTR)SectionObject & 1)
{ {
@ -4624,13 +4619,10 @@ MmMapViewOfSection(IN PVOID SectionObject,
ImageSize = 0; ImageSize = 0;
for (i = 0; i < NrSegments; i++) for (i = 0; i < NrSegments; i++)
{ {
if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) ULONG_PTR MaxExtent;
{ MaxExtent = (ULONG_PTR)SectionSegments[i].VirtualAddress +
ULONG_PTR MaxExtent; SectionSegments[i].Length;
MaxExtent = (ULONG_PTR)SectionSegments[i].VirtualAddress + ImageSize = max(ImageSize, MaxExtent);
SectionSegments[i].Length;
ImageSize = max(ImageSize, MaxExtent);
}
} }
ImageSectionObject->ImageSize = ImageSize; ImageSectionObject->ImageSize = ImageSize;
@ -4652,33 +4644,33 @@ MmMapViewOfSection(IN PVOID SectionObject,
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
return(STATUS_UNSUCCESSFUL); return(STATUS_UNSUCCESSFUL);
} }
/* Remember that we loaded image at a different base address */
NotAtBase = TRUE;
} }
for (i = 0; i < NrSegments; i++) for (i = 0; i < NrSegments; i++)
{ {
if (!(SectionSegments[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD)) PVOID SBaseAddress = (PVOID)
{ ((char*)ImageBase + (ULONG_PTR)SectionSegments[i].VirtualAddress);
PVOID SBaseAddress = (PVOID) MmLockSectionSegment(&SectionSegments[i]);
((char*)ImageBase + (ULONG_PTR)SectionSegments[i].VirtualAddress); Status = MmMapViewOfSegment(AddressSpace,
MmLockSectionSegment(&SectionSegments[i]); Section,
Status = MmMapViewOfSegment(AddressSpace, &SectionSegments[i],
Section, &SBaseAddress,
&SectionSegments[i], SectionSegments[i].Length,
&SBaseAddress, SectionSegments[i].Protection,
SectionSegments[i].Length, 0,
SectionSegments[i].Protection, 0);
0, MmUnlockSectionSegment(&SectionSegments[i]);
0); if (!NT_SUCCESS(Status))
MmUnlockSectionSegment(&SectionSegments[i]); {
if (!NT_SUCCESS(Status)) MmUnlockAddressSpace(AddressSpace);
{ return(Status);
MmUnlockAddressSpace(AddressSpace); }
return(Status);
}
}
} }
*BaseAddress = (PVOID)ImageBase; *BaseAddress = (PVOID)ImageBase;
*ViewSize = ImageSize;
} }
else else
{ {
@ -4756,7 +4748,12 @@ MmMapViewOfSection(IN PVOID SectionObject,
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
return(STATUS_SUCCESS); if (NotAtBase)
Status = STATUS_IMAGE_NOT_AT_BASE;
else
Status = STATUS_SUCCESS;
return Status;
} }
/* /*

View file

@ -90,7 +90,7 @@ EngpRegisterGraphicsDevice(
pustrDeviceName->Length); pustrDeviceName->Length);
/* Create a win device name (FIXME: virtual devices!) */ /* Create a win device name (FIXME: virtual devices!) */
swprintf(pGraphicsDevice->szWinDeviceName, L"\\\\.\\VIDEO%d", (int)giDevNum); swprintf(pGraphicsDevice->szWinDeviceName, L"\\\\.\\DISPLAY%d", (int)giDevNum);
/* Allocate a buffer for the strings */ /* Allocate a buffer for the strings */
cj = pustrDiplayDrivers->Length + pustrDescription->Length + sizeof(WCHAR); cj = pustrDiplayDrivers->Length + pustrDescription->Length + sizeof(WCHAR);

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