* 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
*
* updated by Caemyr - Olaf Siejka (Jan, 2008)
* updated by Saibamen - Adam Stachowicz (Mar, 2011)
*/
LANGUAGE LANG_POLISH, SUBLANG_DEFAULT
@ -46,7 +47,7 @@ BEGIN
POPUP "Pomoc"
BEGIN
MENUITEM "Pomoc", ID_HELP
MENUITEM "Servman - informacje", ID_ABOUT
MENUITEM "O programie", ID_ABOUT
END
END
@ -72,11 +73,11 @@ BEGIN
END
IDD_ABOUTBOX DIALOGEX 22,16,190,182
CAPTION "Service Manager - informacje"
CAPTION "Mened¿er Us³ug - informacje"
FONT 8, "MS Shell Dlg",0,0
STYLE DS_SHELLFONT | WS_BORDER | WS_DLGFRAME | WS_SYSMENU | DS_MODALFRAME
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
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
@ -198,8 +199,8 @@ END
STRINGTABLE DISCARDABLE
BEGIN
IDS_NUM_SERVICES "Numer usługi: %d"
IDS_STOP_DEPENDS "When %s stops, these other services will also stop"
IDS_NO_DEPENDS "<No Dependencies>"
IDS_STOP_DEPENDS "Kiedy %s siê zatrzyma, inne us³ugi równie¿ siê zatrzymaj¹"
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."
END

View file

@ -59,7 +59,6 @@ typedef struct _ICMP_ECHO_PACKET
#pragma pack(1)
BOOL InvalidOption;
BOOL NeverStop;
BOOL ResolveAddresses;
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 */
static BOOL ParseCmdline(int argc, LPWSTR argv[])
{
INT i;
BOOL ShowUsage;
BOOL FoundTarget;
BOOL FoundTarget = FALSE, InvalidOption = FALSE;
if (argc < 2)
ShowUsage = TRUE;
else
ShowUsage = FALSE;
FoundTarget = FALSE;
InvalidOption = FALSE;
{
Usage();
return FALSE;
}
for (i = 1; i < argc; i++)
{
if (argv[i][0] == L'-')
if (argv[i][0] == L'-' || argv[i][0] == L'/')
{
switch (argv[i][1])
{
case L't': NeverStop = 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':
DataSize = GetULONG2(&argv[i][2], argv[i + 1], &i);
if (DataSize > ICMP_MAXSIZE - sizeof(ICMP_ECHO_PACKET) - sizeof(IPv4_HEADER))
if (i + 1 < argc)
{
FormatOutput(IDS_BAD_VALUE_OPTION_L, ICMP_MAXSIZE - \
(int)sizeof(ICMP_ECHO_PACKET) - \
(int)sizeof(IPv4_HEADER));
return FALSE;
}
DataSize = wcstoul(argv[++i], NULL, 0);
if (DataSize > ICMP_MAXSIZE - sizeof(ICMP_ECHO_PACKET) - sizeof(IPv4_HEADER))
{
FormatOutput(IDS_BAD_VALUE_OPTION_L, ICMP_MAXSIZE - \
(int)sizeof(ICMP_ECHO_PACKET) - \
(int)sizeof(IPv4_HEADER));
return FALSE;
}
} else
InvalidOption = TRUE;
break;
case L'f': DontFragment = TRUE; break;
case L'i': TTLValue = GetULONG2(&argv[i][2], argv[i + 1], &i); break;
case L'v': TOSValue = GetULONG2(&argv[i][2], argv[i + 1], &i); break;
case L'w': Timeout = GetULONG2(&argv[i][2], argv[i + 1], &i); break;
case L'i':
if (i + 1 < argc)
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:
FormatOutput(IDS_BAD_OPTION, argv[i]);
Usage();
return FALSE;
}
if (InvalidOption)
@ -314,17 +300,12 @@ static BOOL ParseCmdline(int argc, LPWSTR argv[])
}
}
if ((!ShowUsage) && (!FoundTarget))
if (!FoundTarget)
{
FormatOutput(IDS_DEST_MUST_BE_SPECIFIED);
return FALSE;
}
if (ShowUsage)
{
Usage();
return FALSE;
}
return TRUE;
}

View file

@ -4,7 +4,7 @@
Name = Microsoft Visual Basic 6.0 Common Controls
Version = 6.0
Licence = Unknown
Description = File needed by some applications.
Description = File needed by some applications. Contains: comctl32.ocx, mscomctl.ocx, advpack.dll.
Size = 914kB
Category = 14
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]
Name = Mozilla Firefox 3.6
Version = 3.6.15
Version = 3.6.16
Licence = MPL/GPL/LGPL
Description = The most popular and one of the best free Web Browsers out there.
Size = 8.2M
Category = 5
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
[Section.0407]
Description = Der populärste und einer der besten freien Webbrowser.
Size = 8.1M
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]
Description = El más popular y uno de los mejores navegadores web gratuitos que hay.
Size = 8.1M
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]
Description = Le navigateur web gratuit le plus populaire et l'un des meilleurs.
Size = 8.1M
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]
Description = Mest populære og best også gratis nettleserene der ute.
Size = 8.1M
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]
Description = Najpopularniejsza i jedna z najlepszych darmowych przeglądarek internetowych.
Size = 8.9M
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]
Description = Один из самых популярных и лучших бесплатных браузеров.
Size = 8.5M
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]
Description = Найпопулярніший та один з кращих безплатних веб-браузерів.
Size = 8.5M
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]
Name = LibreOffice
Version = 3.3.1
Version = 3.3.2
Licence = LGPL
Description = Former called OpenOffice. Open Source Office Suite.
Size = 213.4MB
Size = 214.0MB
Category = 6
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
[Section.0407]

View file

@ -4,7 +4,7 @@
Name = OLE Viewer and Microsoft Foundation Classes version 4
Version = 4.0
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
Category = 14
URLSite = http://support.microsoft.com/kb/122244/

View file

@ -2,13 +2,13 @@
[Section]
Name = Miranda IM
Version = 0.9.17
Version = 0.9.18
Licence = GPL
Description = Open source multiprotocol instant messaging application - May not work completely.
Size = 3.0MB
Category = 5
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
[Section.0407]

View file

@ -4,11 +4,11 @@
Name = Microsoft XML 3
Version = 3.0
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
Category = 14
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
[Section.0407]

View file

@ -2,13 +2,13 @@
[Section]
Name = SciTE
Version = 2.24
Version = 2.25
Licence = Freeware
Description = SciTE is a SCIntilla based Text Editor. Originally built to demonstrate Scintilla, it has grown to be a generally useful editor with facilities for building and running programs.
Size = 0.6M
Category = 7
URLSite = http://www.scintilla.org/
URLDownload = http://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
[Section.0407]

View file

@ -2,36 +2,36 @@
[Section]
Name = Mozilla SeaMonkey
Version = 2.0.12
Version = 2.0.13
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.
Size = 10.2MB
Category = 5
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
[Section.0407]
Description = Mozilla Suite lebt. Dies ist das einzige Browser-, Mail-, Chat- and Composerwerkzeug-Bundle welches Sie benötigen.
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]
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
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]
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
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]
Description = Pakiet Mozilla żyje. W zestawie: przeglądarka, klient poczty, IRC oraz Edytor HTML - wszystko, czego potrzebujesz.
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]
Description = Продолжение Mozilla Suite. Включает браузер, почтовый клиент, IRC-клиент и HTML-редактор.
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
Version = 1.0
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
Category = 14
URLSite = http://support.microsoft.com/

View file

@ -4,7 +4,7 @@
Name = Visual Basic 5 Runtime
Version = 5.0
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
Category = 14
URLSite = http://support.microsoft.com/kb/180071/

View file

@ -4,7 +4,7 @@
Name = Visual Basic 6 Runtime
Version = 6.0
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
Category = 14
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
Version = 7.1
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
Category = 14
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
Version = 8.0
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
Category = 14
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
Version = 6.0
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
Category = 14
URLSite = http://support.microsoft.com/kb/259403/

View file

@ -2,13 +2,13 @@
[Section]
Name = VLC media player
Version = 1.1.7
Version = 1.1.8
Licence = GPL
Description = A media player.
Size = 19.4MB
Size = 19.6MB
Category = 1
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
[Section.0407]

View file

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

View file

@ -680,10 +680,10 @@ FormatTime(TCHAR *lpTime, LPSYSTEMTIME dt)
{
case 0: /* 12 hour format */
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)),
cTimeSeparator,
dt->wMinute, (dt->wHour <= 11 ? _T('a') : _T('p')));
dt->wMinute, (dt->wHour <= 11 ? _T('A') : _T('P')));
break;
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_DESKTOP "Pulpit"
IDS_TASKBAR "Pasek zadañ"
IDS_NAMECOLUMN "Name"
IDS_PATHCOLUMN "Path"
IDS_NAMECOLUMN "Nazwa"
IDS_PATHCOLUMN "Ścieżka"
IDS_MENUCOLUMN "Menu path"
END

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -15,9 +15,6 @@
/* GLOBALS *******************************************************************/
#define LDR_LOCK_HELD 0x2
#define LDR_LOCK_FREE 0x1
LONG LdrpLoaderLockAcquisitonCount;
/* FUNCTIONS *****************************************************************/
@ -38,7 +35,7 @@ LdrUnlockLoaderLock(IN ULONG Flags,
if (Flags & ~1)
{
/* 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 */
RtlRaiseStatus(STATUS_INVALID_PARAMETER_1);
@ -60,7 +57,7 @@ LdrUnlockLoaderLock(IN ULONG Flags,
DPRINT1("LdrUnlockLoaderLock() called with an invalid cookie!\n");
/* 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 */
RtlRaiseStatus(STATUS_INVALID_PARAMETER_2);
@ -73,7 +70,7 @@ LdrUnlockLoaderLock(IN ULONG Flags,
}
/* 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 */
RtlLeaveCriticalSection(&LdrpLoaderLock);
@ -118,11 +115,11 @@ LdrLockLoaderLock(IN ULONG Flags,
if (Cookie) *Cookie = 0;
/* 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))
{
/* 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 */
RtlRaiseStatus(STATUS_INVALID_PARAMETER_1);
@ -136,7 +133,7 @@ LdrLockLoaderLock(IN ULONG Flags,
if (!Cookie)
{
/* 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 */
RtlRaiseStatus(STATUS_INVALID_PARAMETER_3);
@ -150,7 +147,7 @@ LdrLockLoaderLock(IN ULONG Flags,
if ((Flags & LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY) && !(Result))
{
/* 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 */
RtlRaiseStatus(STATUS_INVALID_PARAMETER_2);
@ -164,7 +161,7 @@ LdrLockLoaderLock(IN ULONG Flags,
if (InInit) return STATUS_SUCCESS;
/* 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 */
if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY)
@ -173,13 +170,13 @@ LdrLockLoaderLock(IN ULONG Flags,
if (!RtlTryEnterCriticalSection(&LdrpLoaderLock))
{
/* It's locked */
*Result = LDR_LOCK_HELD;
*Result = LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_NOT_ACQUIRED;
goto Quickie;
}
else
{
/* It worked */
*Result = LDR_LOCK_FREE;
*Result = LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_ACQUIRED;
}
}
else
@ -188,7 +185,7 @@ LdrLockLoaderLock(IN ULONG Flags,
RtlEnterCriticalSection(&LdrpLoaderLock);
/* 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 */
@ -209,13 +206,13 @@ LdrLockLoaderLock(IN ULONG Flags,
if (!RtlTryEnterCriticalSection(&LdrpLoaderLock))
{
/* It's locked */
*Result = LDR_LOCK_HELD;
*Result = LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_NOT_ACQUIRED;
_SEH2_YIELD(return STATUS_SUCCESS);
}
else
{
/* It worked */
*Result = LDR_LOCK_FREE;
*Result = LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_ACQUIRED;
}
}
else
@ -224,7 +221,7 @@ LdrLockLoaderLock(IN ULONG Flags,
RtlEnterCriticalSection(&LdrpLoaderLock);
/* 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 */
@ -530,4 +527,66 @@ LdrQueryProcessModuleInformation(IN PRTL_PROCESS_MODULES ModuleInformation,
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 */

View file

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

View file

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

View file

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

View file

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

View file

@ -275,7 +275,7 @@ HGDIOBJ
FASTCALL
hGetPEBHandle(HANDLECACHETYPE Type, COLORREF cr)
{
int Number;
int Number, Offset, MaxNum, GdiType;
HANDLE Lock;
HGDIOBJ Handle = NULL;
@ -287,26 +287,58 @@ hGetPEBHandle(HANDLECACHETYPE Type, COLORREF cr)
Number = GdiHandleCache->ulNumHandles[Type];
if ( Number && Number <= CACHE_REGION_ENTRIES )
if (Type == hctBrushHandle)
{
if ( Type == hctRegionHandle)
{
PRGN_ATTR pRgn_Attr;
HGDIOBJ *hPtr;
hPtr = GdiHandleCache->Handle + CACHE_BRUSH_ENTRIES+CACHE_PEN_ENTRIES;
Handle = hPtr[Number - 1];
Offset = 0;
MaxNum = CACHE_BRUSH_ENTRIES;
GdiType = GDILoObjType_LO_BRUSH_TYPE;
}
else if (Type == hctPenHandle)
{
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 (pRgn_Attr->AttrFlags & ATTR_CACHED)
if ( Number && Number <= MaxNum )
{
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);
pRgn_Attr->AttrFlags &= ~ATTR_CACHED;
hPtr[Number - 1] = NULL;
GdiHandleCache->ulNumHandles[Type]--;
pBrush_Attr->lbColor = cr ;
pBrush_Attr->AttrFlags |= ATTR_NEW_COLOR;
}
}
}
}
}
}
else
{
Handle = NULL;
}
}
(void)InterlockedExchangePointer((PVOID*)&GdiHandleCache->ulLock, Lock);
return Handle;

View file

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

View file

@ -23,12 +23,34 @@ CreatePen(
int nWidth,
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_NULL) return GetStockObject(NULL_PEN);
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);
}

View file

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

View file

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

View file

@ -91,9 +91,11 @@ extern HANDLE hProcessHeap;
extern HANDLE hBaseDir;
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;
@ -211,6 +213,12 @@ BasepMapFile(IN LPCWSTR lpApplicationName,
OUT PHANDLE hSection,
IN PUNICODE_STRING ApplicationName);
LPWSTR
WINAPI
BasepGetDllPath(LPWSTR FullPath,
PVOID Environment);
PCODEPAGE_ENTRY FASTCALL
IntGetCodePageEntry(UINT CodePage);

View file

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

View file

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

View file

@ -1,10 +1,10 @@
/* $Id$
*
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT : ReactOS user mode libraries
* MODULE : kernel32.dll
* FILE : reactos/lib/kernel32/misc/ldr.c
* AUTHOR : Ariadne
* FILE : reactos/dll/win32/kernel32/misc/ldr.c
* AUTHOR : Aleksey Bragin <aleksey@reactos.org>
* Ariadne
*/
#include <k32.h>
@ -22,8 +22,68 @@ typedef struct tagLOADPARMS32 {
extern BOOLEAN InWindows;
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 ****************************************************************/
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
*
@ -220,7 +280,7 @@ LoadLibraryExW (
HINSTANCE hInst;
NTSTATUS Status;
PWSTR SearchPath;
ULONG DllCharacteristics;
ULONG DllCharacteristics = 0;
BOOL FreeString = FALSE;
(void)hFile;
@ -349,27 +409,49 @@ GetProcAddress( HMODULE hModule, LPCSTR lpProcName )
BOOL WINAPI FreeLibrary(HINSTANCE hLibModule)
{
NTSTATUS Status;
PIMAGE_NT_HEADERS NtHeaders;
if (!hLibModule)
if (LDR_IS_DATAFILE(hLibModule))
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
// FIXME: This SEH should go inside RtlImageNtHeader instead
_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)
{
/* this is a LOAD_LIBRARY_AS_DATAFILE module */
char *ptr = (char *)hLibModule - 1;
return UnmapViewOfFile(ptr);
}
Status = LdrUnloadDll(hLibModule);
/* Check what kind of status we got */
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
/* Set last error */
BaseSetLastNTError(Status);
/* Return failure */
return FALSE;
}
/* Return success */
return TRUE;
}
@ -379,12 +461,30 @@ BOOL WINAPI FreeLibrary(HINSTANCE hLibModule)
*/
VOID
WINAPI
FreeLibraryAndExitThread (
HMODULE hLibModule,
DWORD dwExitCode
)
FreeLibraryAndExitThread(HMODULE hLibModule,
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);
}
@ -394,123 +494,292 @@ FreeLibraryAndExitThread (
*/
DWORD
WINAPI
GetModuleFileNameA (
HINSTANCE hModule,
LPSTR lpFilename,
DWORD nSize
)
GetModuleFileNameA(HINSTANCE hModule,
LPSTR lpFilename,
DWORD nSize)
{
ANSI_STRING FileName;
PLIST_ENTRY ModuleListHead;
PLIST_ENTRY Entry;
PLDR_DATA_TABLE_ENTRY Module;
PPEB Peb;
ULONG Length = 0;
UNICODE_STRING FilenameW;
ANSI_STRING FilenameA;
NTSTATUS Status;
DWORD Length = 0, LengthToCopy;
Peb = NtCurrentPeb ();
RtlEnterCriticalSection (Peb->LoaderLock);
/* Allocate a unicode buffer */
FilenameW.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, nSize * sizeof(WCHAR));
if (!FilenameW.Buffer)
{
BaseSetLastNTError(STATUS_NO_MEMORY);
return 0;
}
if (hModule == NULL)
hModule = Peb->ImageBaseAddress;
/* Call unicode API */
FilenameW.Length = GetModuleFileNameW(hModule, FilenameW.Buffer, nSize) * sizeof(WCHAR);
FilenameW.MaximumLength = FilenameW.Length + sizeof(WCHAR);
ModuleListHead = &Peb->Ldr->InLoadOrderModuleList;
Entry = ModuleListHead->Flink;
if (FilenameW.Length)
{
/* 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)
{
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;
/* Calculate size to copy */
Length = min(nSize, FilenameA.Length);
/* convert unicode string to ansi (or oem) */
if (bIsFileApiAnsi)
RtlUnicodeStringToAnsiString (&FileName,
&Module->FullDllName,
FALSE);
else
RtlUnicodeStringToOemString (&FileName,
&Module->FullDllName,
FALSE);
/* Include terminating zero */
if (nSize > Length)
LengthToCopy = Length + 1;
else
LengthToCopy = nSize;
if (Length < nSize)
lpFilename[Length] = '\0';
else
SetLastErrorByStatus (STATUS_BUFFER_TOO_SMALL);
/* Now copy back to the caller amount he asked */
RtlMoveMemory(lpFilename, FilenameA.Buffer, LengthToCopy);
RtlLeaveCriticalSection (Peb->LoaderLock);
return Length;
}
/* Free ansi filename */
RtlFreeAnsiString(&FilenameA);
}
Entry = Entry->Flink;
}
/* Free unicode filename */
RtlFreeHeap(RtlGetProcessHeap(), 0, FilenameW.Buffer);
SetLastErrorByStatus (STATUS_DLL_NOT_FOUND);
RtlLeaveCriticalSection (Peb->LoaderLock);
return 0;
/* Return length copied */
return Length;
}
/*
* @implemented
*/
DWORD
WINAPI
GetModuleFileNameW (
HINSTANCE hModule,
LPWSTR lpFilename,
DWORD nSize
)
GetModuleFileNameW(HINSTANCE hModule,
LPWSTR lpFilename,
DWORD nSize)
{
UNICODE_STRING FileName;
PLIST_ENTRY ModuleListHead;
PLIST_ENTRY Entry;
PLDR_DATA_TABLE_ENTRY Module;
PPEB Peb;
ULONG Length = 0;
PLIST_ENTRY ModuleListHead, Entry;
PLDR_DATA_TABLE_ENTRY Module;
ULONG Length = 0;
ULONG Cookie;
PPEB Peb;
Peb = NtCurrentPeb ();
RtlEnterCriticalSection (Peb->LoaderLock);
hModule = BasepMapModuleHandle(hModule, FALSE);
if (hModule == NULL)
hModule = Peb->ImageBaseAddress;
/* Upscale nSize from chars to bytes */
nSize *= sizeof(WCHAR);
ModuleListHead = &Peb->Ldr->InLoadOrderModuleList;
Entry = ModuleListHead->Flink;
while (Entry != ModuleListHead)
{
Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
_SEH2_TRY
{
/* We don't use per-thread cur dir now */
//PRTL_PERTHREAD_CURDIR PerThreadCurdir = (PRTL_PERTHREAD_CURDIR)teb->NtTib.SubSystemTib;
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;
Peb = NtCurrentPeb ();
RtlCopyUnicodeString (&FileName,
&Module->FullDllName);
if (Length < nSize)
lpFilename[Length] = L'\0';
else
SetLastErrorByStatus (STATUS_BUFFER_TOO_SMALL);
/* Acquire a loader lock */
LdrLockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, NULL, &Cookie);
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);
RtlLeaveCriticalSection (Peb->LoaderLock);
/* Subtract a terminating zero */
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
WINAPI
GetModuleHandleA ( LPCSTR lpModuleName )
GetModuleHandleW(LPCWSTR lpModuleName)
{
ANSI_STRING ModuleName;
NTSTATUS Status;
PTEB pTeb = NtCurrentTeb();
HMODULE hModule;
NTSTATUS Status;
if (lpModuleName == NULL)
{
return ((HMODULE)pTeb->ProcessEnvironmentBlock->ImageBaseAddress);
}
/* If current module is requested - return it right away */
if (!lpModuleName)
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,
&ModuleName,
FALSE);
/* If it wasn't successful - return 0 */
if (!NT_SUCCESS(Status)) hModule = 0;
if (NT_SUCCESS(Status))
{
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);
/* Return the handle */
return hModule;
}
@ -583,64 +817,31 @@ GetModuleHandleW (LPCWSTR lpModuleName)
BOOL
WINAPI
GetModuleHandleExW(IN DWORD dwFlags,
IN LPCWSTR lpModuleName OPTIONAL,
IN LPCWSTR lpwModuleName OPTIONAL,
OUT HMODULE* phModule)
{
HMODULE hModule;
NTSTATUS Status;
DWORD dwValid;
BOOL Ret = FALSE;
if (phModule == NULL ||
((dwFlags & (GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT)) ==
(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT)))
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
/* Validate parameters */
dwValid = BasepGetModuleHandleExParameterValidation(dwFlags, lpwModuleName, phModule);
if (lpModuleName == NULL)
{
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 result is invalid parameter - return failure */
if (dwValid == BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_ERROR) return FALSE;
if (hModule != NULL)
{
if (!(dwFlags & GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT))
{
Status = LdrAddRefDll((dwFlags & GET_MODULE_HANDLE_EX_FLAG_PIN) ? LDR_PIN_MODULE : 0,
hModule);
/* 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 (NT_SUCCESS(Status))
{
Ret = TRUE;
}
else
{
SetLastErrorByStatus(Status);
hModule = NULL;
}
}
else
Ret = TRUE;
}
/* Use common helper routine */
Status = BasepGetModuleHandleExW(FALSE,
dwFlags,
lpwModuleName,
phModule);
/* Return TRUE in case of success */
if (NT_SUCCESS(Status)) Ret = TRUE;
*phModule = hModule;
return Ret;
}
@ -650,41 +851,52 @@ GetModuleHandleExW(IN DWORD dwFlags,
BOOL
WINAPI
GetModuleHandleExA(IN DWORD dwFlags,
IN LPCSTR lpModuleName OPTIONAL,
IN LPCSTR lpModuleName OPTIONAL,
OUT HMODULE* phModule)
{
ANSI_STRING ModuleName;
LPCWSTR lpModuleNameW;
PUNICODE_STRING lpModuleNameW;
DWORD dwValid;
BOOL Ret = FALSE;
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)
{
lpModuleNameW = (LPCWSTR)lpModuleName;
/* Call the extended version of the API without conversion */
Status = BasepGetModuleHandleExW(FALSE,
dwFlags,
(LPCWSTR)lpModuleName,
phModule);
}
else
{
RtlInitAnsiString(&ModuleName, lpModuleName);
/* Convert module name to unicode */
lpModuleNameW = Basep8BitStringToStaticUnicodeString(lpModuleName);
Status = RtlAnsiStringToUnicodeString(&pTeb->StaticUnicodeString,
&ModuleName,
FALSE);
/* Return FALSE if conversion failed */
if (!lpModuleNameW) return FALSE;
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return FALSE;
}
lpModuleNameW = pTeb->StaticUnicodeString.Buffer;
/* Call the extended version of the API */
Status = BasepGetModuleHandleExW(FALSE,
dwFlags,
lpModuleNameW->Buffer,
phModule);
}
Ret = GetModuleHandleExW(dwFlags,
lpModuleNameW,
phModule);
/* If result was successful - return true */
if (NT_SUCCESS(Status))
Ret = TRUE;
/* Return result */
return Ret;
}

View file

@ -14,6 +14,10 @@
#define NDEBUG
#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 "
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
WINAPI
BasepGetDllPath(LPWSTR FullPath,
PVOID Environment)
{
/* FIXME: Not yet implemented */
return NULL;
#if 0
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

View file

@ -554,7 +554,7 @@ NTSTATUS WINAPI LsarLookupNames(
for (i = 0; i < Count; i++)
{
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;
}
@ -1185,7 +1185,7 @@ NTSTATUS WINAPI LsarLookupNames2(
DWORD Count,
PRPC_UNICODE_STRING Names,
PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
PLSAPR_TRANSLATED_SID_EX TranslatedSids,
PLSAPR_TRANSLATED_SIDS_EX TranslatedSids,
LSAP_LOOKUP_LEVEL LookupLevel,
DWORD *MappedCount,
DWORD LookupOptions,
@ -1287,14 +1287,132 @@ NTSTATUS WINAPI LsarLookupNames3(
DWORD Count,
PRPC_UNICODE_STRING Names,
PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
PLSAPR_TRANSLATED_SID_EX2 TranslatedSids,
PLSAPR_TRANSLATED_SIDS_EX2 TranslatedSids,
LSAP_LOOKUP_LEVEL LookupLevel,
DWORD *MappedCount,
DWORD LookupOptions,
DWORD ClientRevision)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
SID_IDENTIFIER_AUTHORITY IdentifierAuthority = {SECURITY_NT_AUTHORITY};
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,
PRPC_UNICODE_STRING Names,
PLSAPR_REFERENCED_DOMAIN_LIST *ReferencedDomains,
PLSAPR_TRANSLATED_SID_EX2 TranslatedSids,
PLSAPR_TRANSLATED_SIDS_EX2 TranslatedSids,
LSAP_LOOKUP_LEVEL LookupLevel,
DWORD *MappedCount,
DWORD LookupOptions,

View file

@ -223,7 +223,7 @@ BEGIN
LTEXT "", 14011, 68, 93, 160, 10
LTEXT "Utworzony:", 14014, 8, 118, 45, 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
END

View file

@ -584,7 +584,7 @@ BOOL
QueueFile(
FILE_OPERATION_CONTEXT * Context)
{
FILE_ENTRY * from, *to;
FILE_ENTRY * from, *to = NULL;
BOOL bRet = FALSE;
if (Context->Index >= Context->from->dwNumFiles)
@ -593,7 +593,7 @@ QueueFile(
/* get current file */
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];
/* update status */

View file

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

View file

@ -116,6 +116,7 @@ EnumDisplayMonitors(
HMONITOR *hMonitorList;
LPRECT pRectList;
HANDLE hHeap;
BOOL ret = FALSE;
/* get list of monitors/rects */
iCount = NtUserEnumDisplayMonitors(hdc, lprcClip, NULL, NULL, 0);
@ -139,18 +140,15 @@ EnumDisplayMonitors(
pRectList = HeapAlloc(hHeap, 0, sizeof (RECT) * iCount);
if (pRectList == NULL)
{
HeapFree(hHeap, 0, hMonitorList);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
goto cleanup;
}
iCount = NtUserEnumDisplayMonitors(hdc, lprcClip, hMonitorList, pRectList, iCount);
if (iCount <= 0)
{
/* FIXME: SetLastError() */
HeapFree(hHeap, 0, hMonitorList);
HeapFree(hHeap, 0, pRectList);
return FALSE;
goto cleanup;
}
/* enumerate list */
@ -167,11 +165,17 @@ EnumDisplayMonitors(
}
if (!lpfnEnum(hMonitor, hMonitorDC, pMonitorRect, dwData))
break;
goto cleanup; /* return FALSE */
}
HeapFree(hHeap, 0, hMonitorList);
HeapFree(hHeap, 0, pRectList);
return TRUE;
ret = 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,
int nMaxCount)
{
ANSI_STRING ClassName;
int Result;
WCHAR tmpbuf[MAX_ATOM_LEN + 1];
int len;
ClassName.MaximumLength = nMaxCount;
ClassName.Buffer = lpClassName;
Result = NtUserGetClassName(hWnd,
(PUNICODE_STRING)&ClassName,
TRUE);
if (nMaxCount <= 0) return 0;
if (!GetClassNameW( hWnd, tmpbuf, sizeof(tmpbuf)/sizeof(WCHAR) )) return 0;
RtlUnicodeToMultiByteN( lpClassName, nMaxCount - 1, (PULONG)&len, tmpbuf, strlenW(tmpbuf) * sizeof(WCHAR) );
lpClassName[len] = 0;
TRACE("%p class/atom: %s/%04x %x\n", hWnd,
IS_ATOM(lpClassName) ? NULL : lpClassName,
IS_ATOM(lpClassName) ? lpClassName : 0,
nMaxCount);
return Result;
return len;
}
@ -732,8 +730,8 @@ GetClassNameW(
ClassName.Buffer = lpClassName;
Result = NtUserGetClassName(hWnd,
&ClassName,
FALSE);
FALSE,
&ClassName);
TRACE("%p class/atom: %S/%04x %x\n", hWnd,
IS_ATOM(lpClassName) ? NULL : lpClassName,
@ -914,8 +912,11 @@ RealGetWindowClassW(
LPWSTR pszType,
UINT cchType)
{
/* FIXME: Implement correct functionality of RealGetWindowClass */
return GetClassNameW(hwnd,pszType,cchType);
UNICODE_STRING ClassName;
ClassName.MaximumLength = cchType * sizeof(WCHAR);
ClassName.Buffer = (PWSTR)pszType;
return NtUserGetClassName(hwnd,TRUE,&ClassName);
}
@ -929,8 +930,14 @@ RealGetWindowClassA(
LPSTR pszType,
UINT cchType)
{
/* FIXME: Implement correct functionality of RealGetWindowClass */
return GetClassNameA(hwnd,pszType,cchType);
WCHAR tmpbuf[MAX_ATOM_LEN + 1];
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;
BOOL ret = FALSE;
HDC hdc = 0;
static HDC hScreenDC = 0;
if (!(info = HeapAlloc( GetProcessHeap(), 0, max( size, FIELD_OFFSET( BITMAPINFO, bmiColors[2] )))))
return FALSE;
if(!hScreenDC)
{
hScreenDC = GetDC(0);
if(!hScreenDC) goto done;
}
if (!(hdc = CreateCompatibleDC(hScreenDC))) goto done;
if (!(hdc = CreateCompatibleDC(NULL))) goto done;
memcpy( info, bmi, size );
info->bmiHeader.biHeight /= 2;
@ -491,8 +485,8 @@ static BOOL create_icon_bitmaps( const BITMAPINFO *bmi, int width, int height,
else
{
if (!(*mask = CreateBitmap( width, height, 1, 1, NULL ))) goto done;
if (!(*color = CreateBitmap( width, height, GetDeviceCaps(hScreenDC, PLANES),
GetDeviceCaps(hScreenDC, BITSPIXEL), NULL )))
if (!(*color = CreateBitmap( width, height, GetDeviceCaps(hdc, PLANES),
GetDeviceCaps(hdc, BITSPIXEL), NULL )))
{
DeleteObject( *mask );
goto done;

View file

@ -1564,20 +1564,29 @@ FlashWindow(HWND hWnd, BOOL bInvert)
INT WINAPI
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)
{
return FALSE;
}
PatBlt(hDC, lprc->left, lprc->top, lprc->right - lprc->left,
lprc->bottom - lprc->top, PATCOPY);
SelectObject(hDC, prevhbr);
return TRUE;
Ret = PatBlt(hDC, lprc->left, lprc->top, lprc->right - lprc->left,
lprc->bottom - lprc->top, PATCOPY);
/* Select old brush */
if (prevhbr)
SelectObject(hDC, prevhbr);
return (INT)Ret;
}
/*

View file

@ -100,7 +100,6 @@ DragDetect(
#endif
}
/*
* @implemented
*/
@ -108,43 +107,9 @@ BOOL WINAPI
EnableWindow(HWND hWnd,
BOOL bEnable)
{
// This will soon be moved to win32k.
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;
return NtUserCallTwoParam((DWORD_PTR)hWnd, (DWORD_PTR)bEnable, TWOPARAM_ROUTINE_ENABLEWINDOW);
}
/*
* @implemented
*/

View file

@ -1576,6 +1576,11 @@ static BOOL FASTCALL MenuShowPopup(HWND hwndOwner, HMENU hmenu, UINT id, UINT fl
MenuInfo.FocusedItem = NO_SELECTED_ITEM;
}
/* ReactOS Check */
if (!ValidateHwnd(hwndOwner))
{ // This window maybe already DEAD!!!
return FALSE;
}
/* store the owner for DrawItem */
MenuInfo.WndOwner = hwndOwner;
MenuSetRosMenuInfo(&MenuInfo);
@ -3174,6 +3179,7 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y,
BOOL fRemove;
INT executedMenuId = -1;
MTRACKER mt;
HWND capture_win;
BOOL enterIdleSent = FALSE;
mt.TrackFlags = 0;
@ -3207,12 +3213,16 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y,
fEndMenu = !fRemove;
}
SetCapture(mt.OwnerWnd);
(void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, mt.OwnerWnd);
if (wFlags & TF_ENDMENU) fEndMenu = TRUE;
/* 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)
{
BOOL ErrorExit = FALSE;
PVOID menu = ValidateHandle(mt.CurrentMenu, VALIDATE_TYPE_MENU);
if (!menu) /* sometimes happens if I do a window manager close */
break;
@ -3230,6 +3240,12 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y,
}
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)
{
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();
}
//FIXME("MenuTrackMenu loop 1\n");
}
if (ErrorExit) break; // Gracefully dropout.
/* check if EndMenu() tried to cancel us, by posting this message */
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 );
DispatchMessageW( &msg );
//FIXME("MenuTrackMenu loop 2\n");
continue;
}
@ -3457,9 +3473,7 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y,
if (fRemove && !(mt.TrackFlags & TF_SKIPREMOVE) )
PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE );
else mt.TrackFlags &= ~TF_SKIPREMOVE;
//FIXME("MenuTrackMenu loop 3\n");
}
FIXME("MenuTrackMenu 2\n");
(void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, NULL);
SetCapture(NULL); /* release the capture */
@ -3518,12 +3532,11 @@ static BOOL FASTCALL MenuInitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT
HideCaret(0);
MenuGetRosMenuInfo(&MenuInfo, hMenu);
/* This makes the menus of applications built with Delphi work.
* 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.
*/
if(MenuInfo.Self == hMenu)
if (MenuGetRosMenuInfo(&MenuInfo, hMenu))
{
MenuInfo.Wnd = hWnd;
MenuSetRosMenuInfo(&MenuInfo);
@ -3655,13 +3668,7 @@ VOID MenuTrackKbdMenuBar(HWND hwnd, UINT wParam, WCHAR wChar)
MenuSelectItem( hwnd, &MenuInfo, uItem, TRUE, 0 );
if (wParam & HTSYSMENU)
{
/* 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 (!(wParam & HTSYSMENU) || wChar == ' ')
{
if( uItem == NO_SELECTED_ITEM )
MenuMoveSelection( hwnd, &MenuInfo, ITEM_NEXT );
@ -3690,6 +3697,12 @@ BOOL WINAPI TrackPopupMenuEx( HMENU Menu, UINT Flags, int x, int y,
return FALSE;
}
/* ReactOS Check */
if (!ValidateHwnd(Wnd))
{
return FALSE;
}
MenuGetRosMenuInfo(&MenuInfo, Menu);
if (IsWindow(MenuInfo.Wnd))
{

View file

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

View file

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

View file

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

View file

@ -71,14 +71,25 @@ Author:
//
// LdrLockLoaderLock Flags
//
#define LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS 0x00000001
#define LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY 0x00000002
#define LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS 0x00000001
#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!
//
#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
//
@ -188,4 +199,10 @@ typedef struct _ALT_RESOURCE_MODULE
#endif
} 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

View file

@ -1012,7 +1012,7 @@ typedef struct _CURDIR
HANDLE Handle;
} CURDIR, *PCURDIR;
typedef struct RTL_DRIVE_LETTER_CURDIR
typedef struct _RTL_DRIVE_LETTER_CURDIR
{
USHORT Flags;
USHORT Length;
@ -1020,6 +1020,13 @@ typedef struct RTL_DRIVE_LETTER_CURDIR
UNICODE_STRING DosPath;
} 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
//

View file

@ -19,6 +19,9 @@ DWORD WINAPI DeleteProxyArpEntry(DWORD,DWORD,DWORD);
DWORD WINAPI EnableRouter(HANDLE*,OVERLAPPED*);
DWORD WINAPI FlushIpNetTable(DWORD);
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 GetBestInterface(IPAddr,PDWORD);
DWORD WINAPI GetBestRoute(DWORD,DWORD,PMIB_IPFORWARDROW);

View file

@ -348,6 +348,25 @@ typedef struct {
WAVEFORMATEX 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 {
ULONG Flags;
ULONG Control;
@ -734,4 +753,50 @@ typedef struct
ULONG ChannelMask;
} 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

View file

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

View file

@ -975,7 +975,7 @@ cpp_quote("#if _WIN32_WINNT >= 0x0500")
[in] DWORD Count,
[in, size_is(Count)] PRPC_UNICODE_STRING Names,
[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, out] DWORD *MappedCount,
[in] DWORD LookupOptions,
@ -1029,7 +1029,7 @@ cpp_quote("#if _WIN32_WINNT >= 0x0501")
[in] DWORD Count,
[in, size_is(Count)] PRPC_UNICODE_STRING Names,
[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, out] DWORD *MappedCount,
[in] DWORD LookupOptions,
@ -1088,7 +1088,7 @@ cpp_quote("#if _WIN32_WINNT >= 0x0501")
[in] DWORD Count,
[in, size_is(Count)] PRPC_UNICODE_STRING Names,
[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, out] DWORD *MappedCount,
[in] DWORD LookupOptions,

View file

@ -34,97 +34,138 @@
Here you can change the configuration of FullFAT as appropriate to your
platform.
*/
//---------- ENDIANESS
#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.
// See ff_memory.c for more information.
#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.
// See ff_memory.c for more information.
//---------- LFN (Long File-name) SUPPORT
#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!
#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!
//---------- LEGAL LFNS
//#define FF_LEGAL_LFNS // Enabling this define causes FullFAT to not infringe on any of Microsoft's patents when making LFN names.
// To do this, it will only create LFNs and no shortnames. Microsofts patents are only relevent when mapping
// a shortname to a long name. This is the same way that Linux gets around the FAT legal issues:
// 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_INCLUDE_SHORT_NAME // HT addition, in 'FF_DIRENT', beside FileName, ShortName will be filled as well
// Useful for debugging, but also some situations its useful to know both.
//---------- SHORTNAMES CAN USE THE CASE BITS
#define FF_SHORTNAME_CASE // Works for XP+ e.g. short.TXT or SHORT.txt.
#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_NO_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.
// FF_FindFirst() and FF_FindNext() will also return Filenames in UTF-8 format.
//---------- DON'T
//---------- 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
// Note the 2 UNICODE options are mutually exclusive. Only one can be enabled.
// Ensure that dirents are big enough to hold the maximum UTF-8 sequence.
//---------- FAT12 SUPPORT
#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,
// therefore savings can be made by not having it.
#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,
// 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
#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:
// FF_GetFreeSize() and FF_GetVolumeSize() don't make sense when reporting sizes > 4GB.
#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:
// 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
#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.
//---------- Driver Sleep Time
#define FF_DRIVER_BUSY_SLEEP 20 // How long FullFAT should sleep the thread for in ms, if FF_ERR_DRIVER_BUSY is recieved.
//---------- Actively Determine if partition is FAT
#define FF_FAT_CHECK // This is experimental, so if FullFAT won't mount your volume, comment this out
// Also report the problem to james@worm.me.uk
//---------- DEBUGGING FEATURES (HELPFUL ERROR MESSAGES)
#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!
#ifdef FF_LFN_SUPPORT
#define FF_MAX_FILENAME 260
#define FF_MAX_FILENAME (260)
#else
#define FF_MAX_FILENAME 13
#define FF_MAX_FILENAME (13)
#endif
#ifdef FF_USE_NATIVE_STDIO
#ifdef MAX_PATH
#define FF_MAX_PATH MAX_PATH
#elif PATH_MAX
#define FF_MAX_PATH PATH_MAX
#else
#define FF_MAX_PATH 2600
#endif
@ -144,6 +185,16 @@
#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_BIG_ENDIAN
#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
#ifdef FF_HASH_TABLE_SUPPORT
#ifdef FF_HASH_CACHE
#if FF_HASH_FUNCTION == CRC16
#define FF_HASH_TABLE_SIZE 8192
#elif FF_HASH_FUNCTION == CRC8
#define FF_HASH_TABLE_SIZE 32
#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
//---------- END-OF-CONFIGURATION

View file

@ -44,6 +44,7 @@
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_UINT32 FF_GetCRC32 (FF_T_UINT8 *pbyData, FF_T_UINT32 stLength);
#endif

View file

@ -43,7 +43,7 @@
#include "ff_ioman.h"
#include "ff_blk.h"
#include "ff_fat.h"
#include "fat.h"
#include "ff_fatdef.h"
#include "ff_memory.h"
#include "ff_time.h"
#include "ff_hash.h"
@ -52,54 +52,118 @@
#include <string.h>
typedef struct {
FF_T_INT8 FileName[FF_MAX_FILENAME];
FF_T_UINT8 Attrib;
FF_T_UINT32 ulChainLength;
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 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
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;
#ifdef FF_FINDAPI_ALLOW_WILDCARDS
#ifdef FF_UNICODE_SUPPORT
FF_T_WCHAR szWildCard[FF_MAX_FILENAME];
#else
FF_T_INT8 szWildCard[FF_MAX_FILENAME];
#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_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);
// PUBLIC API
#ifdef FF_UNICODE_SUPPORT
FF_ERROR FF_FindFirst (FF_IOMAN *pIoman, FF_DIRENT *pDirent, const FF_T_WCHAR *path);
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

View file

@ -40,53 +40,111 @@
#include "ff_config.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
that all error codes remain unique, and their meaning can be quickly identified.
*/
// Global Error Codes
#define FF_ERR_NONE 0 ///< No Error
#define FF_ERR_NULL_POINTER -2 ///< pIoman was NULL.
#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.
#define FF_ERR_NONE 0 ///< No Error
//#define FF_ERR_GENERIC 1 ///< BAD NEVER USE THIS!
#define FF_ERR_NULL_POINTER 2 ///< pIoman was NULL.
#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
#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_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_INVALID_FORMAT -15 ///< The
#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_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_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_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_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_INVALID_FORMAT 15 ///< The
#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_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_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 +
#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_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_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_READ_MODE -36
#define FF_ERR_FILE_EXTEND_FAILED -37 ///< Could not extend the file.
#define FF_ERR_FILE_DESTINATION_EXISTS -38
#define FF_ERR_FILE_SOURCE_NOT_FOUND -39
#define FF_ERR_FILE_DIR_NOT_FOUND -40
#define FF_ERR_FILE_COULD_NOT_CREATE_DIRENT -41
// File Error Codes 30 +
#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_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_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_READ_MODE 36
#define FF_ERR_FILE_EXTEND_FAILED 37 ///< Could not extend the file.
#define FF_ERR_FILE_DESTINATION_EXISTS 38
#define FF_ERR_FILE_SOURCE_NOT_FOUND 39
#define FF_ERR_FILE_DIR_NOT_FOUND 40
#define FF_ERR_FILE_COULD_NOT_CREATE_DIRENT 41
// 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_DIRECTORY_FULL -51 ///< No more items could be added to the directory.
#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_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.
// 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_DIRECTORY_FULL 51 ///< No more items could be added to the directory.
#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_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_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 +
#define FF_ERR_FAT_NO_FREE_CLUSTERS -70 ///< No more free space is available on the disk.
// Fat Error Codes 70 +
#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
const FF_T_INT8 *FF_GetErrMessage(FF_ERROR iErrorCode);

View file

@ -39,7 +39,7 @@
#define _FF_FAT_H_
#include "ff_config.h"
#include "fat.h"
#include "ff_fatdef.h"
#include "ff_ioman.h"
#include "ff_blk.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_Cluster2LBA (FF_IOMAN *pIoman, FF_T_UINT32 Cluster);
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_SINT8 FF_putFatEntry (FF_IOMAN *pIoman, FF_T_UINT32 nCluster, FF_T_UINT32 Value);
FF_T_UINT32 FF_FindFreeCluster (FF_IOMAN *pIoman);
FF_T_UINT32 FF_FindFreeCluster (FF_IOMAN *pIoman, FF_ERROR *pError);
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_T_UINT32 FF_TraverseFAT (FF_IOMAN *pIoman, FF_T_UINT32 Start, FF_T_UINT32 Count);
FF_T_UINT32 FF_CreateClusterChain (FF_IOMAN *pIoman);
FF_T_UINT32 FF_GetChainLength (FF_IOMAN *pIoman, FF_T_UINT32 pa_nStartCluster, FF_T_UINT32 *piEndOfChain);
FF_T_UINT32 FF_FindEndOfChain (FF_IOMAN *pIoman, FF_T_UINT32 Start);
FF_T_SINT8 FF_ClearCluster (FF_IOMAN *pIoman, FF_T_UINT32 nCluster);
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_ERROR *pError);
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_ERROR *pError);
FF_T_UINT32 FF_FindEndOfChain (FF_IOMAN *pIoman, FF_T_UINT32 Start, FF_ERROR *pError);
FF_ERROR FF_ClearCluster (FF_IOMAN *pIoman, FF_T_UINT32 nCluster);
#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
FF_T_UINT32 FF_GetFreeSize (FF_IOMAN *pIoman);
FF_T_UINT32 FF_GetFreeSize (FF_IOMAN *pIoman, FF_ERROR *pError);
#endif
FF_T_UINT32 FF_FindFreeCluster (FF_IOMAN *pIoman);
FF_T_UINT32 FF_CountFreeClusters (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!
void FF_lockFAT (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
// 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_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_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_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_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);
// 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.
**/
typedef struct {
FF_WRITE_BLOCKS fnWriteBlocks; ///< 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_WRITE_BLOCKS fnpWriteBlocks; ///< Function Pointer, to write 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.
void *pParam; ///< Pointer to some parameters e.g. for a Low-Level Driver Handle
} FF_BLK_DEVICE;
@ -100,24 +100,33 @@ typedef struct {
**/
typedef struct {
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 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 Valid; ///< Initially FALSE.
FF_T_UINT8 *pBuffer; ///< Pointer to the cache block.
} FF_BUFFER;
typedef struct {
#ifdef FF_UNICODE_SUPPORT
FF_T_WCHAR Path[FF_MAX_PATH];
#else
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
FF_T_UINT32 DirCluster;
} 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
* @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_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 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 PartSize; ///< Size of Partition in number of sectors.
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_PARTITION *pPartition; ///< Pointer to a partition 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_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_UINT8 PreventFlush; ///< Flushing to disk only allowed when 0
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).
void *pSemaphore; ///< Pointer to a Semaphore object. (For buffer description modifications only!).
void *FirstFile; ///< Pointer to the first File object.
#ifdef FF_HASH_CACHE
FF_HASHCACHE HashCache[FF_HASH_CACHE_DEPTH];
#endif
} FF_IOMAN;
// Bit-Masks for Memory Allocation testing.
@ -219,6 +235,8 @@ FF_T_UINT32 FF_GetVolumeSize(FF_IOMAN *pIoman);
#endif
// 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_DecreaseFreeClusters (FF_IOMAN *pIoman, FF_T_UINT32 Count);
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_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
FF_T_UINT8 FF_getChar (FF_T_UINT8 *pBuffer, FF_T_UINT16 offset);
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);
#if defined(FF_LITTLE_ENDIAN)
void FF_putChar (FF_T_UINT8 *pBuffer, FF_T_UINT16 offset, FF_T_UINT8 Value);
void FF_putShort (FF_T_UINT8 *pBuffer, FF_T_UINT16 offset, FF_T_UINT16 Value);
void FF_putLong (FF_T_UINT8 *pBuffer, FF_T_UINT16 offset, FF_T_UINT32 Value);
typedef struct {
FF_T_UINT8 u8_0;
FF_T_UINT8 u8_1;
} FF_T_SHORT;
void *FF_Malloc(FF_T_UINT32 allocSize);
void FF_Free(void *pBuffer);
typedef struct {
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

View file

@ -44,11 +44,35 @@
#define _FF_STRING_H_
#include "ff_types.h"
#include "ff_config.h"
#include <string.h>
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);
#ifdef WIN32
#define FF_stricmp stricmp
#else
#define FF_stricmp strcasecmp
#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

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 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
//---------------- 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.
@ -70,5 +75,9 @@ typedef signed long long FF_T_SINT64; // > 4GB in bytes if you cannot support 64
#endif
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

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_
#define _FULLFAT_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "ff_config.h"
#include "ff_ioman.h"
#include "ff_fat.h"
@ -41,6 +45,11 @@
#include "ff_crc.h"
#include "ff_hash.h"
#include "ff_string.h"
#include "ff_unicode.h"
//#include "ff_format.h"
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View file

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

View file

@ -41,7 +41,68 @@
#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,
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,
};
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,
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--) {
bTableValue = (FF_T_UINT8)((wCRC & 0x00FF) ^ *pbyData++);
wCRC = (FF_T_UINT16)(((CRC16_High[bTableValue]) << 8)
+ (CRC16_Low[bTableValue] ^ ((wCRC >> 8) & 0x00FF)));
wCRC = (FF_T_UINT16)(((crc16_table_high[bTableValue]) << 8)
+ (crc16_table_low[bTableValue] ^ ((wCRC >> 8) & 0x00FF)));
}
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,
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;
while (stLength--) {
byData = *pbyData++;
byCRC = byCRCLookUpTable[(byCRC ^ byData)];
byCRC = crc8_table[(byCRC ^ byData)];
}
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},
{"Device Driver returned a FATAL error!.", FF_ERR_DEVICE_DRIVER_FAILED},
{"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},
{"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},
@ -65,6 +65,7 @@ const struct _FFERRTAB
{"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 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},
{"The specified file could not be found.", FF_ERR_FILE_NOT_FOUND},
{"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},
{"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},
{"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
**/
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_T_UINT32 FatOffset;
@ -136,19 +136,20 @@ FF_T_SINT32 FF_getFatEntry(FF_IOMAN *pIoman, FF_T_UINT32 nCluster) {
FatSectorEntry = FatOffset % pIoman->pPartition->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);
#ifdef FF_FAT12_SUPPORT
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!
// First Buffer get the last Byte in buffer (first byte of our address)!
pBuffer = FF_GetBuffer(pIoman, FatSector + LBAadjust, FF_MODE_READ);
{
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));
}
@ -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);
{
if(!pBuffer) {
return FF_ERR_DEVICE_DRIVER_FAILED;
*pError = FF_ERR_DEVICE_DRIVER_FAILED;
return 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);
{
if(!pBuffer) {
return FF_ERR_DEVICE_DRIVER_FAILED;
*pError = FF_ERR_DEVICE_DRIVER_FAILED;
return 0;
}
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;
}
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_T_UINT16 i;
FF_T_UINT32 BaseLBA;
FF_T_SINT8 RetVal = 0;
BaseLBA = FF_Cluster2LBA(pIoman, nCluster);
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++) {
pBuffer = FF_GetBuffer(pIoman, BaseLBA++, FF_MODE_WRITE);
{
if(pBuffer) {
memset(pBuffer->pBuffer, 0x00, 512);
} else {
RetVal = FF_ERR_DEVICE_DRIVER_FAILED;
if(!pBuffer) {
return FF_ERR_DEVICE_DRIVER_FAILED;
}
memset(pBuffer->pBuffer, 0x00, 512);
}
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 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 fatEntry = Start, currentCluster = Start;
*pError = FF_ERR_NONE;
for(i = 0; i < Count; i++) {
fatEntry = FF_getFatEntry(pIoman, currentCluster);
if(fatEntry == (FF_T_UINT32) FF_ERR_DEVICE_DRIVER_FAILED) {
fatEntry = FF_getFatEntry(pIoman, currentCluster, pError);
if(*pError) {
return 0;
}
@ -264,13 +267,14 @@ FF_T_UINT32 FF_TraverseFAT(FF_IOMAN *pIoman, FF_T_UINT32 Start, FF_T_UINT32 Coun
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;
*pError = FF_ERR_NONE;
while(!FF_isEndOfChain(pIoman, fatEntry)) {
fatEntry = FF_getFatEntry(pIoman, currentCluster);
if(fatEntry == (FF_T_UINT32) FF_ERR_DEVICE_DRIVER_FAILED) {
fatEntry = FF_getFatEntry(pIoman, currentCluster, pError);
if(*pError) {
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 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_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 FatEntry;
FF_T_UINT8 LBAadjust;
FF_T_UINT16 relClusterEntry;
FF_T_UINT32 relClusterEntry;
#ifdef FF_FAT12_SUPPORT
FF_T_UINT8 F12short[2]; // For FAT12 FAT Table Across sector boundary traversal.
#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;
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);
#ifdef FF_FAT12_SUPPORT
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!
// First Buffer get the last Byte in buffer (first byte of our address)!
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);
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.
**/
#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 fatEntry;
*pError = FF_ERR_NONE;
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) {
pIoman->pPartition->LastFreeCluster = nCluster;
return nCluster;
@ -469,7 +478,7 @@ FF_T_UINT32 FF_FindFreeClusterOLD(FF_IOMAN *pIoman) {
}
#endif
FF_T_UINT32 FF_FindFreeCluster(FF_IOMAN *pIoman) {
FF_T_UINT32 FF_FindFreeCluster(FF_IOMAN *pIoman, FF_ERROR *pError) {
FF_BUFFER *pBuffer;
FF_T_UINT32 i, x, nCluster = pIoman->pPartition->LastFreeCluster;
FF_T_UINT32 FatOffset;
@ -478,9 +487,11 @@ FF_T_UINT32 FF_FindFreeCluster(FF_IOMAN *pIoman) {
FF_T_UINT32 EntriesPerSector;
FF_T_UINT32 FatEntry = 1;
*pError = FF_ERR_NONE;
#ifdef FF_FAT12_SUPPORT
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
@ -492,11 +503,21 @@ FF_T_UINT32 FF_FindFreeCluster(FF_IOMAN *pIoman) {
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);
for(i = FatSector; i < pIoman->pPartition->SectorsPerFAT; i++) {
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++) {
if(pIoman->pPartition->Type == FF_T_FAT32) {
FatOffset = x * 4;
@ -528,24 +549,54 @@ FF_T_UINT32 FF_FindFreeCluster(FF_IOMAN *pIoman) {
* @private
* @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_ERROR Error;
*pError = FF_ERR_NONE;
FF_lockFAT(pIoman);
{
iStartCluster = FF_FindFreeCluster(pIoman);
FF_putFatEntry(pIoman, iStartCluster, 0xFFFFFFFF); // Mark the cluster as EOC
iStartCluster = FF_FindFreeCluster(pIoman, &Error);
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);
if(iStartCluster) {
Error = FF_DecreaseFreeClusters(pIoman, 1);
if(Error) {
*pError = Error;
return 0;
}
}
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;
*pError = FF_ERR_NONE;
FF_lockFAT(pIoman);
{
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++;
}
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.
*
**/
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 currentCluster, chainLength = 0;
FF_T_UINT32 iLen = 0;
FF_T_UINT32 lastFree = StartCluster; /* HT addition : reset LastFreeCluster */
FF_ERROR Error;
fatEntry = StartCluster;
@ -620,16 +673,35 @@ FF_T_SINT8 FF_UnlinkClusterChain(FF_IOMAN *pIoman, FF_T_UINT32 StartCluster, FF_
currentCluster = StartCluster;
fatEntry = currentCluster;
do {
fatEntry = FF_getFatEntry(pIoman, fatEntry);
FF_putFatEntry(pIoman, currentCluster, 0x00000000);
fatEntry = FF_getFatEntry(pIoman, fatEntry, &Error);
if(Error) {
return Error;
}
Error = FF_putFatEntry(pIoman, currentCluster, 0x00000000);
if(Error) {
return Error;
}
if (lastFree > currentCluster) {
lastFree = currentCluster;
}
currentCluster = fatEntry;
iLen ++;
}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 {
// Truncation - This is quite hard, because we can only do it backwards.
do {
fatEntry = FF_getFatEntry(pIoman, fatEntry);
fatEntry = FF_getFatEntry(pIoman, fatEntry, &Error);
if(Error) {
return Error;
}
chainLength++;
}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
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 TotalClusters = pIoman->pPartition->DataSectors / pIoman->pPartition->SectorsPerCluster;
FF_T_UINT32 FatEntry;
FF_T_UINT32 FreeClusters = 0;
*pError = FF_ERR_NONE;
for(i = 0; i < TotalClusters; i++) {
FatEntry = FF_getFatEntry(pIoman, i);
FatEntry = FF_getFatEntry(pIoman, i, pError);
if(*pError) {
return 0;
}
if(!FatEntry) {
FreeClusters++;
}
@ -656,7 +733,7 @@ FF_T_UINT32 FF_CountFreeClustersOLD(FF_IOMAN *pIoman) {
#endif
FF_T_UINT32 FF_CountFreeClusters(FF_IOMAN *pIoman) {
FF_T_UINT32 FF_CountFreeClusters(FF_IOMAN *pIoman, FF_ERROR *pError) {
FF_BUFFER *pBuffer;
FF_T_UINT32 i, x, nCluster = 0;
FF_T_UINT32 FatOffset;
@ -666,9 +743,14 @@ FF_T_UINT32 FF_CountFreeClusters(FF_IOMAN *pIoman) {
FF_T_UINT32 FatEntry = 1;
FF_T_UINT32 FreeClusters = 0;
*pError = FF_ERR_NONE;
#ifdef FF_FAT12_SUPPORT
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
@ -685,6 +767,10 @@ FF_T_UINT32 FF_CountFreeClusters(FF_IOMAN *pIoman) {
for(i = 0; i < pIoman->pPartition->SectorsPerFAT; i++) {
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++) {
if(pIoman->pPartition->Type == FF_T_FAT32) {
FatOffset = x * 4;
@ -694,7 +780,7 @@ FF_T_UINT32 FF_CountFreeClusters(FF_IOMAN *pIoman) {
} else {
FatOffset = x * 2;
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) {
FreeClusters += 1;
@ -706,19 +792,27 @@ FF_T_UINT32 FF_CountFreeClusters(FF_IOMAN *pIoman) {
FF_ReleaseBuffer(pIoman, pBuffer);
}
return FreeClusters;
return FreeClusters <= pIoman->pPartition->NumClusters ? FreeClusters : pIoman->pPartition->NumClusters;
}
#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_UINT64 FreeSize;
FF_ERROR Error;
if(pIoman) {
FF_lockFAT(pIoman);
{
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;
}

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 <string.h>
#ifdef FF_HASH_TABLE_SUPPORT
#ifdef FF_HASH_CACHE
struct _FF_HASH_TABLE {
FF_T_UINT8 bitTable[FF_HASH_TABLE_SIZE];
};
@ -53,7 +53,7 @@ struct _FF_HASH_TABLE {
*
**/
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) {
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) {
if(pHash) {
free(pHash);
FF_FREE(pHash);
return FF_ERR_NONE;
}
return FF_ERR_NULL_POINTER;

View file

@ -42,11 +42,14 @@
* Destroying a FullFAT IO object.
**/
#include "ff_ioman.h" // Includes ff_types.h, ff_safety.h, <stdio.h>
#include "fat.h"
#include <string.h>
extern FF_T_UINT32 FF_FindFreeCluster (FF_IOMAN *pIoman);
extern FF_T_UINT32 FF_CountFreeClusters (FF_IOMAN *pIoman);
#include "ff_ioman.h" // Includes ff_types.h, ff_safety.h, <stdio.h>
#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);
@ -55,7 +58,7 @@ static void FF_IOMAN_InitBufferDescriptors(FF_IOMAN *pIoman);
* @brief Creates an FF_IOMAN object, to initialise FullFAT
*
* @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 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.
@ -75,85 +78,99 @@ FF_IOMAN *FF_CreateIOMAN(FF_T_UINT8 *pCacheMem, FF_T_UINT32 Size, FF_T_UINT16 Bl
*pError = FF_ERR_NONE;
}
if((BlkSize % 512) != 0 || Size == 0) {
if((BlkSize % 512) != 0 || BlkSize == 0) {
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
}
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) {
*pError = FF_ERR_IOMAN_BAD_MEMSIZE;
*pError = FF_ERR_IOMAN_BAD_MEMSIZE | FF_CREATEIOMAN;
}
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(pError) {
*pError = FF_ERR_NOT_ENOUGH_MEMORY;
*pError = FF_ERR_NOT_ENOUGH_MEMORY | FF_CREATEIOMAN;
}
return NULL;
}
memset (pIoman, '\0', sizeof(FF_IOMAN));
// This is just a bit-mask, to use a byte to keep track of memory.
// pIoman->MemAllocation = 0x00; // Unset all allocation identifiers.
pIoman->pBlkDevice = NULL;
pIoman->pBuffers = NULL;
pIoman->pCacheMem = NULL;
pIoman->pPartition = NULL;
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
pIoman->pPartition = (FF_PARTITION *) FF_MALLOC(sizeof(FF_PARTITION));
if(!pIoman->pPartition) {
if(pError) {
*pError = FF_ERR_NOT_ENOUGH_MEMORY | FF_CREATEIOMAN;
}
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
} 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);
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));
if(pIoman->pBlkDevice) { // If succeeded, flag that allocation.
pIoman->MemAllocation |= FF_IOMAN_ALLOC_BLKDEV;
// Make sure all pointers are NULL
pIoman->pBlkDevice->fnReadBlocks = NULL;
pIoman->pBlkDevice->fnWriteBlocks = NULL;
pIoman->pBlkDevice->pParam = NULL;
} else {
FF_DestroyIOMAN(pIoman);
return NULL;
}
// Make sure all pointers are NULL
pIoman->pBlkDevice->fnpReadBlocks = NULL;
pIoman->pBlkDevice->fnpWriteBlocks = NULL;
pIoman->pBlkDevice->pParam = NULL;
// Organise the memory provided, or create our own!
if(pCacheMem) {
pIoman->pCacheMem = pCacheMem;
}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;
if(!pIoman->pCacheMem) {
pIoman->MemAllocation |= FF_IOMAN_ALLOC_BUFFERS;
if(pError) {
*pError = FF_ERR_NOT_ENOUGH_MEMORY | FF_CREATEIOMAN;
}
FF_DestroyIOMAN(pIoman);
return NULL;
}
pIoman->MemAllocation |= FF_IOMAN_ALLOC_BUFFERS;
}
memset (pIoman->pCacheMem, '\0', Size);
pIoman->BlkSize = 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
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) {
pIoman->MemAllocation |= FF_IOMAN_ALLOC_BUFDESCR;
FF_IOMAN_InitBufferDescriptors(pIoman);
} else {
if(!pIoman->pBuffers) {
if(pError) {
*pError = FF_ERR_NOT_ENOUGH_MEMORY | FF_CREATEIOMAN;
}
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.
pIoman->pSemaphore = FF_CreateSemaphore();
#ifdef FF_BLKDEV_USES_SEM
pIoman->pBlkDevSemaphore = FF_CreateSemaphore();
#endif
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) {
#ifdef FF_HASH_CACHE
FF_T_UINT32 i;
#endif
// Ensure no NULL pointer was provided.
if(!pIoman) {
return FF_ERR_NULL_POINTER;
return FF_ERR_NULL_POINTER | FF_DESTROYIOMAN;
}
// Ensure pPartition pointer was allocated.
if((pIoman->MemAllocation & FF_IOMAN_ALLOC_PART)) {
FF_Free(pIoman->pPartition);
FF_FREE(pIoman->pPartition);
}
// Ensure pBlkDevice pointer was allocated.
if((pIoman->MemAllocation & FF_IOMAN_ALLOC_BLKDEV)) {
FF_Free(pIoman->pBlkDevice);
FF_FREE(pIoman->pBlkDevice);
}
// Ensure pBuffers pointer was allocated.
if((pIoman->MemAllocation & FF_IOMAN_ALLOC_BUFDESCR)) {
FF_Free(pIoman->pBuffers);
FF_FREE(pIoman->pBuffers);
}
// Ensure pCacheMem pointer was allocated.
if((pIoman->MemAllocation & FF_IOMAN_ALLOC_BUFFERS)) {
FF_Free(pIoman->pCacheMem);
FF_FREE(pIoman->pCacheMem);
}
// Destroy any Semaphore that was created.
if(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.
FF_Free(pIoman);
FF_FREE(pIoman);
return FF_ERR_NONE;
}
@ -236,100 +278,13 @@ static void FF_IOMAN_InitBufferDescriptors(FF_IOMAN *pIoman) {
FF_T_UINT16 i;
FF_BUFFER *pBuffer = pIoman->pBuffers;
pIoman->LastReplaced = 0;
// HT : it is assmued that pBuffer was cleared by memset ()
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->Modified = FF_FALSE;
pBuffer->Valid = FF_FALSE;
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
@ -344,7 +299,7 @@ FF_ERROR FF_FlushCache(FF_IOMAN *pIoman) {
FF_T_UINT16 i,x;
if(!pIoman) {
return FF_ERR_NULL_POINTER;
return FF_ERR_NULL_POINTER | FF_FLUSHCACHE;
}
FF_PendSemaphore(pIoman->pSemaphore);
@ -352,7 +307,7 @@ FF_ERROR FF_FlushCache(FF_IOMAN *pIoman) {
for(i = 0; i < pIoman->CacheSize; i++) {
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.
(pIoman->pBuffers + i)->Mode = FF_MODE_READ;
@ -375,13 +330,6 @@ FF_ERROR FF_FlushCache(FF_IOMAN *pIoman) {
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 *pBuffer;
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) {
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);
if(pBuffer->Sector == Sector && pBuffer->Valid == FF_TRUE) {
pBufMatch = pBuffer;
} else {
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;
}
}
break; // Why look further if you found a perfect match?
}
}
@ -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!
} 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) {
// Process the suitable candidate.
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->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;
}
FF_IOMAN_FillBuffer(pIoman, Sector, pBufLRU->pBuffer);
FF_BlockRead(pIoman, Sector, 1, pBufLRU->pBuffer);
pBufLRU->Valid = FF_TRUE;
FF_ReleaseSemaphore(pIoman->pSemaphore);
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_Yield();
FF_Yield(); // Better to go asleep to give low-priority task a chance to release buffer(s)
}
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.
FF_PendSemaphore(pIoman->pSemaphore);
{
pBuffer->NumHandles--;
if (pBuffer->NumHandles) {
pBuffer->NumHandles--;
} else {
//printf ("FF_ReleaseBuffer: buffer not claimed\n");
}
}
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) {
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) {
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) {
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"
// Doing so would corrupt the context of FullFAT
if(pIoman->pBlkDevice->fnReadBlocks) {
return FF_ERR_IOMAN_DEV_ALREADY_REGD;
if(pIoman->pBlkDevice->fnpReadBlocks) {
return FF_ERR_IOMAN_DEV_ALREADY_REGD | FF_REGISTERBLKDEVICE;
}
if(pIoman->pBlkDevice->fnWriteBlocks) {
return FF_ERR_IOMAN_DEV_ALREADY_REGD;
if(pIoman->pBlkDevice->fnpWriteBlocks) {
return FF_ERR_IOMAN_DEV_ALREADY_REGD | FF_REGISTERBLKDEVICE;
}
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.
// FullFAT checks before using any of these values.
pIoman->pBlkDevice->devBlkSize = BlkSize;
pIoman->pBlkDevice->fnReadBlocks = fnReadBlocks;
pIoman->pBlkDevice->fnWriteBlocks = fnWriteBlocks;
pIoman->pBlkDevice->fnpReadBlocks = fnReadBlocks;
pIoman->pBlkDevice->fnpWriteBlocks = fnWriteBlocks;
pIoman->pBlkDevice->pParam = pParam;
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
**/
@ -620,7 +632,7 @@ static FF_ERROR FF_DetermineFatType(FF_IOMAN *pIoman) {
testLong = FF_getLong(pBuffer->pBuffer, 0x0000);
}
FF_ReleaseBuffer(pIoman, pBuffer);
if((testLong & 0x0FFFFFF8) != 0x0FFFFFF8) {
if((testLong & 0x0FFFFFF8) != 0x0FFFFFF8 && (testLong & 0x0FFFFFF8) != 0x0FFFFFF0) {
return FF_ERR_IOMAN_NOT_FAT_FORMATTED;
}
#endif
@ -630,6 +642,119 @@ static FF_ERROR FF_DetermineFatType(FF_IOMAN *pIoman) {
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
* @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_PARTITION *pPart;
FF_BUFFER *pBuffer = 0;
FF_ERROR Error;
FF_T_UINT8 ucPartitionType;
int partCount;
if(!pIoman) {
return FF_ERR_NULL_POINTER;
}
if(PartitionNumber > 3) {
/*if(PartitionNumber > 3) {
return FF_ERR_IOMAN_INVALID_PARTITION_NUM;
}
}*/
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);
if(!pBuffer) {
return FF_ERR_DEVICE_DRIVER_FAILED;
}
partCount = FF_PartitionCount (pBuffer->pBuffer);
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)
pPart->BeginLBA = 0;
} 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);
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) {
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;
}
}
// Assume FAT16, then we'll adjust if its FAT32
pPart->ReservedSectors = FF_getShort(pBuffer->pBuffer, FF_FAT_RESERVED_SECTORS);
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) {
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
pPart->ClusterBeginLBA = pPart->BeginLBA + pPart->ReservedSectors + (pPart->NumFATS * pPart->SectorsPerFAT);
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) {
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!
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->FirstDataSector = pPart->ClusterBeginLBA + 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;
if(FF_DetermineFatType(pIoman)) {
return FF_ERR_IOMAN_NOT_FAT_FORMATTED;
Error = FF_DetermineFatType(pIoman);
if(Error) {
return Error;
}
#ifdef FF_MOUNT_FIND_FREE
@ -761,8 +937,8 @@ FF_ERROR FF_UnregisterBlkDevice(FF_IOMAN *pIoman) {
{
if(pIoman->pPartition->PartitionMounted == FF_FALSE) {
pIoman->pBlkDevice->devBlkSize = 0;
pIoman->pBlkDevice->fnReadBlocks = NULL;
pIoman->pBlkDevice->fnWriteBlocks = NULL;
pIoman->pBlkDevice->fnpReadBlocks = NULL;
pIoman->pBlkDevice->fnpWriteBlocks = NULL;
pIoman->pBlkDevice->pParam = NULL;
} else {
RetVal = FF_ERR_IOMAN_PARTITION_MOUNTED;
@ -817,7 +993,11 @@ FF_ERROR FF_UnmountPartition(FF_IOMAN *pIoman) {
{
if(!FF_ActiveHandles(pIoman)) {
if(pIoman->FirstFile == NULL) {
// Release Semaphore to call this function!
FF_ReleaseSemaphore(pIoman->pSemaphore);
FF_FlushCache(pIoman); // Flush any unwritten sectors to disk.
// Reclaim Semaphore
FF_PendSemaphore(pIoman->pSemaphore);
pIoman->pPartition->PartitionMounted = FF_FALSE;
} else {
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 Error;
//FF_PendSemaphore(pIoman->pSemaphore);
//{
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);
@ -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 Error;
//FF_lockFAT(pIoman);
//{
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);

View file

@ -48,87 +48,55 @@
#include "ff_memory.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
incase there is a system that doesn't have byte-wise access to all memory.
* HT inlined these functions
*
* 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.
*/
FF_T_UINT8 FF_getChar(FF_T_UINT8 *pBuffer, FF_T_UINT16 offset) {
return (FF_T_UINT8) (pBuffer[offset]);
#ifndef FF_INLINE_MEMORY_ACCESS
FF_T_UINT8 FF_getChar(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset) {
return (FF_T_UINT8) (pBuffer[aOffset]);
}
FF_T_UINT16 FF_getShort(FF_T_UINT8 *pBuffer, FF_T_UINT16 offset) {
return (FF_T_UINT16) (pBuffer[offset] & 0x00FF) | ((FF_T_UINT16) (pBuffer[offset+1] << 8) & 0xFF00);
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_T_UINT32 FF_getLong(FF_T_UINT8 *pBuffer, FF_T_UINT16 offset) {
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_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;
}
void FF_putChar(FF_T_UINT8 *pBuffer, FF_T_UINT16 offset, FF_T_UINT8 Value) {
pBuffer[offset] = Value;
void FF_putChar(FF_T_UINT8 *pBuffer, FF_T_UINT32 aOffset, FF_T_UINT8 Value) {
pBuffer[aOffset] = 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[0];
pBuffer[offset + 1] = Val[1];
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;
}
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[0];
pBuffer[offset + 1] = Val[1];
pBuffer[offset + 2] = Val[2];
pBuffer[offset + 3] = Val[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];
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;
}
#endif

View file

@ -55,50 +55,113 @@
**/
#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) {
// Call your OS's CreateSemaphore function
//
PKSEMAPHORE ProcessSemaphore;
// return pointer to semaphore
return NULL; // Comment this out for your implementation.
/* Allocate some memory to store the semaphore */
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) {
// 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.
pSemaphore = 0;
NTSTATUS Status;
/* Sanity check */
if (pSemaphore)
{
/* Wait for the sempaphore to become signaled */
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) {
// Call your OS's ReleaseSemaphore with the provided pSemaphore pointer.
//
//
pSemaphore = 0;
/* Sanity check */
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) {
// Call your OS's DestroySemaphore with the provided pSemaphore pointer.
//
//
pSemaphore = 0;
/* Sanity check */
if (pSemaphore)
{
/* Free the semaphore memory */
ExFreePoolWithTag(pSemaphore,
TAG_FULLFAT);
}
}
// FIXME: what do we do with this?
void FF_Yield(void) {
// Call your OS's thread Yield function.
// 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) {
// Call your OS's thread sleep function,
// Sleep for TimeMs milliseconds
TimeMs = 0;
LARGE_INTEGER Interval;
NTSTATUS Status;
/* 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 <string.h>
#include <ctype.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
* 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
* @brief Converts an ASCII string to lowercase.
**/
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;
}
}
#ifndef FF_UNICODE_SUPPORT
/**
* @private
* @brief Converts an ASCII string to uppercase.
@ -76,6 +106,32 @@ void FF_toupper(FF_T_INT8 *string, FF_T_UINT32 strLen) {
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.
*
**/
#ifndef FF_UNICODE_SUPPORT
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_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;
}
#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
* @brief A re-entrant Strtok function. No documentation is provided :P
* 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_UINT16 strLen = Length;
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;
}
memcpy(token, (string + tokenStart), (FF_T_UINT32)(tokenEnd - tokenStart));
token[tokenEnd - tokenStart] = '\0';
if((tokenEnd - tokenStart) < FF_MAX_FILENAME) {
memcpy(token, (string + tokenStart), (FF_T_UINT32)(tokenEnd - tokenStart));
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;
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) {
/* Check to see if the string contains the wild card */
i = 0;
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 it does not then do a straight string compare */
// if it does not then do a straight string compare
if (strcmp(pszWildCard, pszString))
{
return FF_FALSE;
@ -177,20 +321,20 @@ FF_T_BOOL FF_wildcompare(const FF_T_INT8 *pszWildCard, const FF_T_INT8 *pszStrin
while ((*pszWildCard)
&& (*pszString))
{
/* Test for the wild card */
// Test for the wild card
if (*pszWildCard == '*')
{
/* Eat more than one */
// Eat more than one
while (*pszWildCard == '*')
{
pszWildCard++;
}
/* If there are more chars in the string */
// If there are more chars in the string
if (*pszWildCard)
{
/* Search for the next char */
// Search for the next char
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)
{
return FF_FALSE;
@ -201,7 +345,7 @@ FF_T_BOOL FF_wildcompare(const FF_T_INT8 *pszWildCard, const FF_T_INT8 *pszStrin
{
if (*pszWildCard)
{
/* continue */
// continue
break;
}
else
@ -212,17 +356,17 @@ FF_T_BOOL FF_wildcompare(const FF_T_INT8 *pszWildCard, const FF_T_INT8 *pszStrin
}
else
{
/* Fail if they don't match */
// Fail if they don't match
if (*pszWildCard != *pszString)
{
return FF_FALSE;
}
}
/* Bump both pointers */
// Bump both pointers
pszWildCard++;
pszString++;
}
/* fail if different lengths */
// fail if different lengths
if (*pszWildCard != *pszString)
{
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;
}
}*/
/*
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 FileLength)
{
#if 0
PIMAGE_NT_HEADERS Header;
PUSHORT Ptr;
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);
return (BOOLEAN)(CalcSum == HeaderSum);
#else
return TRUE;
#endif
}
/*

View file

@ -340,6 +340,9 @@ KiDeliverApc(IN KPROCESSOR_MODE DeliveryMode,
break;
}
/* Kernel APC is not pending anymore */
Thread->ApcState.KernelApcPending = FALSE;
/* Get the next Entry */
ApcListEntry = Thread->ApcState.ApcListHead[KernelMode].Flink;
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! */
MiDereferenceImports(LoadedImports);
if (LoadedImports) ExFreePool(LoadedImports);
if (LoadedImports) ExFreePoolWithTag(LoadedImports, 'TDmM');
return STATUS_PROCEDURE_NOT_FOUND;
}
@ -1073,7 +1073,7 @@ MiResolveImageReferences(IN PVOID ImageBase,
{
/* This is not kernel code */
MiDereferenceImports(LoadedImports);
if (LoadedImports) ExFreePool(LoadedImports);
if (LoadedImports) ExFreePoolWithTag(LoadedImports, 'TDmM');
return STATUS_PROCEDURE_NOT_FOUND;
}
@ -1098,7 +1098,7 @@ MiResolveImageReferences(IN PVOID ImageBase,
{
/* Failed */
MiDereferenceImports(LoadedImports);
if (LoadedImports) ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR);
if (LoadedImports) ExFreePoolWithTag(LoadedImports, 'TDmM');
return Status;
}
@ -1219,7 +1219,7 @@ CheckDllState:
/* Cleanup and return */
RtlFreeUnicodeString(&NameString);
MiDereferenceImports(LoadedImports);
if (LoadedImports) ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR);
if (LoadedImports) ExFreePoolWithTag(LoadedImports, 'TDmM');
return Status;
}
@ -1252,7 +1252,7 @@ CheckDllState:
{
/* Cleanup and return */
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);
return STATUS_DRIVER_ENTRYPOINT_NOT_FOUND;
}
@ -1282,7 +1282,7 @@ CheckDllState:
{
/* Cleanup and return */
MiDereferenceImports(LoadedImports);
if (LoadedImports) ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR);
if (LoadedImports) ExFreePoolWithTag(LoadedImports, 'TDmM');
return Status;
}
@ -1315,13 +1315,13 @@ CheckDllState:
if (!ImportCount)
{
/* Free the list and set it to no imports */
ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR);
ExFreePoolWithTag(LoadedImports, 'TDmM');
LoadedImports = MM_SYSLDR_NO_IMPORTS;
}
else if (ImportCount == 1)
{
/* 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;
}
else if (ImportCount != LoadedImports->Count)
@ -1349,7 +1349,7 @@ CheckDllState:
}
/* Free the old copy */
ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR);
ExFreePoolWithTag(LoadedImports, 'TDmM');
LoadedImports = NewImports;
}
}
@ -3004,7 +3004,7 @@ Quickie:
/* if (NamePrefix) ExFreePool(PrefixName.Buffer); */
/* Free the name buffer and return status */
ExFreePoolWithTag(Buffer, TAG_LDR_WSTR);
ExFreePoolWithTag(Buffer, 'nLmM');
return Status;
}

View file

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

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