update SVN properties

svn path=/trunk/; revision=17143
This commit is contained in:
Martin Fuchs 2005-08-07 07:33:14 +00:00
parent 100b8232d0
commit 4f8cc9596c
69 changed files with 14676 additions and 14676 deletions

View file

@ -1,105 +1,105 @@
//
// CardLib - Card class
//
// Freeware
// Copyright J Brown 2001
//
#ifndef _CARD_INCLUDED
#define _CARD_INCLUDED
enum eSuit { Clubs = 0, Diamonds = 1, Hearts = 2, Spades = 3 };
enum eValue { Ace = 1, Two = 2, Three = 3, Four = 4, Five = 5, Six = 6, Seven = 7,
Eight = 8, Nine = 9, Ten = 10, Jack = 11, Queen = 12, King = 13 };
inline int MAKE_CARD(int Value, int Suit)
{
if(Value < 1) Value = 1;
if(Value == 14) Value = 1;
if(Value > 13) Value = 13;
if(Suit < 0) Suit = 0;
if(Suit > 3) Suit = 3;
return ((Value - 1) * 4 + Suit);
}
class Card
{
friend class CardStack;
public:
Card()
{
nValue = 0; //ace of spades by default
fFaceUp = true;
}
Card(int value, int suit) //specify a face value [1-13] and suit [0-3]
{
nValue = MAKE_CARD(value, suit);
fFaceUp = true;
}
Card(int index) //specify a 0-51 index
{
if(index < 0) index = 0;
if(index > 51) index = 51;
nValue = index;
fFaceUp = true;
}
int Suit() const
{
return (nValue % 4);
}
int LoVal() const
{
return (nValue / 4) + 1;
}
int HiVal() const
{
return ((nValue < 4) ? 14 : (nValue / 4) + 1);
}
int Idx() const //unique value (0-51 etc)
{
return nValue;
}
bool FaceUp() const
{
return fFaceUp;
}
bool FaceDown() const
{
return !fFaceUp;
}
void SetFaceUp(bool fTrue)
{
fFaceUp = fTrue;
}
bool IsBlack() const
{
return Suit() == 0 || Suit() == 3;
}
bool IsRed() const
{
return !IsBlack();
}
private:
int nValue;
bool fFaceUp;
};
#endif
//
// CardLib - Card class
//
// Freeware
// Copyright J Brown 2001
//
#ifndef _CARD_INCLUDED
#define _CARD_INCLUDED
enum eSuit { Clubs = 0, Diamonds = 1, Hearts = 2, Spades = 3 };
enum eValue { Ace = 1, Two = 2, Three = 3, Four = 4, Five = 5, Six = 6, Seven = 7,
Eight = 8, Nine = 9, Ten = 10, Jack = 11, Queen = 12, King = 13 };
inline int MAKE_CARD(int Value, int Suit)
{
if(Value < 1) Value = 1;
if(Value == 14) Value = 1;
if(Value > 13) Value = 13;
if(Suit < 0) Suit = 0;
if(Suit > 3) Suit = 3;
return ((Value - 1) * 4 + Suit);
}
class Card
{
friend class CardStack;
public:
Card()
{
nValue = 0; //ace of spades by default
fFaceUp = true;
}
Card(int value, int suit) //specify a face value [1-13] and suit [0-3]
{
nValue = MAKE_CARD(value, suit);
fFaceUp = true;
}
Card(int index) //specify a 0-51 index
{
if(index < 0) index = 0;
if(index > 51) index = 51;
nValue = index;
fFaceUp = true;
}
int Suit() const
{
return (nValue % 4);
}
int LoVal() const
{
return (nValue / 4) + 1;
}
int HiVal() const
{
return ((nValue < 4) ? 14 : (nValue / 4) + 1);
}
int Idx() const //unique value (0-51 etc)
{
return nValue;
}
bool FaceUp() const
{
return fFaceUp;
}
bool FaceDown() const
{
return !fFaceUp;
}
void SetFaceUp(bool fTrue)
{
fFaceUp = fTrue;
}
bool IsBlack() const
{
return Suit() == 0 || Suit() == 3;
}
bool IsRed() const
{
return !IsBlack();
}
private:
int nValue;
bool fFaceUp;
};
#endif

View file

@ -1,281 +1,281 @@
//
// CardLib - Card bitmap support
//
// Freeware
// Copyright J Brown 2001
//
#include <windows.h>
#include "globals.h"
#include "cardcolor.h"
#ifndef __REACTOS__
#pragma comment( lib, "..\\CardLib\\cards16.lib" )
extern "C" HINSTANCE WINAPI LoadLibrary16( PSTR );
extern "C" void WINAPI FreeLibrary16( HINSTANCE );
#endif
#define NUMCARDBITMAPS (52+16)
void PaintRect(HDC hdc, RECT *rect, COLORREF col);
void LoadCardBitmapsFromLibrary(HINSTANCE hCardDll, int *pwidth, int *pheight)
{
HBITMAP hBitmap;
HDC hdcCard = NULL;
HANDLE hOld;
int i, xpos;
int width, height;
BITMAP bmp;
for(i = 0; i < NUMCARDBITMAPS; i++)
{
//convert into the range used by the cdt_xxx functions
int val;
if(i < 52) val = (i % 4) * 13 + (i/4);
else val = i;
hBitmap = LoadBitmap(hCardDll, MAKEINTRESOURCE(val + 1));
GetObject(hBitmap, sizeof(bmp), &bmp);
width = bmp.bmWidth;
height = bmp.bmHeight;
if(i == 0) //if first time through, create BIG bitmap..
{
HDC hdc = GetDC(0);
__hdcCardBitmaps = CreateCompatibleDC(hdc);
__hbmCardBitmaps = CreateCompatibleBitmap(hdc, width * NUMCARDBITMAPS, height);
SelectObject(__hdcCardBitmaps, __hbmCardBitmaps);
hdcCard = CreateCompatibleDC(0);
ReleaseDC(0, hdc);
}
hOld = SelectObject(hdcCard, hBitmap);
BitBlt(__hdcCardBitmaps, i*width, 0, width, height, hdcCard, 0, 0, SRCCOPY);
SelectObject(hdcCard, hOld);
//Now draw a black border around each card...
xpos = i*width;
MoveToEx(__hdcCardBitmaps, xpos+2, 0, 0);
LineTo(__hdcCardBitmaps, xpos+width - 3, 0);
LineTo(__hdcCardBitmaps, xpos+width - 1, 2);
LineTo(__hdcCardBitmaps, xpos+width - 1, height - 3); //vertical
LineTo(__hdcCardBitmaps, xpos+width - 3, height - 1);
LineTo(__hdcCardBitmaps, xpos+2, height - 1);
LineTo(__hdcCardBitmaps, xpos+0, height - 3);
LineTo(__hdcCardBitmaps, xpos+0, 2);
LineTo(__hdcCardBitmaps, xpos+2, 0);
DeleteObject(hBitmap);
}
DeleteDC(hdcCard);
*pwidth = width;
*pheight = height;
}
void LoadCardBitmaps(void)
{
HINSTANCE hCardDll;
//If Windows NT/2000/XP
if(GetVersion() < 0x80000000)
{
hCardDll = LoadLibrary("cards.dll");
if(hCardDll == 0)
{
MessageBox(0, "Error loading cards.dll (32bit)", "Shed", MB_OK | MB_ICONEXCLAMATION);
PostQuitMessage(0);
return;
}
LoadCardBitmapsFromLibrary(hCardDll, &__cardwidth, &__cardheight);
FreeLibrary(hCardDll);
}
#ifndef __REACTOS__
//Else, Win9X
else
{
hCardDll = LoadLibrary16("cards.dll");
if(hCardDll == 0)
{
MessageBox(0, "Error loading cards.dll (16bit)", "Shed", MB_OK | MB_ICONEXCLAMATION);
PostQuitMessage(0);
return;
}
LoadCardBitmapsFromLibrary(hCardDll, &__cardwidth, &__cardheight);
FreeLibrary16(hCardDll);
}
#endif
}
void FreeCardBitmaps()
{
DeleteObject (__hbmCardBitmaps);
DeleteDC (__hdcCardBitmaps);
}
//
// Paint a checkered rectangle, with each alternate
// pixel being assigned a different colour
//
static void DrawCheckedRect(HDC hdc, RECT *rect, COLORREF fg, COLORREF bg)
{
static WORD wCheckPat[8] =
{
0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555
};
HBITMAP hbmp;
HBRUSH hbr, hbrold;
COLORREF fgold, bgold;
hbmp = CreateBitmap(8, 8, 1, 1, wCheckPat);
hbr = CreatePatternBrush(hbmp);
//UnrealizeObject(hbr);
SetBrushOrgEx(hdc, rect->left, rect->top, 0);
hbrold = (HBRUSH)SelectObject(hdc, hbr);
fgold = SetTextColor(hdc, fg);
bgold = SetBkColor(hdc, bg);
PatBlt(hdc, rect->left, rect->top,
rect->right - rect->left,
rect->bottom - rect->top,
PATCOPY);
SetBkColor(hdc, bgold);
SetTextColor(hdc, fgold);
SelectObject(hdc, hbrold);
DeleteObject(hbr);
DeleteObject(hbmp);
}
void GetSinkCols(COLORREF crBase, COLORREF *fg, COLORREF *bg, COLORREF *sh1, COLORREF *sh2)
{
if(bg) *bg = crBase;
if(fg) *fg = ColorScaleRGB(crBase, RGB(255,255,255), 0.2);//RGB(49, 99, 140);
if(sh1) *sh1 = ColorScaleRGB(crBase, RGB(0,0,0), 0.4);
if(sh2) *sh2 = ColorScaleRGB(crBase, RGB(0,0,0), 0.2);
}
HBITMAP CreateSinkBmp(HDC hdcCompat, HDC hdc, COLORREF col, int width, int height)
{
HANDLE hold, hpold;
HBITMAP hbm = CreateCompatibleBitmap(hdcCompat, width, height);
HPEN hpfg, hpbg, hpsh, hpsh2;
RECT rect;
COLORREF fg, bg, shadow, shadow2;
GetSinkCols(col, &fg, &bg, &shadow, &shadow2);
hold = SelectObject(hdc, hbm);
//fill with a solid base colour
SetRect(&rect, 0,0,width,height);
PaintRect(hdc, &rect, MAKE_PALETTERGB(bg));
//draw the outline
hpfg = CreatePen(PS_SOLID, 0, MAKE_PALETTERGB(fg));
hpbg = CreatePen(PS_SOLID, 0, MAKE_PALETTERGB(bg));
hpsh = CreatePen(PS_SOLID, 0, MAKE_PALETTERGB(shadow));
hpsh2= CreatePen(PS_SOLID, 0, MAKE_PALETTERGB(shadow2));
hpold = SelectObject(hdc, hpsh);
MoveToEx(hdc, 2, 0, NULL);
LineTo (hdc, width-3,0);
LineTo (hdc, width-1, 2);
SelectObject(hdc, hpold);
hpold = SelectObject(hdc, hpsh2);
LineTo (hdc, width-1, height-3); //vertical
LineTo (hdc, width-3, height-1);
LineTo (hdc, 2, height-1);
LineTo (hdc, 0, height-3);
SelectObject(hdc, hpold);
hpold = SelectObject(hdc, hpsh);
//MoveToEx( hdc, 0, height-3,0);
LineTo (hdc, 0, 2);
LineTo (hdc, 2, 0);
SelectObject(hdc, hpold);
//draw the highlight (vertical)
hpold = SelectObject(hdc, hpfg);
MoveToEx(hdc, width - 2, 3, NULL);
LineTo (hdc, width - 2, height - 2);
//(horz)
MoveToEx(hdc, width - 3, height-2, NULL);
LineTo (hdc, 3, height-2);
SelectObject(hdc, hpold);
//draw the background
InflateRect(&rect, -2, -2);
DrawCheckedRect(hdc, &rect, MAKE_PALETTERGB(bg), MAKE_PALETTERGB(fg));
//overwrite the top-left background pixel
SetPixel(hdc, 2, 2, MAKE_PALETTERGB(bg));
DeleteObject(hpsh);
DeleteObject(hpsh2);
DeleteObject(hpfg);
DeleteObject(hpbg);
return hbm;
}
void CopyColor(PALETTEENTRY *pe, COLORREF col)
{
pe->peBlue = GetBValue(col);
pe->peGreen = GetGValue(col);
pe->peRed = GetRValue(col);
pe->peFlags = 0;
}
HPALETTE MakePaletteFromCols(COLORREF cols[], int nNumColours)
{
LOGPALETTE *lp;
HPALETTE hPalette;
// Allocate memory for the logical palette
lp = (LOGPALETTE *)HeapAlloc(
GetProcessHeap(), 0, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * nNumColours);
lp->palNumEntries = nNumColours;
lp->palVersion = 0x300;
//copy the colours into the logical palette format
for(int i = 0; i < nNumColours; i++)
{
CopyColor(&lp->palPalEntry[i], cols[i]);
}
// create palette!
hPalette = CreatePalette(lp);
HeapFree(GetProcessHeap(), 0, lp);
return hPalette;
}
//
// CardLib - Card bitmap support
//
// Freeware
// Copyright J Brown 2001
//
#include <windows.h>
#include "globals.h"
#include "cardcolor.h"
#ifndef __REACTOS__
#pragma comment( lib, "..\\CardLib\\cards16.lib" )
extern "C" HINSTANCE WINAPI LoadLibrary16( PSTR );
extern "C" void WINAPI FreeLibrary16( HINSTANCE );
#endif
#define NUMCARDBITMAPS (52+16)
void PaintRect(HDC hdc, RECT *rect, COLORREF col);
void LoadCardBitmapsFromLibrary(HINSTANCE hCardDll, int *pwidth, int *pheight)
{
HBITMAP hBitmap;
HDC hdcCard = NULL;
HANDLE hOld;
int i, xpos;
int width, height;
BITMAP bmp;
for(i = 0; i < NUMCARDBITMAPS; i++)
{
//convert into the range used by the cdt_xxx functions
int val;
if(i < 52) val = (i % 4) * 13 + (i/4);
else val = i;
hBitmap = LoadBitmap(hCardDll, MAKEINTRESOURCE(val + 1));
GetObject(hBitmap, sizeof(bmp), &bmp);
width = bmp.bmWidth;
height = bmp.bmHeight;
if(i == 0) //if first time through, create BIG bitmap..
{
HDC hdc = GetDC(0);
__hdcCardBitmaps = CreateCompatibleDC(hdc);
__hbmCardBitmaps = CreateCompatibleBitmap(hdc, width * NUMCARDBITMAPS, height);
SelectObject(__hdcCardBitmaps, __hbmCardBitmaps);
hdcCard = CreateCompatibleDC(0);
ReleaseDC(0, hdc);
}
hOld = SelectObject(hdcCard, hBitmap);
BitBlt(__hdcCardBitmaps, i*width, 0, width, height, hdcCard, 0, 0, SRCCOPY);
SelectObject(hdcCard, hOld);
//Now draw a black border around each card...
xpos = i*width;
MoveToEx(__hdcCardBitmaps, xpos+2, 0, 0);
LineTo(__hdcCardBitmaps, xpos+width - 3, 0);
LineTo(__hdcCardBitmaps, xpos+width - 1, 2);
LineTo(__hdcCardBitmaps, xpos+width - 1, height - 3); //vertical
LineTo(__hdcCardBitmaps, xpos+width - 3, height - 1);
LineTo(__hdcCardBitmaps, xpos+2, height - 1);
LineTo(__hdcCardBitmaps, xpos+0, height - 3);
LineTo(__hdcCardBitmaps, xpos+0, 2);
LineTo(__hdcCardBitmaps, xpos+2, 0);
DeleteObject(hBitmap);
}
DeleteDC(hdcCard);
*pwidth = width;
*pheight = height;
}
void LoadCardBitmaps(void)
{
HINSTANCE hCardDll;
//If Windows NT/2000/XP
if(GetVersion() < 0x80000000)
{
hCardDll = LoadLibrary("cards.dll");
if(hCardDll == 0)
{
MessageBox(0, "Error loading cards.dll (32bit)", "Shed", MB_OK | MB_ICONEXCLAMATION);
PostQuitMessage(0);
return;
}
LoadCardBitmapsFromLibrary(hCardDll, &__cardwidth, &__cardheight);
FreeLibrary(hCardDll);
}
#ifndef __REACTOS__
//Else, Win9X
else
{
hCardDll = LoadLibrary16("cards.dll");
if(hCardDll == 0)
{
MessageBox(0, "Error loading cards.dll (16bit)", "Shed", MB_OK | MB_ICONEXCLAMATION);
PostQuitMessage(0);
return;
}
LoadCardBitmapsFromLibrary(hCardDll, &__cardwidth, &__cardheight);
FreeLibrary16(hCardDll);
}
#endif
}
void FreeCardBitmaps()
{
DeleteObject (__hbmCardBitmaps);
DeleteDC (__hdcCardBitmaps);
}
//
// Paint a checkered rectangle, with each alternate
// pixel being assigned a different colour
//
static void DrawCheckedRect(HDC hdc, RECT *rect, COLORREF fg, COLORREF bg)
{
static WORD wCheckPat[8] =
{
0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555
};
HBITMAP hbmp;
HBRUSH hbr, hbrold;
COLORREF fgold, bgold;
hbmp = CreateBitmap(8, 8, 1, 1, wCheckPat);
hbr = CreatePatternBrush(hbmp);
//UnrealizeObject(hbr);
SetBrushOrgEx(hdc, rect->left, rect->top, 0);
hbrold = (HBRUSH)SelectObject(hdc, hbr);
fgold = SetTextColor(hdc, fg);
bgold = SetBkColor(hdc, bg);
PatBlt(hdc, rect->left, rect->top,
rect->right - rect->left,
rect->bottom - rect->top,
PATCOPY);
SetBkColor(hdc, bgold);
SetTextColor(hdc, fgold);
SelectObject(hdc, hbrold);
DeleteObject(hbr);
DeleteObject(hbmp);
}
void GetSinkCols(COLORREF crBase, COLORREF *fg, COLORREF *bg, COLORREF *sh1, COLORREF *sh2)
{
if(bg) *bg = crBase;
if(fg) *fg = ColorScaleRGB(crBase, RGB(255,255,255), 0.2);//RGB(49, 99, 140);
if(sh1) *sh1 = ColorScaleRGB(crBase, RGB(0,0,0), 0.4);
if(sh2) *sh2 = ColorScaleRGB(crBase, RGB(0,0,0), 0.2);
}
HBITMAP CreateSinkBmp(HDC hdcCompat, HDC hdc, COLORREF col, int width, int height)
{
HANDLE hold, hpold;
HBITMAP hbm = CreateCompatibleBitmap(hdcCompat, width, height);
HPEN hpfg, hpbg, hpsh, hpsh2;
RECT rect;
COLORREF fg, bg, shadow, shadow2;
GetSinkCols(col, &fg, &bg, &shadow, &shadow2);
hold = SelectObject(hdc, hbm);
//fill with a solid base colour
SetRect(&rect, 0,0,width,height);
PaintRect(hdc, &rect, MAKE_PALETTERGB(bg));
//draw the outline
hpfg = CreatePen(PS_SOLID, 0, MAKE_PALETTERGB(fg));
hpbg = CreatePen(PS_SOLID, 0, MAKE_PALETTERGB(bg));
hpsh = CreatePen(PS_SOLID, 0, MAKE_PALETTERGB(shadow));
hpsh2= CreatePen(PS_SOLID, 0, MAKE_PALETTERGB(shadow2));
hpold = SelectObject(hdc, hpsh);
MoveToEx(hdc, 2, 0, NULL);
LineTo (hdc, width-3,0);
LineTo (hdc, width-1, 2);
SelectObject(hdc, hpold);
hpold = SelectObject(hdc, hpsh2);
LineTo (hdc, width-1, height-3); //vertical
LineTo (hdc, width-3, height-1);
LineTo (hdc, 2, height-1);
LineTo (hdc, 0, height-3);
SelectObject(hdc, hpold);
hpold = SelectObject(hdc, hpsh);
//MoveToEx( hdc, 0, height-3,0);
LineTo (hdc, 0, 2);
LineTo (hdc, 2, 0);
SelectObject(hdc, hpold);
//draw the highlight (vertical)
hpold = SelectObject(hdc, hpfg);
MoveToEx(hdc, width - 2, 3, NULL);
LineTo (hdc, width - 2, height - 2);
//(horz)
MoveToEx(hdc, width - 3, height-2, NULL);
LineTo (hdc, 3, height-2);
SelectObject(hdc, hpold);
//draw the background
InflateRect(&rect, -2, -2);
DrawCheckedRect(hdc, &rect, MAKE_PALETTERGB(bg), MAKE_PALETTERGB(fg));
//overwrite the top-left background pixel
SetPixel(hdc, 2, 2, MAKE_PALETTERGB(bg));
DeleteObject(hpsh);
DeleteObject(hpsh2);
DeleteObject(hpfg);
DeleteObject(hpbg);
return hbm;
}
void CopyColor(PALETTEENTRY *pe, COLORREF col)
{
pe->peBlue = GetBValue(col);
pe->peGreen = GetGValue(col);
pe->peRed = GetRValue(col);
pe->peFlags = 0;
}
HPALETTE MakePaletteFromCols(COLORREF cols[], int nNumColours)
{
LOGPALETTE *lp;
HPALETTE hPalette;
// Allocate memory for the logical palette
lp = (LOGPALETTE *)HeapAlloc(
GetProcessHeap(), 0, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * nNumColours);
lp->palNumEntries = nNumColours;
lp->palVersion = 0x300;
//copy the colours into the logical palette format
for(int i = 0; i < nNumColours; i++)
{
CopyColor(&lp->palPalEntry[i], cols[i]);
}
// create palette!
hPalette = CreatePalette(lp);
HeapFree(GetProcessHeap(), 0, lp);
return hPalette;
}

View file

@ -1,489 +1,489 @@
//
// CardLib - CardButton class
//
// Freeware
// Copyright J Brown 2001
//
#include <windows.h>
#include <tchar.h>
#include "cardlib.h"
#include "cardwindow.h"
#include "cardbutton.h"
#include "cardcolor.h"
HPALETTE UseNicePalette(HDC, HPALETTE);
void RestorePalette(HDC, HPALETTE);
void PaintRect(HDC hdc, RECT *rect, COLORREF colour);
CardButton::CardButton(CardWindow &parent, int Id, TCHAR *szText, UINT Style, bool visible,
int x, int y, int width, int height)
: parentWnd(parent), id(Id), uStyle(Style), fVisible(visible), ButtonCallback(0)
{
crText = RGB(255,255,255);
crBack = RGB(0, 128, 0);
xadjust = 0;
yadjust = 0;
xjustify = 0;
yjustify = 0;
fMouseDown = false;
fButtonDown = false;
hIcon = 0;
SetText(szText);
Move(x, y, width, height);
mxlock = CreateMutex(0, FALSE, 0);
hFont = 0;
}
CardButton::~CardButton()
{
CloseHandle(mxlock);
}
void CardButton::DrawRect(HDC hdc, RECT *rect, bool fNormal)
{
RECT fill;
HANDLE hOld;
HPEN hhi = CreatePen(0, 0, MAKE_PALETTERGB(crHighlight));
HPEN hsh = CreatePen(0, 0, MAKE_PALETTERGB(crShadow));
HPEN hbl = (HPEN)GetStockObject(BLACK_PEN);
int x = rect->left;
int y = rect->top;
int width = rect->right-rect->left - 1;
int height = rect->bottom-rect->top - 1;
SetRect(&fill, x+1, y+1, x+width-1, y+height-1);
int one = 1;
if(!fNormal)
{
x += width;
y += height;
width = -width;
height = -height;
one = -1;
OffsetRect(&fill, 1, 1);
}
if(fNormal)
hOld = SelectObject(hdc, hhi);
else
hOld = SelectObject(hdc, hhi);
MoveToEx(hdc, x, y+height, 0);
LineTo(hdc, x, y);
LineTo(hdc, x+width, y);
SelectObject(hdc, hOld);
hOld = SelectObject(hdc, hbl);
LineTo(hdc, x+width, y+height);
LineTo(hdc, x-one, y+height);
SelectObject(hdc, hOld);
hOld = SelectObject(hdc, hsh);
MoveToEx(hdc, x+one, y+height-one, 0);
LineTo(hdc, x+width-one, y+height-one);
LineTo(hdc, x+width-one, y);
SelectObject(hdc, hOld);
PaintRect(hdc, &fill, MAKE_PALETTERGB(crBack));
DeleteObject(hhi);
DeleteObject(hsh);
}
void CardButton::Clip(HDC hdc)
{
if(fVisible == false) return;
ExcludeClipRect(hdc, rect.left, rect.top, rect.right, rect.bottom);
}
void CardButton::Draw(HDC hdc, bool fNormal)
{
SIZE textsize;
int x, y; //text x, y
int ix, iy; //icon x, y
int iconwidth = 0;
RECT cliprect;
if(fVisible == 0) return;
if(hFont == 0)
SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));
else
SelectObject(hdc, hFont);
GetTextExtentPoint32(hdc, szText, lstrlen(szText), &textsize);
if(hIcon)
{
x = rect.left + 32 + 8;
}
else
{
if(uStyle & CB_ALIGN_LEFT)
{
x = rect.left + iconwidth;
}
else if(uStyle & CB_ALIGN_RIGHT)
{
x = rect.left + (rect.right-rect.left-iconwidth-textsize.cx);
}
else //centered
{
x = rect.right - rect.left - iconwidth;
x = (x - textsize.cx) / 2;
x += rect.left + iconwidth;
}
}
y = rect.bottom - rect.top;
y = (y - textsize.cy) / 2;
y += rect.top;
//calc icon position..
ix = rect.left + 4;
iy = rect.top + (rect.bottom-rect.top-32) / 2;
//if button is pressed, then shift text
if(fNormal == false && (uStyle & CB_PUSHBUTTON))
{
x += 1;
y += 1;
ix += 1;
iy += 1;
}
SetRect(&cliprect, x, y, x+textsize.cx, y+textsize.cy);
ExcludeClipRect(hdc, x, y, x+textsize.cx, y+textsize.cy);
//
// Calc icon pos
//
if(hIcon)
{
ExcludeClipRect(hdc, ix, iy, ix + 32, iy + 32);
}
if(uStyle & CB_PUSHBUTTON)
{
DrawRect(hdc, &rect, fNormal);
SetBkColor(hdc, MAKE_PALETTERGB(crBack));
SetTextColor(hdc, crText);//MAKE_PALETTERGB(crText));
SelectClipRgn(hdc, 0);
ExtTextOut(hdc, x, y, ETO_OPAQUE, &cliprect, szText, lstrlen(szText), 0);
}
else
{
SetBkColor(hdc, MAKE_PALETTERGB(crBack));
SetTextColor(hdc, crText);//MAKE_PALETTERGB(crText));
SelectClipRgn(hdc, 0);
ExtTextOut(hdc, x, y, ETO_OPAQUE, &rect, szText, lstrlen(szText), 0);
}
if(hIcon)
{
HBRUSH hbr = CreateSolidBrush(MAKE_PALETTERGB(crBack));
DrawIconEx(hdc, ix, iy, hIcon, 32, 32, 0, hbr, 0);
DeleteObject(hbr);
}
}
void CardButton::AdjustPosition(int winwidth, int winheight)
{
int width = rect.right-rect.left;
int height = rect.bottom-rect.top;
width = width & ~0x1;
switch(xjustify)
{
case CS_XJUST_NONE:
break;
case CS_XJUST_CENTER: //centered
rect.left = (winwidth - (width)) / 2;
rect.left += xadjust;
rect.right = rect.left+width;
break;
case CS_XJUST_RIGHT: //right-aligned
rect.left = winwidth - width;
rect.left += xadjust;
rect.right = rect.left+width;
break;
}
switch(yjustify)
{
case CS_YJUST_NONE:
break;
case CS_YJUST_CENTER: //centered
rect.top = (winheight - (height)) / 2;
rect.top += yadjust;
rect.bottom = rect.top+height;
break;
case CS_YJUST_BOTTOM: //right-aligned
rect.top = winheight - height;
rect.top += yadjust;
rect.bottom = rect.top+height;
break;
}
}
int CardButton::OnLButtonDown(HWND hwnd, int x, int y)
{
if((uStyle & CB_PUSHBUTTON) == 0)
return 0;
//make sure that the user is allowed to do something
if(WaitForSingleObject(mxlock, 0) != WAIT_OBJECT_0)
{
return 0;
}
else
{
ReleaseMutex(mxlock);
}
fMouseDown = true;
fButtonDown = true;
Redraw();
SetCapture(hwnd);
return 1;
}
int CardButton::OnMouseMove(HWND hwnd, int x, int y)
{
if(fMouseDown)
{
bool fOldButtonDown = fButtonDown;
POINT pt;
pt.x = x;
pt.y = y;
if(PtInRect(&rect, pt))
fButtonDown = true;
else
fButtonDown = false;
if(fButtonDown != fOldButtonDown)
Redraw();
}
return 0;
}
int CardButton::OnLButtonUp(HWND hwnd, int x, int y)
{
if(fMouseDown)
{
fMouseDown = false;
fButtonDown = false;
if(uStyle & CB_PUSHBUTTON)
{
Redraw();
ReleaseCapture();
}
//if have clicked the button
if(parentWnd.CardButtonFromPoint(x, y) == this)
{
if(ButtonCallback)
{
ButtonCallback(*this);
}
else
{
HWND hwnd = (HWND)parentWnd;
SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(id, BN_CLICKED), (LONG)hwnd);
}
}
}
return 0;
}
#define _countof(array) (sizeof(array)/sizeof(array[0]))
CardButton *CardWindow::CreateButton(int id, TCHAR *szText, UINT uStyle, bool fVisible, int x, int y, int width, int height)
{
CardButton *cb;
if(nNumButtons == MAXBUTTONS)
return 0;
cb = new CardButton(*this, id, szText, uStyle, fVisible, x, y, width, height);
Buttons[nNumButtons++] = cb;
if(uStyle & CB_PUSHBUTTON)
{
cb->SetBackColor(CardButton::GetFace(crBackgnd));
//cb->SetBackColor(ScaleLumRGB(crBackgnd, 0.1));
cb->SetForeColor(RGB(255,255,255));
}
else
{
cb->SetBackColor(crBackgnd);
cb->SetForeColor(RGB(255,255,255));
}
return cb;
}
void CardButton::SetText(TCHAR *lpszFormat, ...)
{
int count;
va_list args;
va_start(args, lpszFormat);
count = wvsprintf(szText, lpszFormat, args);
va_end(args);
}
int CardButton::Id()
{
return id;
}
void CardButton::Show(bool fShow)
{
fVisible = fShow;
}
void CardButton::Move(int x, int y, int width, int height)
{
SetRect(&rect, x, y, x+width, y+height);
}
void CardButton::Redraw()
{
HDC hdc = GetDC((HWND)parentWnd);
HPALETTE hOldPal = UseNicePalette(hdc, __hPalette);
Draw(hdc, !fButtonDown);
RestorePalette(hdc, hOldPal);
ReleaseDC((HWND)parentWnd, hdc);
}
void CardButton::SetForeColor(COLORREF cr)
{
crText = cr;
}
void CardButton::SetBackColor(COLORREF cr)
{
crBack = cr;
crHighlight = GetHighlight(cr);
crShadow = GetShadow(cr);
//crHighlight = ScaleLumRGB(cr, +0.25);
//crShadow = ScaleLumRGB(cr, -0.25);
}
// Static member
COLORREF CardButton::GetHighlight(COLORREF crBase)
{
return ColorScaleRGB(crBase, RGB(255,255,255), 0.25);
}
// Static member
COLORREF CardButton::GetShadow(COLORREF crBase)
{
return ColorScaleRGB(crBase, RGB(0, 0, 0), 0.25);
}
COLORREF CardButton::GetFace(COLORREF crBase)
{
return ColorScaleRGB(crBase, RGB(255,255,255), 0.1);
}
void CardButton::SetPlacement(UINT xJustify, UINT yJustify, int xAdjust, int yAdjust)
{
xadjust = xAdjust;
yadjust = yAdjust;
xjustify = xJustify;
yjustify = yJustify;
}
void CardButton::SetIcon(HICON hicon, bool fRedraw)
{
hIcon = hicon;
if(fRedraw)
Redraw();
}
void CardButton::SetFont(HFONT font)
{
//don't delete the existing font..
hFont = font;
}
void CardButton::SetButtonProc(pButtonProc proc)
{
ButtonCallback = proc;
}
bool CardButton::Lock()
{
DWORD dw = WaitForSingleObject(mxlock, 0);
if(dw == WAIT_OBJECT_0)
return true;
else
return false;
}
bool CardButton::UnLock()
{
if(ReleaseMutex(mxlock))
return true;
else
return false;
}
void CardButton::SetStyle(UINT style)
{
uStyle = style;
}
UINT CardButton::GetStyle()
{
return uStyle;
}
//
// CardLib - CardButton class
//
// Freeware
// Copyright J Brown 2001
//
#include <windows.h>
#include <tchar.h>
#include "cardlib.h"
#include "cardwindow.h"
#include "cardbutton.h"
#include "cardcolor.h"
HPALETTE UseNicePalette(HDC, HPALETTE);
void RestorePalette(HDC, HPALETTE);
void PaintRect(HDC hdc, RECT *rect, COLORREF colour);
CardButton::CardButton(CardWindow &parent, int Id, TCHAR *szText, UINT Style, bool visible,
int x, int y, int width, int height)
: parentWnd(parent), id(Id), uStyle(Style), fVisible(visible), ButtonCallback(0)
{
crText = RGB(255,255,255);
crBack = RGB(0, 128, 0);
xadjust = 0;
yadjust = 0;
xjustify = 0;
yjustify = 0;
fMouseDown = false;
fButtonDown = false;
hIcon = 0;
SetText(szText);
Move(x, y, width, height);
mxlock = CreateMutex(0, FALSE, 0);
hFont = 0;
}
CardButton::~CardButton()
{
CloseHandle(mxlock);
}
void CardButton::DrawRect(HDC hdc, RECT *rect, bool fNormal)
{
RECT fill;
HANDLE hOld;
HPEN hhi = CreatePen(0, 0, MAKE_PALETTERGB(crHighlight));
HPEN hsh = CreatePen(0, 0, MAKE_PALETTERGB(crShadow));
HPEN hbl = (HPEN)GetStockObject(BLACK_PEN);
int x = rect->left;
int y = rect->top;
int width = rect->right-rect->left - 1;
int height = rect->bottom-rect->top - 1;
SetRect(&fill, x+1, y+1, x+width-1, y+height-1);
int one = 1;
if(!fNormal)
{
x += width;
y += height;
width = -width;
height = -height;
one = -1;
OffsetRect(&fill, 1, 1);
}
if(fNormal)
hOld = SelectObject(hdc, hhi);
else
hOld = SelectObject(hdc, hhi);
MoveToEx(hdc, x, y+height, 0);
LineTo(hdc, x, y);
LineTo(hdc, x+width, y);
SelectObject(hdc, hOld);
hOld = SelectObject(hdc, hbl);
LineTo(hdc, x+width, y+height);
LineTo(hdc, x-one, y+height);
SelectObject(hdc, hOld);
hOld = SelectObject(hdc, hsh);
MoveToEx(hdc, x+one, y+height-one, 0);
LineTo(hdc, x+width-one, y+height-one);
LineTo(hdc, x+width-one, y);
SelectObject(hdc, hOld);
PaintRect(hdc, &fill, MAKE_PALETTERGB(crBack));
DeleteObject(hhi);
DeleteObject(hsh);
}
void CardButton::Clip(HDC hdc)
{
if(fVisible == false) return;
ExcludeClipRect(hdc, rect.left, rect.top, rect.right, rect.bottom);
}
void CardButton::Draw(HDC hdc, bool fNormal)
{
SIZE textsize;
int x, y; //text x, y
int ix, iy; //icon x, y
int iconwidth = 0;
RECT cliprect;
if(fVisible == 0) return;
if(hFont == 0)
SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));
else
SelectObject(hdc, hFont);
GetTextExtentPoint32(hdc, szText, lstrlen(szText), &textsize);
if(hIcon)
{
x = rect.left + 32 + 8;
}
else
{
if(uStyle & CB_ALIGN_LEFT)
{
x = rect.left + iconwidth;
}
else if(uStyle & CB_ALIGN_RIGHT)
{
x = rect.left + (rect.right-rect.left-iconwidth-textsize.cx);
}
else //centered
{
x = rect.right - rect.left - iconwidth;
x = (x - textsize.cx) / 2;
x += rect.left + iconwidth;
}
}
y = rect.bottom - rect.top;
y = (y - textsize.cy) / 2;
y += rect.top;
//calc icon position..
ix = rect.left + 4;
iy = rect.top + (rect.bottom-rect.top-32) / 2;
//if button is pressed, then shift text
if(fNormal == false && (uStyle & CB_PUSHBUTTON))
{
x += 1;
y += 1;
ix += 1;
iy += 1;
}
SetRect(&cliprect, x, y, x+textsize.cx, y+textsize.cy);
ExcludeClipRect(hdc, x, y, x+textsize.cx, y+textsize.cy);
//
// Calc icon pos
//
if(hIcon)
{
ExcludeClipRect(hdc, ix, iy, ix + 32, iy + 32);
}
if(uStyle & CB_PUSHBUTTON)
{
DrawRect(hdc, &rect, fNormal);
SetBkColor(hdc, MAKE_PALETTERGB(crBack));
SetTextColor(hdc, crText);//MAKE_PALETTERGB(crText));
SelectClipRgn(hdc, 0);
ExtTextOut(hdc, x, y, ETO_OPAQUE, &cliprect, szText, lstrlen(szText), 0);
}
else
{
SetBkColor(hdc, MAKE_PALETTERGB(crBack));
SetTextColor(hdc, crText);//MAKE_PALETTERGB(crText));
SelectClipRgn(hdc, 0);
ExtTextOut(hdc, x, y, ETO_OPAQUE, &rect, szText, lstrlen(szText), 0);
}
if(hIcon)
{
HBRUSH hbr = CreateSolidBrush(MAKE_PALETTERGB(crBack));
DrawIconEx(hdc, ix, iy, hIcon, 32, 32, 0, hbr, 0);
DeleteObject(hbr);
}
}
void CardButton::AdjustPosition(int winwidth, int winheight)
{
int width = rect.right-rect.left;
int height = rect.bottom-rect.top;
width = width & ~0x1;
switch(xjustify)
{
case CS_XJUST_NONE:
break;
case CS_XJUST_CENTER: //centered
rect.left = (winwidth - (width)) / 2;
rect.left += xadjust;
rect.right = rect.left+width;
break;
case CS_XJUST_RIGHT: //right-aligned
rect.left = winwidth - width;
rect.left += xadjust;
rect.right = rect.left+width;
break;
}
switch(yjustify)
{
case CS_YJUST_NONE:
break;
case CS_YJUST_CENTER: //centered
rect.top = (winheight - (height)) / 2;
rect.top += yadjust;
rect.bottom = rect.top+height;
break;
case CS_YJUST_BOTTOM: //right-aligned
rect.top = winheight - height;
rect.top += yadjust;
rect.bottom = rect.top+height;
break;
}
}
int CardButton::OnLButtonDown(HWND hwnd, int x, int y)
{
if((uStyle & CB_PUSHBUTTON) == 0)
return 0;
//make sure that the user is allowed to do something
if(WaitForSingleObject(mxlock, 0) != WAIT_OBJECT_0)
{
return 0;
}
else
{
ReleaseMutex(mxlock);
}
fMouseDown = true;
fButtonDown = true;
Redraw();
SetCapture(hwnd);
return 1;
}
int CardButton::OnMouseMove(HWND hwnd, int x, int y)
{
if(fMouseDown)
{
bool fOldButtonDown = fButtonDown;
POINT pt;
pt.x = x;
pt.y = y;
if(PtInRect(&rect, pt))
fButtonDown = true;
else
fButtonDown = false;
if(fButtonDown != fOldButtonDown)
Redraw();
}
return 0;
}
int CardButton::OnLButtonUp(HWND hwnd, int x, int y)
{
if(fMouseDown)
{
fMouseDown = false;
fButtonDown = false;
if(uStyle & CB_PUSHBUTTON)
{
Redraw();
ReleaseCapture();
}
//if have clicked the button
if(parentWnd.CardButtonFromPoint(x, y) == this)
{
if(ButtonCallback)
{
ButtonCallback(*this);
}
else
{
HWND hwnd = (HWND)parentWnd;
SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(id, BN_CLICKED), (LONG)hwnd);
}
}
}
return 0;
}
#define _countof(array) (sizeof(array)/sizeof(array[0]))
CardButton *CardWindow::CreateButton(int id, TCHAR *szText, UINT uStyle, bool fVisible, int x, int y, int width, int height)
{
CardButton *cb;
if(nNumButtons == MAXBUTTONS)
return 0;
cb = new CardButton(*this, id, szText, uStyle, fVisible, x, y, width, height);
Buttons[nNumButtons++] = cb;
if(uStyle & CB_PUSHBUTTON)
{
cb->SetBackColor(CardButton::GetFace(crBackgnd));
//cb->SetBackColor(ScaleLumRGB(crBackgnd, 0.1));
cb->SetForeColor(RGB(255,255,255));
}
else
{
cb->SetBackColor(crBackgnd);
cb->SetForeColor(RGB(255,255,255));
}
return cb;
}
void CardButton::SetText(TCHAR *lpszFormat, ...)
{
int count;
va_list args;
va_start(args, lpszFormat);
count = wvsprintf(szText, lpszFormat, args);
va_end(args);
}
int CardButton::Id()
{
return id;
}
void CardButton::Show(bool fShow)
{
fVisible = fShow;
}
void CardButton::Move(int x, int y, int width, int height)
{
SetRect(&rect, x, y, x+width, y+height);
}
void CardButton::Redraw()
{
HDC hdc = GetDC((HWND)parentWnd);
HPALETTE hOldPal = UseNicePalette(hdc, __hPalette);
Draw(hdc, !fButtonDown);
RestorePalette(hdc, hOldPal);
ReleaseDC((HWND)parentWnd, hdc);
}
void CardButton::SetForeColor(COLORREF cr)
{
crText = cr;
}
void CardButton::SetBackColor(COLORREF cr)
{
crBack = cr;
crHighlight = GetHighlight(cr);
crShadow = GetShadow(cr);
//crHighlight = ScaleLumRGB(cr, +0.25);
//crShadow = ScaleLumRGB(cr, -0.25);
}
// Static member
COLORREF CardButton::GetHighlight(COLORREF crBase)
{
return ColorScaleRGB(crBase, RGB(255,255,255), 0.25);
}
// Static member
COLORREF CardButton::GetShadow(COLORREF crBase)
{
return ColorScaleRGB(crBase, RGB(0, 0, 0), 0.25);
}
COLORREF CardButton::GetFace(COLORREF crBase)
{
return ColorScaleRGB(crBase, RGB(255,255,255), 0.1);
}
void CardButton::SetPlacement(UINT xJustify, UINT yJustify, int xAdjust, int yAdjust)
{
xadjust = xAdjust;
yadjust = yAdjust;
xjustify = xJustify;
yjustify = yJustify;
}
void CardButton::SetIcon(HICON hicon, bool fRedraw)
{
hIcon = hicon;
if(fRedraw)
Redraw();
}
void CardButton::SetFont(HFONT font)
{
//don't delete the existing font..
hFont = font;
}
void CardButton::SetButtonProc(pButtonProc proc)
{
ButtonCallback = proc;
}
bool CardButton::Lock()
{
DWORD dw = WaitForSingleObject(mxlock, 0);
if(dw == WAIT_OBJECT_0)
return true;
else
return false;
}
bool CardButton::UnLock()
{
if(ReleaseMutex(mxlock))
return true;
else
return false;
}
void CardButton::SetStyle(UINT style)
{
uStyle = style;
}
UINT CardButton::GetStyle()
{
return uStyle;
}

View file

@ -1,101 +1,101 @@
#ifndef CARDBUTTON_INCLUDED
#define CARDBUTTON_INCLUDED
#define MAXBUTTONTEXT 64
#include "cardlib.h"
class CardButton
{
friend class CardWindow;
//
// Constructor is PRIVATE - only a
// CardWindow can create buttons!
//
CardButton(CardWindow &parent, int id, TCHAR *szText, UINT style, bool visible,
int x, int y, int width, int height);
~CardButton();
public:
void SetStyle(UINT uStyle);
UINT GetStyle();
void SetText(TCHAR *fmt, ...);
void SetFont(HFONT font);
void SetPlacement(UINT xJustify, UINT yJustify, int xAdjust, int yAdjust);
void SetForeColor(COLORREF cr);
void SetBackColor(COLORREF cr);
void Move(int x, int y, int width, int height);
void Show(bool fShow);
void Redraw();
int Id();
void SetIcon(HICON hicon, bool fRedraw);
void SetButtonProc(pButtonProc proc);
CardWindow &GetCardWindow() { return parentWnd; }
bool Lock();
bool UnLock();
static COLORREF GetHighlight(COLORREF crBase);
static COLORREF GetShadow(COLORREF crBase);
static COLORREF GetFace(COLORREF crBase);
private:
//
// Private member functions
//
void AdjustPosition(int winwidth, int winheight);
void DrawRect(HDC hdc, RECT *rect, bool fNormal);
void Draw(HDC hdc, bool fNormal);
void Clip(HDC hdc);
int OnLButtonDown(HWND hwnd, int x, int y);
int OnMouseMove(HWND hwnd, int x, int y);
int OnLButtonUp(HWND hwnd, int x, int y);
//
// Private members
//
CardWindow &parentWnd;
RECT rect;
int id;
UINT uStyle;
bool fVisible;
int xadjust;
int xjustify;
int yadjust;
int yjustify;
HICON hIcon;
HFONT hFont;
TCHAR szText[MAXBUTTONTEXT];
COLORREF crBack;
COLORREF crText;
COLORREF crHighlight;
COLORREF crShadow;
COLORREF crShadow2;
bool fMouseDown;
bool fButtonDown;
HANDLE mxlock;
pButtonProc ButtonCallback;
};
#endif
#ifndef CARDBUTTON_INCLUDED
#define CARDBUTTON_INCLUDED
#define MAXBUTTONTEXT 64
#include "cardlib.h"
class CardButton
{
friend class CardWindow;
//
// Constructor is PRIVATE - only a
// CardWindow can create buttons!
//
CardButton(CardWindow &parent, int id, TCHAR *szText, UINT style, bool visible,
int x, int y, int width, int height);
~CardButton();
public:
void SetStyle(UINT uStyle);
UINT GetStyle();
void SetText(TCHAR *fmt, ...);
void SetFont(HFONT font);
void SetPlacement(UINT xJustify, UINT yJustify, int xAdjust, int yAdjust);
void SetForeColor(COLORREF cr);
void SetBackColor(COLORREF cr);
void Move(int x, int y, int width, int height);
void Show(bool fShow);
void Redraw();
int Id();
void SetIcon(HICON hicon, bool fRedraw);
void SetButtonProc(pButtonProc proc);
CardWindow &GetCardWindow() { return parentWnd; }
bool Lock();
bool UnLock();
static COLORREF GetHighlight(COLORREF crBase);
static COLORREF GetShadow(COLORREF crBase);
static COLORREF GetFace(COLORREF crBase);
private:
//
// Private member functions
//
void AdjustPosition(int winwidth, int winheight);
void DrawRect(HDC hdc, RECT *rect, bool fNormal);
void Draw(HDC hdc, bool fNormal);
void Clip(HDC hdc);
int OnLButtonDown(HWND hwnd, int x, int y);
int OnMouseMove(HWND hwnd, int x, int y);
int OnLButtonUp(HWND hwnd, int x, int y);
//
// Private members
//
CardWindow &parentWnd;
RECT rect;
int id;
UINT uStyle;
bool fVisible;
int xadjust;
int xjustify;
int yadjust;
int yjustify;
HICON hIcon;
HFONT hFont;
TCHAR szText[MAXBUTTONTEXT];
COLORREF crBack;
COLORREF crText;
COLORREF crHighlight;
COLORREF crShadow;
COLORREF crShadow2;
bool fMouseDown;
bool fButtonDown;
HANDLE mxlock;
pButtonProc ButtonCallback;
};
#endif

View file

@ -1,337 +1,337 @@
//
// Colour support
//
#include <windows.h>
#define MakeRGB RGB
#define MIN3(a,b,c) ( (a)<=(b) ? (a)<=(c)?(a):(c) : (b)<=(c)?(b):(c) )
#define MAX3(a,b,c) ( (a)>=(b) ? (a)>=(c)?(a):(c) : (b)>=(c)?(b):(c) )
inline double fMax(double a, double b)
{
return a < b ? b : a;
}
inline double fMin(double a, double b)
{
return a < b ? a : b;
}
/******************************************************************************
FUNCTION: RGBtoHLS
PURPOSE: Convert from RGB to HLS
IN: RGB color (0xBBGGRR)
OUT: Hue, Saturation, Luminance from 0 to 1
COPYRIGHT:1995-1997 Robert Mashlan
Modified for LabWindows/CVI, 1999 Guillaume Dargaud
******************************************************************************/
void RGBtoHLS(const COLORREF rgb, double *H, double *L, double *S )
{
double delta;
double r = (double)((rgb )&0xFF)/255;
double g = (double)((rgb>> 8)&0xFF)/255;
double b = (double)((rgb>>16)&0xFF)/255;
double cmax = MAX3(r,g,b);
double cmin = MIN3(r,g,b);
*L=(cmax+cmin)/2.0;
if(cmax == cmin)
{
*S = *H = 0; // it's really undefined
}
else
{
if(*L < 0.5) *S = (cmax-cmin)/(cmax+cmin);
else *S = (cmax-cmin)/(2.0-cmax-cmin);
delta = cmax - cmin;
if(r == cmax)
{
*H = (g - b) / delta;
}
else
{
if(g == cmax) *H = 2.0 + (b-r) / delta;
else *H = 4.0 + (r-g) / delta;
}
*H /= 6.0;
if (*H < 0.0) *H += 1;
}
}
/******************************************************************************
FUNCTION: HueToRGB
PURPOSE: Convert a hue (color) to RGB
COPYRIGHT:1995-1997 Robert Mashlan
Modified for LabWindows/CVI, 1999 Guillaume Dargaud
******************************************************************************/
double HueToRGB(const double m1, const double m2, double h )
{
if (h<0) h+=1.0;
if (h>1) h-=1.0;
if (6.0*h < 1 ) return (m1+(m2-m1)*h*6.0);
if (2.0*h < 1 ) return m2;
if (3.0*h < 2.0) return (m1+(m2-m1)*((2.0/3.0)-h)*6.0);
return m1;
}
/******************************************************************************
FUNCTION: HLStoRGB
PURPOSE: Convert from HSL to RGB
IN: Hue, Saturation, Luminance from 0 to 1
RETURN: RGB color (0xBBGGRR)
COPYRIGHT:1995-1997 Robert Mashlan
Modified for LabWindows/CVI, 1999 Guillaume Dargaud
******************************************************************************/
COLORREF HLStoRGB(const double H, const double L, const double S )
{
double r,g,b;
double m1, m2;
if(S == 0)
{
r = g = b = L;
}
else
{
if (L <= 0.5)
m2 = L * (1.0 + S);
else
m2 = L + S - L * S;
m1 = 2.0 * L - m2;
r = HueToRGB(m1,m2,H+1.0/3.0);
g = HueToRGB(m1,m2,H);
b = HueToRGB(m1,m2,H-1.0/3.0);
}
return RGB(r*255, g*255, b*255);
}
/******************************************************************************
FUNCTION: ColorScaleHSL
PURPOSE: Returns the HSL linear interpolated color between 2 colors
(more natural looking than RGB interpolation)
For instance if the luminance is the same in Col1 and Col2,
then the luminance of the result will be the same
If Ratio=0, you get Col1,
If Ratio=1, you get Col2
IN: Col1: low color in hex 0xBBGGRR format
Col2: high color in hex 0xBBGGRR format
Ratio: 0 for low color, 1 for high color, or in between
EXAMPLE: Col1=0, Col2=0xFF00FF, Ratio=0.5 returns 0x1F5F3F
******************************************************************************/
COLORREF ColorScaleHSL( const COLORREF Col1, const COLORREF Col2, const double Ratio)
{
static double H1, H2, S1, S2, L1, L2;
if (Ratio<=0) return Col1; // Ratio parameter must be between 0 and 1
else if (Ratio>=1) return Col2;
RGBtoHLS( Col1, &H1, &L1, &S1);
RGBtoHLS( Col2, &H2, &L2, &S2);
return HLStoRGB( H1+(H2-H1)*Ratio, L1+(L2-L1)*Ratio, S1+(S2-S1)*Ratio );
}
/******************************************************************************
FUNCTION: ColorScaleRGB
PURPOSE: Returns the RGB linear interpolated color between 2 colors
If Ratio=0, you get Col1,
If Ratio=1, you get Col2
IN: Col1: low color in hex 0xBBGGRR format
Col2: high color in hex 0xBBGGRR format
Ratio: 0 for low color, 1 for high color, or in between
EXAMPLE: Col1=0, Col2=0xFF00FF, Ratio=0.5 returns 0x800080
******************************************************************************/
COLORREF ColorScaleRGB( const COLORREF Col1,
const COLORREF Col2,
const double Ratio) {
int R1=(Col1)&0xFF, G1=(Col1>>8)&0xFF, B1=(Col1>>16)&0xFF;
int R2=(Col2)&0xFF, G2=(Col2>>8)&0xFF, B2=(Col2>>16)&0xFF;
if (Ratio<=0) return Col1; // Ratio parameter must be between 0 and 1
else if (Ratio>=1) return Col2;
/* return RGB(
(R1 + (R2 - R1) * (Ratio + 0.02) + 0.5), // rounding
(G1 + (G2 - G1) * (Ratio - 0.00) + 0.5),
(B1 + (B2 - B1) * (Ratio + 0.05) + 0.5)
);*/
/*double r = Ratio;
if(Col2 == 0)
r = 1-Ratio;
else
r = 1+Ratio;
R1 = (int)(double(R1) * r + 0.5);
G1 = (int)(double(G1) * r + 0.5);
B1 = (int)(double(B1) * r + 0.5);
return RGB(R1,G1,B1);*/
return RGB(
(R1 + (R2 - R1) * (Ratio + 0.02) + 0.5), // rounding
(G1 + (G2 - G1) * (Ratio - 0.00) + 0.5),
(B1 + (B2 - B1) * (Ratio + 0.05) + 0.5)
);
}
COLORREF ColorDarker(COLORREF col, double ratio)
{
return ColorScaleHSL(col, RGB(0,0,0), ratio);
}
COLORREF ColorLighter(COLORREF col, double ratio)
{
return ColorScaleHSL(col, RGB(255,255,255), ratio);
}
//
// Experimental!!!
//
#if 0
typedef enum { Red, Green, Blue };
void RGBtoHLS(COLORREF rgb, double *Hue, double *Lum, double *Sat)
{
double mn, mx;
int major;
BYTE red, green, blue;
red = GetRValue(rgb);
green = GetGValue(rgb);
blue = GetBValue(rgb);
if(red < green)
{
mn = red; mx = green; major = Green;
}
else
{
mn = green; mx = red; major = Red;
}
if(blue < mn)
{
mn = blue;
}
else if(blue > mx)
{
mx = blue; major = Blue;
}
if(mn == mx)
{
*Lum = mn / 255;
*Sat = 0;
*Hue = 0;
}
else
{
*Lum = (mx + mn) / 510;
if(*Lum <= 0.5)
*Sat = (mx-mn) / (mn+mx);
else
*Sat = (mx-mn) / (510-mn-mx);
switch(major)
{
case Red: *Hue = (green-blue) * 60.0 / (mx-mn) + 360.0;
break;
case Green: *Hue = (blue-red) * 60.0 / (mx-mn) + 120.0;
break;
case Blue: *Hue = (red-green) * 60.0 / (mx-mn) + 240.0;
break;
}
if(*Hue > 360.0)
*Hue -= 360.0;
}
}
static BYTE Value(double m1, double m2, double hue)
{
if(hue > 360) hue -= 360;
else if(hue < 0) hue += 360;
if(hue < 60)
m1 = m1 + (m2 - m1) * hue / 60;
else if(hue < 180)
m1 = m2;
else if(hue < 240)
m1 = m1 + (m2 - m1) * (240 - hue) / 60;
return (BYTE)(m1 * 255);
}
COLORREF HLStoRGB(const double Hue, const double Lum, const double Sat)
{
BYTE red, green, blue;
if(Sat == 0)
{
red = green = blue = (BYTE)(Lum * 255);
}
else
{
double m1, m2;
if(Lum <= 0.5)
m2 = Lum + Lum * Sat;
else
m2 = Lum + Sat - Lum * Sat;
m1 = 2 * Lum - m2;
red = Value(m1, m2, Hue + 120);
green = Value(m1, m2, Hue);
blue = Value(m1, m2, Hue - 120);
}
return RGB(red, green, blue);
}
COLORREF ScaleLumRGB(COLORREF col1, double ratio)
{
double H1, L1, S1;
RGBtoHLS(col1, &H1, &L1, &S1);
L1 += L1 * ratio;
return HLStoRGB(H1, L1, S1);
}
COLORREF ColorScaleHSL(const COLORREF Col1, const COLORREF Col2, const double Ratio)
{
static double H1, H2, S1, S2, L1, L2;
if(Ratio <= 0) return Col1; // Ratio parameter must be between 0 and 1
else if(Ratio >= 1) return Col2;
RGBtoHLS( Col1, &H1, &L1, &S1);
RGBtoHLS( Col2, &H2, &L2, &S2);
return HLStoRGB( H1 /*+ (H2 - H1 ) * Ratio*/, L1 + (L2 - L1) * Ratio, S1 + (S2 - S1) * Ratio * 2);
}
COLORREF ColorScaleRGB(const COLORREF Col1, const COLORREF Col2, const double Ratio)
{
return ColorScaleHSL(Col1, Col2, Ratio);
}
#endif
//
// Colour support
//
#include <windows.h>
#define MakeRGB RGB
#define MIN3(a,b,c) ( (a)<=(b) ? (a)<=(c)?(a):(c) : (b)<=(c)?(b):(c) )
#define MAX3(a,b,c) ( (a)>=(b) ? (a)>=(c)?(a):(c) : (b)>=(c)?(b):(c) )
inline double fMax(double a, double b)
{
return a < b ? b : a;
}
inline double fMin(double a, double b)
{
return a < b ? a : b;
}
/******************************************************************************
FUNCTION: RGBtoHLS
PURPOSE: Convert from RGB to HLS
IN: RGB color (0xBBGGRR)
OUT: Hue, Saturation, Luminance from 0 to 1
COPYRIGHT:1995-1997 Robert Mashlan
Modified for LabWindows/CVI, 1999 Guillaume Dargaud
******************************************************************************/
void RGBtoHLS(const COLORREF rgb, double *H, double *L, double *S )
{
double delta;
double r = (double)((rgb )&0xFF)/255;
double g = (double)((rgb>> 8)&0xFF)/255;
double b = (double)((rgb>>16)&0xFF)/255;
double cmax = MAX3(r,g,b);
double cmin = MIN3(r,g,b);
*L=(cmax+cmin)/2.0;
if(cmax == cmin)
{
*S = *H = 0; // it's really undefined
}
else
{
if(*L < 0.5) *S = (cmax-cmin)/(cmax+cmin);
else *S = (cmax-cmin)/(2.0-cmax-cmin);
delta = cmax - cmin;
if(r == cmax)
{
*H = (g - b) / delta;
}
else
{
if(g == cmax) *H = 2.0 + (b-r) / delta;
else *H = 4.0 + (r-g) / delta;
}
*H /= 6.0;
if (*H < 0.0) *H += 1;
}
}
/******************************************************************************
FUNCTION: HueToRGB
PURPOSE: Convert a hue (color) to RGB
COPYRIGHT:1995-1997 Robert Mashlan
Modified for LabWindows/CVI, 1999 Guillaume Dargaud
******************************************************************************/
double HueToRGB(const double m1, const double m2, double h )
{
if (h<0) h+=1.0;
if (h>1) h-=1.0;
if (6.0*h < 1 ) return (m1+(m2-m1)*h*6.0);
if (2.0*h < 1 ) return m2;
if (3.0*h < 2.0) return (m1+(m2-m1)*((2.0/3.0)-h)*6.0);
return m1;
}
/******************************************************************************
FUNCTION: HLStoRGB
PURPOSE: Convert from HSL to RGB
IN: Hue, Saturation, Luminance from 0 to 1
RETURN: RGB color (0xBBGGRR)
COPYRIGHT:1995-1997 Robert Mashlan
Modified for LabWindows/CVI, 1999 Guillaume Dargaud
******************************************************************************/
COLORREF HLStoRGB(const double H, const double L, const double S )
{
double r,g,b;
double m1, m2;
if(S == 0)
{
r = g = b = L;
}
else
{
if (L <= 0.5)
m2 = L * (1.0 + S);
else
m2 = L + S - L * S;
m1 = 2.0 * L - m2;
r = HueToRGB(m1,m2,H+1.0/3.0);
g = HueToRGB(m1,m2,H);
b = HueToRGB(m1,m2,H-1.0/3.0);
}
return RGB(r*255, g*255, b*255);
}
/******************************************************************************
FUNCTION: ColorScaleHSL
PURPOSE: Returns the HSL linear interpolated color between 2 colors
(more natural looking than RGB interpolation)
For instance if the luminance is the same in Col1 and Col2,
then the luminance of the result will be the same
If Ratio=0, you get Col1,
If Ratio=1, you get Col2
IN: Col1: low color in hex 0xBBGGRR format
Col2: high color in hex 0xBBGGRR format
Ratio: 0 for low color, 1 for high color, or in between
EXAMPLE: Col1=0, Col2=0xFF00FF, Ratio=0.5 returns 0x1F5F3F
******************************************************************************/
COLORREF ColorScaleHSL( const COLORREF Col1, const COLORREF Col2, const double Ratio)
{
static double H1, H2, S1, S2, L1, L2;
if (Ratio<=0) return Col1; // Ratio parameter must be between 0 and 1
else if (Ratio>=1) return Col2;
RGBtoHLS( Col1, &H1, &L1, &S1);
RGBtoHLS( Col2, &H2, &L2, &S2);
return HLStoRGB( H1+(H2-H1)*Ratio, L1+(L2-L1)*Ratio, S1+(S2-S1)*Ratio );
}
/******************************************************************************
FUNCTION: ColorScaleRGB
PURPOSE: Returns the RGB linear interpolated color between 2 colors
If Ratio=0, you get Col1,
If Ratio=1, you get Col2
IN: Col1: low color in hex 0xBBGGRR format
Col2: high color in hex 0xBBGGRR format
Ratio: 0 for low color, 1 for high color, or in between
EXAMPLE: Col1=0, Col2=0xFF00FF, Ratio=0.5 returns 0x800080
******************************************************************************/
COLORREF ColorScaleRGB( const COLORREF Col1,
const COLORREF Col2,
const double Ratio) {
int R1=(Col1)&0xFF, G1=(Col1>>8)&0xFF, B1=(Col1>>16)&0xFF;
int R2=(Col2)&0xFF, G2=(Col2>>8)&0xFF, B2=(Col2>>16)&0xFF;
if (Ratio<=0) return Col1; // Ratio parameter must be between 0 and 1
else if (Ratio>=1) return Col2;
/* return RGB(
(R1 + (R2 - R1) * (Ratio + 0.02) + 0.5), // rounding
(G1 + (G2 - G1) * (Ratio - 0.00) + 0.5),
(B1 + (B2 - B1) * (Ratio + 0.05) + 0.5)
);*/
/*double r = Ratio;
if(Col2 == 0)
r = 1-Ratio;
else
r = 1+Ratio;
R1 = (int)(double(R1) * r + 0.5);
G1 = (int)(double(G1) * r + 0.5);
B1 = (int)(double(B1) * r + 0.5);
return RGB(R1,G1,B1);*/
return RGB(
(R1 + (R2 - R1) * (Ratio + 0.02) + 0.5), // rounding
(G1 + (G2 - G1) * (Ratio - 0.00) + 0.5),
(B1 + (B2 - B1) * (Ratio + 0.05) + 0.5)
);
}
COLORREF ColorDarker(COLORREF col, double ratio)
{
return ColorScaleHSL(col, RGB(0,0,0), ratio);
}
COLORREF ColorLighter(COLORREF col, double ratio)
{
return ColorScaleHSL(col, RGB(255,255,255), ratio);
}
//
// Experimental!!!
//
#if 0
typedef enum { Red, Green, Blue };
void RGBtoHLS(COLORREF rgb, double *Hue, double *Lum, double *Sat)
{
double mn, mx;
int major;
BYTE red, green, blue;
red = GetRValue(rgb);
green = GetGValue(rgb);
blue = GetBValue(rgb);
if(red < green)
{
mn = red; mx = green; major = Green;
}
else
{
mn = green; mx = red; major = Red;
}
if(blue < mn)
{
mn = blue;
}
else if(blue > mx)
{
mx = blue; major = Blue;
}
if(mn == mx)
{
*Lum = mn / 255;
*Sat = 0;
*Hue = 0;
}
else
{
*Lum = (mx + mn) / 510;
if(*Lum <= 0.5)
*Sat = (mx-mn) / (mn+mx);
else
*Sat = (mx-mn) / (510-mn-mx);
switch(major)
{
case Red: *Hue = (green-blue) * 60.0 / (mx-mn) + 360.0;
break;
case Green: *Hue = (blue-red) * 60.0 / (mx-mn) + 120.0;
break;
case Blue: *Hue = (red-green) * 60.0 / (mx-mn) + 240.0;
break;
}
if(*Hue > 360.0)
*Hue -= 360.0;
}
}
static BYTE Value(double m1, double m2, double hue)
{
if(hue > 360) hue -= 360;
else if(hue < 0) hue += 360;
if(hue < 60)
m1 = m1 + (m2 - m1) * hue / 60;
else if(hue < 180)
m1 = m2;
else if(hue < 240)
m1 = m1 + (m2 - m1) * (240 - hue) / 60;
return (BYTE)(m1 * 255);
}
COLORREF HLStoRGB(const double Hue, const double Lum, const double Sat)
{
BYTE red, green, blue;
if(Sat == 0)
{
red = green = blue = (BYTE)(Lum * 255);
}
else
{
double m1, m2;
if(Lum <= 0.5)
m2 = Lum + Lum * Sat;
else
m2 = Lum + Sat - Lum * Sat;
m1 = 2 * Lum - m2;
red = Value(m1, m2, Hue + 120);
green = Value(m1, m2, Hue);
blue = Value(m1, m2, Hue - 120);
}
return RGB(red, green, blue);
}
COLORREF ScaleLumRGB(COLORREF col1, double ratio)
{
double H1, L1, S1;
RGBtoHLS(col1, &H1, &L1, &S1);
L1 += L1 * ratio;
return HLStoRGB(H1, L1, S1);
}
COLORREF ColorScaleHSL(const COLORREF Col1, const COLORREF Col2, const double Ratio)
{
static double H1, H2, S1, S2, L1, L2;
if(Ratio <= 0) return Col1; // Ratio parameter must be between 0 and 1
else if(Ratio >= 1) return Col2;
RGBtoHLS( Col1, &H1, &L1, &S1);
RGBtoHLS( Col2, &H2, &L2, &S2);
return HLStoRGB( H1 /*+ (H2 - H1 ) * Ratio*/, L1 + (L2 - L1) * Ratio, S1 + (S2 - S1) * Ratio * 2);
}
COLORREF ColorScaleRGB(const COLORREF Col1, const COLORREF Col2, const double Ratio)
{
return ColorScaleHSL(Col1, Col2, Ratio);
}
#endif

View file

@ -1,16 +1,16 @@
COLORREF ColorScaleRGB( const COLORREF Col1,
const COLORREF Col2,
const double Ratio);
COLORREF ColorScaleHSL( const COLORREF Col1,
const COLORREF Col2,
const double Ratio);
COLORREF ColorDarker(COLORREF col, double ratio);
COLORREF ColorLighter(COLORREF col, double ratio);
COLORREF ScaleLumRGB(COLORREF col1, double ratio);
#define MAKE_PALETTERGB(colref) (0x02000000 | colref)
COLORREF ColorScaleRGB( const COLORREF Col1,
const COLORREF Col2,
const double Ratio);
COLORREF ColorScaleHSL( const COLORREF Col1,
const COLORREF Col2,
const double Ratio);
COLORREF ColorDarker(COLORREF col, double ratio);
COLORREF ColorLighter(COLORREF col, double ratio);
COLORREF ScaleLumRGB(COLORREF col1, double ratio);
#define MAKE_PALETTERGB(colref) (0x02000000 | colref)

View file

@ -1,90 +1,90 @@
//
// CardCount is a helper library for CardStacks.
//
// When you initialize a CardCount object with a
// cardstack, it keeps track of the number of cards
// the stack contains.
//
// e.g. CardCount count(cardstack);
//
// Then you can do:
//
// int num_fives = count[5]
//
// count.Add(cardstack2); - combine with another stack
//
// int num_aces = count[1] - aces low
// int num_aces = count[14] - aces high
//
// count.Clear();
//
#include "cardcount.h"
CardCount::CardCount()
{
Clear();
}
CardCount::CardCount(const CardStack &cs)
{
Init(cs);
}
void CardCount::Clear()
{
for(int i = 0; i < 13; i++)
count[i] = 0;
}
void CardCount::Add(const CardStack &cs)
{
for(int i = 0; i < cs.NumCards(); i++)
{
Card card = cs[i];
int val = card.LoVal();
count[val - 1]++;
}
}
void CardCount::Sub(const CardStack &cs)
{
for(int i = 0; i < cs.NumCards(); i++)
{
Card card = cs[i];
int val = card.LoVal();
if(count[val - 1] > 0)
count[val - 1]--;
}
}
void CardCount::Init(const CardStack &cs)
{
Clear();
Add(cs);
}
int CardCount::operator [] (size_t index) const
{
if(index < 1) return 0;
else if(index > 14) return 0; //if out of range
else if(index == 14) index = 1; //if a "ace-high"
return count[index - 1];
}
//
// Decrement specified item by one
//
void CardCount::Dec(size_t index)
{
if(index < 1) return;
else if(index > 14) return; //if out of range
else if(index == 14) index = 1; //if a "ace-high"
index -= 1;
if(count[index] > 0)
count[index]--;
}
//
// CardCount is a helper library for CardStacks.
//
// When you initialize a CardCount object with a
// cardstack, it keeps track of the number of cards
// the stack contains.
//
// e.g. CardCount count(cardstack);
//
// Then you can do:
//
// int num_fives = count[5]
//
// count.Add(cardstack2); - combine with another stack
//
// int num_aces = count[1] - aces low
// int num_aces = count[14] - aces high
//
// count.Clear();
//
#include "cardcount.h"
CardCount::CardCount()
{
Clear();
}
CardCount::CardCount(const CardStack &cs)
{
Init(cs);
}
void CardCount::Clear()
{
for(int i = 0; i < 13; i++)
count[i] = 0;
}
void CardCount::Add(const CardStack &cs)
{
for(int i = 0; i < cs.NumCards(); i++)
{
Card card = cs[i];
int val = card.LoVal();
count[val - 1]++;
}
}
void CardCount::Sub(const CardStack &cs)
{
for(int i = 0; i < cs.NumCards(); i++)
{
Card card = cs[i];
int val = card.LoVal();
if(count[val - 1] > 0)
count[val - 1]--;
}
}
void CardCount::Init(const CardStack &cs)
{
Clear();
Add(cs);
}
int CardCount::operator [] (size_t index) const
{
if(index < 1) return 0;
else if(index > 14) return 0; //if out of range
else if(index == 14) index = 1; //if a "ace-high"
return count[index - 1];
}
//
// Decrement specified item by one
//
void CardCount::Dec(size_t index)
{
if(index < 1) return;
else if(index > 14) return; //if out of range
else if(index == 14) index = 1; //if a "ace-high"
index -= 1;
if(count[index] > 0)
count[index]--;
}

View file

@ -1,31 +1,31 @@
#ifndef _CARDCOUNT_INCLUDED
#define _CARDCOUNT_INCLUDED
#include <windows.h>
#include "cardstack.h"
class CardCount
{
public:
CardCount();
CardCount(const CardStack &cs);
void Init(const CardStack &cs);
void Clear();
void Add(const CardStack &cs);
void Sub(const CardStack &cs);
void Dec(size_t index);
int operator[] (size_t index) const;
CardCount &operator = (const CardStack &cs);
CardCount &operator += (const CardStack &cs);
private:
int count[13]; //13 different card values
//(ace,2,3,4,5,6,7,8,9,10,J,Q,K)
};
#endif
#ifndef _CARDCOUNT_INCLUDED
#define _CARDCOUNT_INCLUDED
#include <windows.h>
#include "cardstack.h"
class CardCount
{
public:
CardCount();
CardCount(const CardStack &cs);
void Init(const CardStack &cs);
void Clear();
void Add(const CardStack &cs);
void Sub(const CardStack &cs);
void Dec(size_t index);
int operator[] (size_t index) const;
CardCount &operator = (const CardStack &cs);
CardCount &operator += (const CardStack &cs);
private:
int count[13]; //13 different card values
//(ace,2,3,4,5,6,7,8,9,10,J,Q,K)
};
#endif

View file

@ -1,122 +1,122 @@
//
// CardLib - not much of interest in here
//
// Freeware
// Copyright J Brown 2001
//
#include <windows.h>
#include "cardlib.h"
#include "globals.h"
void LoadCardBitmaps(void);
//static bool __CARDLIB_ACES_HIGH = false;
extern double __CARDZOOMSPEED;
//
// Global variables!
//
HDC __hdcCardBitmaps;
HBITMAP __hbmCardBitmaps;
HDC __hdcPlaceHolder;
HBITMAP __hbmPlaceHolder;
HPALETTE __holdplacepal;
int __cardwidth;
int __cardheight;
HPALETTE __hPalette;
//
// Cardlib global functions!
//
void CardLib_SetZoomSpeed(int speed)
{
__CARDZOOMSPEED = (double)speed;
}
/*
It's dangerous to use these operators, because of all
the implicit conversions that could take place, which
would have unpredicted side-effects.
e.g. Card card(Hearts, 4);
if(card == 4) - how does 4 get converted??
It uses the Card(int uval) constructor,
which results in a 2 of clubs...
not what was expected
*/
/*
void CardLib_SetAcesHigh(bool fHigh);
bool operator != (const Card &lhs, const Card &rhs);
bool operator == (const Card &lhs, const Card &rhs);
bool operator < (const Card &lhs, const Card &rhs);
bool operator <= (const Card &lhs, const Card &rhs);
bool operator > (const Card &lhs, const Card &rhs);
bool operator >= (const Card &lhs, const Card &rhs);
*/
/*
void CardLib_SetAcesHigh(bool fHigh)
{
__CARDLIB_ACES_HIGH = fHigh;
}
bool operator == (const Card &lhs, const Card &rhs)
{
if(__CARDLIB_ACES_HIGH)
return lhs.HiVal() == rhs.HiVal();
else
return lhs.LoVal() == rhs.LoVal();
}
bool operator != (const Card &lhs, const Card &rhs)
{
if(__CARDLIB_ACES_HIGH)
return lhs.HiVal() != rhs.HiVal();
else
return lhs.LoVal() != rhs.LoVal();
}
bool operator > (const Card &lhs, const Card &rhs)
{
if(__CARDLIB_ACES_HIGH)
return lhs.HiVal() > rhs.HiVal();
else
return lhs.LoVal() > rhs.LoVal();
}
bool operator >= (const Card &lhs, const Card &rhs)
{
if(__CARDLIB_ACES_HIGH)
return lhs.HiVal() >= rhs.HiVal();
else
return lhs.LoVal() >= rhs.LoVal();
}
bool operator < (const Card &lhs, const Card &rhs)
{
if(__CARDLIB_ACES_HIGH)
return lhs.HiVal() < rhs.HiVal();
else
return lhs.LoVal() < rhs.LoVal();
}
bool operator <= (const Card &lhs, const Card &rhs)
{
if(__CARDLIB_ACES_HIGH)
return lhs.HiVal() <= rhs.HiVal();
else
return lhs.LoVal() <= rhs.LoVal();
}
*/
void PaintRect(HDC hdc, RECT *rect, COLORREF colour)
{
COLORREF oldcr = SetBkColor(hdc, colour);
ExtTextOut(hdc, 0, 0, ETO_OPAQUE, rect, "", 0, 0);
SetBkColor(hdc, oldcr);
}
//
// CardLib - not much of interest in here
//
// Freeware
// Copyright J Brown 2001
//
#include <windows.h>
#include "cardlib.h"
#include "globals.h"
void LoadCardBitmaps(void);
//static bool __CARDLIB_ACES_HIGH = false;
extern double __CARDZOOMSPEED;
//
// Global variables!
//
HDC __hdcCardBitmaps;
HBITMAP __hbmCardBitmaps;
HDC __hdcPlaceHolder;
HBITMAP __hbmPlaceHolder;
HPALETTE __holdplacepal;
int __cardwidth;
int __cardheight;
HPALETTE __hPalette;
//
// Cardlib global functions!
//
void CardLib_SetZoomSpeed(int speed)
{
__CARDZOOMSPEED = (double)speed;
}
/*
It's dangerous to use these operators, because of all
the implicit conversions that could take place, which
would have unpredicted side-effects.
e.g. Card card(Hearts, 4);
if(card == 4) - how does 4 get converted??
It uses the Card(int uval) constructor,
which results in a 2 of clubs...
not what was expected
*/
/*
void CardLib_SetAcesHigh(bool fHigh);
bool operator != (const Card &lhs, const Card &rhs);
bool operator == (const Card &lhs, const Card &rhs);
bool operator < (const Card &lhs, const Card &rhs);
bool operator <= (const Card &lhs, const Card &rhs);
bool operator > (const Card &lhs, const Card &rhs);
bool operator >= (const Card &lhs, const Card &rhs);
*/
/*
void CardLib_SetAcesHigh(bool fHigh)
{
__CARDLIB_ACES_HIGH = fHigh;
}
bool operator == (const Card &lhs, const Card &rhs)
{
if(__CARDLIB_ACES_HIGH)
return lhs.HiVal() == rhs.HiVal();
else
return lhs.LoVal() == rhs.LoVal();
}
bool operator != (const Card &lhs, const Card &rhs)
{
if(__CARDLIB_ACES_HIGH)
return lhs.HiVal() != rhs.HiVal();
else
return lhs.LoVal() != rhs.LoVal();
}
bool operator > (const Card &lhs, const Card &rhs)
{
if(__CARDLIB_ACES_HIGH)
return lhs.HiVal() > rhs.HiVal();
else
return lhs.LoVal() > rhs.LoVal();
}
bool operator >= (const Card &lhs, const Card &rhs)
{
if(__CARDLIB_ACES_HIGH)
return lhs.HiVal() >= rhs.HiVal();
else
return lhs.LoVal() >= rhs.LoVal();
}
bool operator < (const Card &lhs, const Card &rhs)
{
if(__CARDLIB_ACES_HIGH)
return lhs.HiVal() < rhs.HiVal();
else
return lhs.LoVal() < rhs.LoVal();
}
bool operator <= (const Card &lhs, const Card &rhs)
{
if(__CARDLIB_ACES_HIGH)
return lhs.HiVal() <= rhs.HiVal();
else
return lhs.LoVal() <= rhs.LoVal();
}
*/
void PaintRect(HDC hdc, RECT *rect, COLORREF colour)
{
COLORREF oldcr = SetBkColor(hdc, colour);
ExtTextOut(hdc, 0, 0, ETO_OPAQUE, rect, "", 0, 0);
SetBkColor(hdc, oldcr);
}

View file

@ -1,102 +1,102 @@
#ifndef CARDLIB_INCLUDED
#define CARDLIB_INCLUDED
#define CARDLIBPROC __stdcall
void CardBlt(HDC hdc, int x, int y, int nCardNum);
void CardLib_SetZoomSpeed(int);
#define CS_EI_NONE 0
#define CS_EI_SUNK 1
#define CS_DEFXOFF 12 //x-offset
#define CS_DEFYOFF 18 //y-offset
#define CS_NO3D 1 //default 3d counts (recommened)
#define CS_DEF3D 10 //(best for decks)
//#define CS_EI_CIRC 2
//#define CS_EI_X 3
#define CS_DRAG_NONE 0
#define CS_DRAG_TOP 1
#define CS_DRAG_ALL 2
#define CS_DRAG_CALLBACK 3
#define CS_DROP_NONE 0
#define CS_DROP_ALL 1
#define CS_DROP_CALLBACK 2
#define CS_XJUST_NONE 0
#define CS_XJUST_RIGHT 1
#define CS_XJUST_CENTER 2
#define CS_YJUST_NONE 0
#define CS_YJUST_BOTTOM 1
#define CS_YJUST_CENTER 2
#define CB_STATIC 0 //static text label
#define CB_PUSHBUTTON 1 //normal button
#define CB_ALIGN_CENTER 0 //centered is default
#define CB_ALIGN_LEFT 2
#define CB_ALIGN_RIGHT 4
#define CS_FACE_UP 0 //all cards face-up
#define CS_FACE_DOWN 1 //all cards face-down
#define CS_FACE_DOWNUP 2 //bottom X cards down, top-most face-up
#define CS_FACE_UPDOWN 3 //bottom X cards up, top-most face-down
#define CS_FACE_ANY 4 //cards can be any orientation
#define CS_DROPZONE_NODROP -1
//
// Define the standard card-back indices
//
#define ecbCROSSHATCH 53
#define ecbWEAVE1 54
#define ecbWEAVE2 55
#define ecbROBOT 56
#define ecbFLOWERS 57
#define ecbVINE1 58
#define ecbVINE2 59
#define ecbFISH1 60
#define ecbFISH2 61
#define ecbSHELLS 62
#define ecbCASTLE 63
#define ecbISLAND 64
#define ecbCARDHAND 65
#define ecbUNUSED 66
#define ecbTHE_X 67
#define ecbTHE_O 68
class CardRegion;
class CardButton;
class CardStack;
class CardWindow;
typedef bool (CARDLIBPROC *pCanDragProc) (CardRegion &stackobj, int iNumDragging);
typedef bool (CARDLIBPROC *pCanDropProc) (CardRegion &stackobj, const CardStack &cards);
typedef void (CARDLIBPROC *pClickProc) (CardRegion &stackobj, int iNumCards);
typedef void (CARDLIBPROC *pAddProc) (CardRegion &stackobj, const CardStack &cards);
typedef void (CARDLIBPROC *pRemoveProc) (CardRegion &stackobj, int iNumRemoved);
typedef void (CARDLIBPROC *pResizeWndProc) (int width, int height);
typedef int (CARDLIBPROC *pDropZoneProc) (int dzid, const CardStack &cards);
typedef void (CARDLIBPROC *pButtonProc) (CardButton &pButton);
#include "card.h"
#include "cardbutton.h"
#include "cardstack.h"
#include "cardregion.h"
#include "cardcount.h"
#include "cardwindow.h"
#ifdef _DEBUG
typedef bool (CARDLIBPROC *pDebugClickProc) (CardRegion &stackobj);
void CardLib_SetStackClickProc(pDebugClickProc proc);
#endif
#endif
#ifndef CARDLIB_INCLUDED
#define CARDLIB_INCLUDED
#define CARDLIBPROC __stdcall
void CardBlt(HDC hdc, int x, int y, int nCardNum);
void CardLib_SetZoomSpeed(int);
#define CS_EI_NONE 0
#define CS_EI_SUNK 1
#define CS_DEFXOFF 12 //x-offset
#define CS_DEFYOFF 18 //y-offset
#define CS_NO3D 1 //default 3d counts (recommened)
#define CS_DEF3D 10 //(best for decks)
//#define CS_EI_CIRC 2
//#define CS_EI_X 3
#define CS_DRAG_NONE 0
#define CS_DRAG_TOP 1
#define CS_DRAG_ALL 2
#define CS_DRAG_CALLBACK 3
#define CS_DROP_NONE 0
#define CS_DROP_ALL 1
#define CS_DROP_CALLBACK 2
#define CS_XJUST_NONE 0
#define CS_XJUST_RIGHT 1
#define CS_XJUST_CENTER 2
#define CS_YJUST_NONE 0
#define CS_YJUST_BOTTOM 1
#define CS_YJUST_CENTER 2
#define CB_STATIC 0 //static text label
#define CB_PUSHBUTTON 1 //normal button
#define CB_ALIGN_CENTER 0 //centered is default
#define CB_ALIGN_LEFT 2
#define CB_ALIGN_RIGHT 4
#define CS_FACE_UP 0 //all cards face-up
#define CS_FACE_DOWN 1 //all cards face-down
#define CS_FACE_DOWNUP 2 //bottom X cards down, top-most face-up
#define CS_FACE_UPDOWN 3 //bottom X cards up, top-most face-down
#define CS_FACE_ANY 4 //cards can be any orientation
#define CS_DROPZONE_NODROP -1
//
// Define the standard card-back indices
//
#define ecbCROSSHATCH 53
#define ecbWEAVE1 54
#define ecbWEAVE2 55
#define ecbROBOT 56
#define ecbFLOWERS 57
#define ecbVINE1 58
#define ecbVINE2 59
#define ecbFISH1 60
#define ecbFISH2 61
#define ecbSHELLS 62
#define ecbCASTLE 63
#define ecbISLAND 64
#define ecbCARDHAND 65
#define ecbUNUSED 66
#define ecbTHE_X 67
#define ecbTHE_O 68
class CardRegion;
class CardButton;
class CardStack;
class CardWindow;
typedef bool (CARDLIBPROC *pCanDragProc) (CardRegion &stackobj, int iNumDragging);
typedef bool (CARDLIBPROC *pCanDropProc) (CardRegion &stackobj, const CardStack &cards);
typedef void (CARDLIBPROC *pClickProc) (CardRegion &stackobj, int iNumCards);
typedef void (CARDLIBPROC *pAddProc) (CardRegion &stackobj, const CardStack &cards);
typedef void (CARDLIBPROC *pRemoveProc) (CardRegion &stackobj, int iNumRemoved);
typedef void (CARDLIBPROC *pResizeWndProc) (int width, int height);
typedef int (CARDLIBPROC *pDropZoneProc) (int dzid, const CardStack &cards);
typedef void (CARDLIBPROC *pButtonProc) (CardButton &pButton);
#include "card.h"
#include "cardbutton.h"
#include "cardstack.h"
#include "cardregion.h"
#include "cardcount.h"
#include "cardwindow.h"
#ifdef _DEBUG
typedef bool (CARDLIBPROC *pDebugClickProc) (CardRegion &stackobj);
void CardLib_SetStackClickProc(pDebugClickProc proc);
#endif
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,216 +1,216 @@
#ifndef CARDREGION_INCLUDED
#define CARDREGION_INCLUDED
#include "globals.h"
#include "cardstack.h"
#include "cardlib.h"
class CardWindow;
//
// This class defines a physical card-stack,
// which draws the cards, supports
//
class CardRegion
{
friend class CardWindow;
friend class CardStack;
//
// Constructor is PRIVATE - only
// a CardWindow can create cardstacks!
//
CardRegion(CardWindow &parent, int id, bool fVisible,
int x, int y, int xOffset, int yOffset);
~CardRegion();
public:
void SetBackColor(COLORREF cr);
void SetCardStack(const CardStack &cs);
const CardStack & GetCardStack();
//
// Event-callback support
//
bool SetDragRule(UINT uDragType, pCanDragProc proc = 0);
bool SetDropRule(UINT uDropType, pCanDropProc proc = 0);
void SetClickProc (pClickProc proc);
void SetDblClickProc (pClickProc proc);
void SetAddCardProc (pAddProc proc);
void SetRemoveCardProc (pRemoveProc proc);
//
// Physical attribute support
//
bool SetThreedCount (int count);
void SetOffsets (int x, int y);
void SetPos (int x, int y);
void Show (bool fShow);
bool IsVisible ();
void SetEmptyImage (UINT uImage);
void SetBackCardIdx (UINT uBackIdx);
void SetPlacement (UINT xJustify, UINT yJustify, int xAdjust, int yAdjust);
void Update();
void Redraw();
void SetFaceDirection(UINT uDirType, int nOption);
UINT GetFaceDirection(int *pnOption);
void Flash(int count, int timeout);
void StopFlash();
int Id();
CardWindow &GetCardWindow() { return parentWnd; }
bool PlayCard(CardRegion *pDestStack, int value, int num);
bool MoveCard(CardRegion *pDestStack, int nNumCards, bool fAnimate);
bool SimulateDrag(CardRegion *pDestStack, int nNumCards, bool fAnimate);
bool Lock();
bool UnLock();
//
// Common wrappers for the CardStack object
//
int NumCards() const;
void NewDeck() { cardstack.NewDeck(); }
void Shuffle() { cardstack.Shuffle(); }
void Clear() { cardstack.Clear(); }
void Reverse() { cardstack.Reverse(); }
void Push(const Card card) { cardstack.Push(card); }
void Push(const CardStack &cs) { cardstack.Push(cs); }
Card Pop() { return cardstack.Pop(); }
CardStack Pop(int items) { return cardstack.Pop(items); }
Card Top() { return cardstack.Top(); }
CardStack Top(int items) { return cardstack.Top(items); }
private:
void DoFlash();
void RedrawIfNotDim(CardRegion *compare, bool fFullRedraw);
void UpdateFaceDir(CardStack &cards);
void Clip(HDC hdc);
void Render(HDC hdc);
int GetOverlapRatio(int x, int y, int width, int height);
void MoveDragCardTo(HDC hdc, int x, int y);
void ZoomCard(HDC hdc, int xpos, int ypos, CardRegion *dest);
void RenderBottomMost(HDC hdc, int minustopmost = 0);
void PrepareDragBitmaps(int numtodrag);
void PrepareDragBitmapsThreed(int numtodrag);
void ReleaseDragBitmaps(void);
bool CanDragCards(int iNumCards);
bool CanDropCards(CardStack &cards);
void CalcApparentCards();
int CalcApparentCards(int realnum);
void UpdateSize();
void AdjustPosition(int winwidth, int winheight);
bool IsPointInStack(int x, int y);
int GetNumDragCards(int x, int y);
bool OnLButtonDown(int x, int y);
bool OnLButtonDblClk(int x, int y);
bool OnMouseMove(int x, int y);
bool OnLButtonUp(int x, int y);
//
// Private data members
//
int id;
CardWindow &parentWnd;
CardStack cardstack; //cards in this stack
CardStack dragstack; //cards which we might be dragging
bool fMouseDragging;
int xpos; //coordinates of stack
int ypos;
int xoffset; //direction that cards take
int yoffset;
int width; //stack-size of all cards
int height;
//
// justify / placement vars
int xjustify;
int yjustify;
int xadjust;
int yadjust;
//
// Used for mouse-dragging / moving cards
//
int iNumDragCards;
int mousexoffset;
int mouseyoffset;
int oldx;
int oldy;
int nDragCardWidth;
int nDragCardHeight;
HDC hdcBackGnd;
HBITMAP hbmBackGnd;
HDC hdcDragCard;
HBITMAP hbmDragCard;
int nNumApparentCards;
int nThreedCount;
bool fVisible;
int nFlashCount;
bool fFlashVisible;
UINT uFlashTimer;
COLORREF crBackgnd;
UINT uEmptyImage;
UINT uFaceDirType;
int nFaceDirOption;
int nBackCardIdx;
UINT uDragRule;
UINT uDropRule;
//
// Stack callback support
//
pCanDragProc CanDragCallback;
pCanDropProc CanDropCallback;
pClickProc ClickCallback;
pClickProc DblClickCallback;
pAddProc AddCallback;
pRemoveProc RemoveCallback;
//locking mechanism to prevent user dragging etc
HANDLE mxlock;
};
#endif
#ifndef CARDREGION_INCLUDED
#define CARDREGION_INCLUDED
#include "globals.h"
#include "cardstack.h"
#include "cardlib.h"
class CardWindow;
//
// This class defines a physical card-stack,
// which draws the cards, supports
//
class CardRegion
{
friend class CardWindow;
friend class CardStack;
//
// Constructor is PRIVATE - only
// a CardWindow can create cardstacks!
//
CardRegion(CardWindow &parent, int id, bool fVisible,
int x, int y, int xOffset, int yOffset);
~CardRegion();
public:
void SetBackColor(COLORREF cr);
void SetCardStack(const CardStack &cs);
const CardStack & GetCardStack();
//
// Event-callback support
//
bool SetDragRule(UINT uDragType, pCanDragProc proc = 0);
bool SetDropRule(UINT uDropType, pCanDropProc proc = 0);
void SetClickProc (pClickProc proc);
void SetDblClickProc (pClickProc proc);
void SetAddCardProc (pAddProc proc);
void SetRemoveCardProc (pRemoveProc proc);
//
// Physical attribute support
//
bool SetThreedCount (int count);
void SetOffsets (int x, int y);
void SetPos (int x, int y);
void Show (bool fShow);
bool IsVisible ();
void SetEmptyImage (UINT uImage);
void SetBackCardIdx (UINT uBackIdx);
void SetPlacement (UINT xJustify, UINT yJustify, int xAdjust, int yAdjust);
void Update();
void Redraw();
void SetFaceDirection(UINT uDirType, int nOption);
UINT GetFaceDirection(int *pnOption);
void Flash(int count, int timeout);
void StopFlash();
int Id();
CardWindow &GetCardWindow() { return parentWnd; }
bool PlayCard(CardRegion *pDestStack, int value, int num);
bool MoveCard(CardRegion *pDestStack, int nNumCards, bool fAnimate);
bool SimulateDrag(CardRegion *pDestStack, int nNumCards, bool fAnimate);
bool Lock();
bool UnLock();
//
// Common wrappers for the CardStack object
//
int NumCards() const;
void NewDeck() { cardstack.NewDeck(); }
void Shuffle() { cardstack.Shuffle(); }
void Clear() { cardstack.Clear(); }
void Reverse() { cardstack.Reverse(); }
void Push(const Card card) { cardstack.Push(card); }
void Push(const CardStack &cs) { cardstack.Push(cs); }
Card Pop() { return cardstack.Pop(); }
CardStack Pop(int items) { return cardstack.Pop(items); }
Card Top() { return cardstack.Top(); }
CardStack Top(int items) { return cardstack.Top(items); }
private:
void DoFlash();
void RedrawIfNotDim(CardRegion *compare, bool fFullRedraw);
void UpdateFaceDir(CardStack &cards);
void Clip(HDC hdc);
void Render(HDC hdc);
int GetOverlapRatio(int x, int y, int width, int height);
void MoveDragCardTo(HDC hdc, int x, int y);
void ZoomCard(HDC hdc, int xpos, int ypos, CardRegion *dest);
void RenderBottomMost(HDC hdc, int minustopmost = 0);
void PrepareDragBitmaps(int numtodrag);
void PrepareDragBitmapsThreed(int numtodrag);
void ReleaseDragBitmaps(void);
bool CanDragCards(int iNumCards);
bool CanDropCards(CardStack &cards);
void CalcApparentCards();
int CalcApparentCards(int realnum);
void UpdateSize();
void AdjustPosition(int winwidth, int winheight);
bool IsPointInStack(int x, int y);
int GetNumDragCards(int x, int y);
bool OnLButtonDown(int x, int y);
bool OnLButtonDblClk(int x, int y);
bool OnMouseMove(int x, int y);
bool OnLButtonUp(int x, int y);
//
// Private data members
//
int id;
CardWindow &parentWnd;
CardStack cardstack; //cards in this stack
CardStack dragstack; //cards which we might be dragging
bool fMouseDragging;
int xpos; //coordinates of stack
int ypos;
int xoffset; //direction that cards take
int yoffset;
int width; //stack-size of all cards
int height;
//
// justify / placement vars
int xjustify;
int yjustify;
int xadjust;
int yadjust;
//
// Used for mouse-dragging / moving cards
//
int iNumDragCards;
int mousexoffset;
int mouseyoffset;
int oldx;
int oldy;
int nDragCardWidth;
int nDragCardHeight;
HDC hdcBackGnd;
HBITMAP hbmBackGnd;
HDC hdcDragCard;
HBITMAP hbmDragCard;
int nNumApparentCards;
int nThreedCount;
bool fVisible;
int nFlashCount;
bool fFlashVisible;
UINT uFlashTimer;
COLORREF crBackgnd;
UINT uEmptyImage;
UINT uFaceDirType;
int nFaceDirOption;
int nBackCardIdx;
UINT uDragRule;
UINT uDropRule;
//
// Stack callback support
//
pCanDragProc CanDragCallback;
pCanDropProc CanDropCallback;
pClickProc ClickCallback;
pClickProc DblClickCallback;
pAddProc AddCallback;
pRemoveProc RemoveCallback;
//locking mechanism to prevent user dragging etc
HANDLE mxlock;
};
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,237 +1,237 @@
//
// CardLib - CardStack class
//
// Freeware
// Copyright J Brown 2001
//
#include <windows.h>
#include <stdlib.h>
#include "cardstack.h"
Card &CardStack::operator[] (size_t index)
{
if(index >= (size_t)nNumCards) index = nNumCards - 1;
return cardlist[nNumCards - index - 1];
}
const Card &CardStack::operator[] (size_t index) const
{
if(index >= (size_t)nNumCards) index = nNumCards - 1;
return cardlist[nNumCards - index - 1];
}
// Subscripting operator for a constant sequence
//
/*Card CardStack::operator[] (size_t index) const
{
return cardlist[index];
}*/
//
// Subscripting operator for a non-const sequence
//
/*CardStack::ref CardStack::operator[] (size_t index)
{
return ref(this, index);
}*/
void CardStack::Clear()
{
nNumCards = 0;
}
void CardStack::NewDeck()
{
nNumCards = 52;
for(int i = 0; i < 52; i++)
cardlist[i].nValue = i;
}
void CardStack::Shuffle()
{
int src, dest;
Card temp;
//shuffle 8 times..
for(int i = 0; i < 8; i++)
for(dest = nNumCards - 1; dest > 0; dest--)
{
//want to do this:
// bad: src = rand() % (dest + 1)
// good: src = rand() / (RAND_MAX / (dest+1) + 1)
//positions from 0 to dest
src = rand() / (RAND_MAX / (dest+1) + 1);
//swap the cards
temp = cardlist[src];
cardlist[src] = cardlist[dest];
cardlist[dest] = temp;
}
}
void CardStack::Reverse()
{
for(int i = 0; i < nNumCards / 2; i++)
{
Card temp = cardlist[i];
cardlist[i] = cardlist[nNumCards - i - 1];
cardlist[nNumCards - i - 1] = temp;
}
}
void CardStack::Push(const Card card)
{
if(nNumCards < MAX_CARDSTACK_SIZE)
cardlist[nNumCards++] = card;
}
void CardStack::Push(const CardStack &cardstack)
{
if(nNumCards + cardstack.nNumCards < MAX_CARDSTACK_SIZE)
{
int num = cardstack.NumCards();
for(int i = 0; i < num; i++)
cardlist[nNumCards++] = cardstack.cardlist[i];
}
}
CardStack& CardStack::operator += (Card card)
{
Push(card);
return *this;
}
CardStack& CardStack::operator += (CardStack &cs)
{
Push(cs);
return *this;
}
CardStack CardStack::operator + (Card card)
{
CardStack poo = *this;
poo.Push(card);
return poo;
}
CardStack CardStack::operator + (CardStack &cs)
{
CardStack poo = *this;
poo.Push(cs);
return poo;
}
Card CardStack::Pop()
{
if(nNumCards > 0)
return cardlist[--nNumCards];
else
return 0;
}
CardStack CardStack::Pop(int items)
{
if(items <= nNumCards && nNumCards > 0)
{
CardStack cs(*this, nNumCards - items);
nNumCards -= items;
return cs;
}
else
{
return CardStack();
}
}
Card CardStack::Top()
{
if(nNumCards > 0)
return cardlist[nNumCards - 1];
else
return 0;
}
CardStack CardStack::Top(int items)
{
if(items <= nNumCards && nNumCards > 0)
{
return CardStack (*this, nNumCards - items);
}
else
{
return CardStack();
}
}
Card CardStack::RemoveCard(size_t index)
{
if(nNumCards == 0 || index >= (size_t)nNumCards)
return 0;
//put index into reverse range..
index = nNumCards - index - 1;
Card temp = cardlist[index];
nNumCards--;
for(size_t i = index; i < (size_t)nNumCards; i++)
{
cardlist[i] = cardlist[i+1];
}
return temp;
}
void CardStack::InsertCard(size_t index, Card card)
{
if(nNumCards == MAX_CARDSTACK_SIZE)
return;
if(index > (size_t)nNumCards)
return;
if((size_t)nNumCards == index)
{
cardlist[nNumCards] = card;
nNumCards++;
return;
}
//put index into reverse range..
index = nNumCards - index - 1;
nNumCards++;
//make room for the card
for(size_t i = nNumCards; i > index; i--)
{
cardlist[i] = cardlist[i - 1];
}
cardlist[index] = card;
}
void CardStack::Print()
{
// for(int i = 0; i < nNumCards; i++)
// cout << cardlist[i].HiVal() << " ";
}
CardStack::CardStack(CardStack &copythis, size_t fromindex)
{
nNumCards = copythis.nNumCards - fromindex;
for(int i = 0; i < nNumCards; i++)
cardlist[i] = copythis.cardlist[fromindex + i];
}
//
// CardLib - CardStack class
//
// Freeware
// Copyright J Brown 2001
//
#include <windows.h>
#include <stdlib.h>
#include "cardstack.h"
Card &CardStack::operator[] (size_t index)
{
if(index >= (size_t)nNumCards) index = nNumCards - 1;
return cardlist[nNumCards - index - 1];
}
const Card &CardStack::operator[] (size_t index) const
{
if(index >= (size_t)nNumCards) index = nNumCards - 1;
return cardlist[nNumCards - index - 1];
}
// Subscripting operator for a constant sequence
//
/*Card CardStack::operator[] (size_t index) const
{
return cardlist[index];
}*/
//
// Subscripting operator for a non-const sequence
//
/*CardStack::ref CardStack::operator[] (size_t index)
{
return ref(this, index);
}*/
void CardStack::Clear()
{
nNumCards = 0;
}
void CardStack::NewDeck()
{
nNumCards = 52;
for(int i = 0; i < 52; i++)
cardlist[i].nValue = i;
}
void CardStack::Shuffle()
{
int src, dest;
Card temp;
//shuffle 8 times..
for(int i = 0; i < 8; i++)
for(dest = nNumCards - 1; dest > 0; dest--)
{
//want to do this:
// bad: src = rand() % (dest + 1)
// good: src = rand() / (RAND_MAX / (dest+1) + 1)
//positions from 0 to dest
src = rand() / (RAND_MAX / (dest+1) + 1);
//swap the cards
temp = cardlist[src];
cardlist[src] = cardlist[dest];
cardlist[dest] = temp;
}
}
void CardStack::Reverse()
{
for(int i = 0; i < nNumCards / 2; i++)
{
Card temp = cardlist[i];
cardlist[i] = cardlist[nNumCards - i - 1];
cardlist[nNumCards - i - 1] = temp;
}
}
void CardStack::Push(const Card card)
{
if(nNumCards < MAX_CARDSTACK_SIZE)
cardlist[nNumCards++] = card;
}
void CardStack::Push(const CardStack &cardstack)
{
if(nNumCards + cardstack.nNumCards < MAX_CARDSTACK_SIZE)
{
int num = cardstack.NumCards();
for(int i = 0; i < num; i++)
cardlist[nNumCards++] = cardstack.cardlist[i];
}
}
CardStack& CardStack::operator += (Card card)
{
Push(card);
return *this;
}
CardStack& CardStack::operator += (CardStack &cs)
{
Push(cs);
return *this;
}
CardStack CardStack::operator + (Card card)
{
CardStack poo = *this;
poo.Push(card);
return poo;
}
CardStack CardStack::operator + (CardStack &cs)
{
CardStack poo = *this;
poo.Push(cs);
return poo;
}
Card CardStack::Pop()
{
if(nNumCards > 0)
return cardlist[--nNumCards];
else
return 0;
}
CardStack CardStack::Pop(int items)
{
if(items <= nNumCards && nNumCards > 0)
{
CardStack cs(*this, nNumCards - items);
nNumCards -= items;
return cs;
}
else
{
return CardStack();
}
}
Card CardStack::Top()
{
if(nNumCards > 0)
return cardlist[nNumCards - 1];
else
return 0;
}
CardStack CardStack::Top(int items)
{
if(items <= nNumCards && nNumCards > 0)
{
return CardStack (*this, nNumCards - items);
}
else
{
return CardStack();
}
}
Card CardStack::RemoveCard(size_t index)
{
if(nNumCards == 0 || index >= (size_t)nNumCards)
return 0;
//put index into reverse range..
index = nNumCards - index - 1;
Card temp = cardlist[index];
nNumCards--;
for(size_t i = index; i < (size_t)nNumCards; i++)
{
cardlist[i] = cardlist[i+1];
}
return temp;
}
void CardStack::InsertCard(size_t index, Card card)
{
if(nNumCards == MAX_CARDSTACK_SIZE)
return;
if(index > (size_t)nNumCards)
return;
if((size_t)nNumCards == index)
{
cardlist[nNumCards] = card;
nNumCards++;
return;
}
//put index into reverse range..
index = nNumCards - index - 1;
nNumCards++;
//make room for the card
for(size_t i = nNumCards; i > index; i--)
{
cardlist[i] = cardlist[i - 1];
}
cardlist[index] = card;
}
void CardStack::Print()
{
// for(int i = 0; i < nNumCards; i++)
// cout << cardlist[i].HiVal() << " ";
}
CardStack::CardStack(CardStack &copythis, size_t fromindex)
{
nNumCards = copythis.nNumCards - fromindex;
for(int i = 0; i < nNumCards; i++)
cardlist[i] = copythis.cardlist[fromindex + i];
}

View file

@ -1,53 +1,53 @@
#ifndef CARDSTACK_INCLUDED
#define CARDSTACK_INCLUDED
#include "card.h"
#define MAX_CARDSTACK_SIZE 128
class CardStack
{
friend class CardRegion;
public:
CardStack() : nNumCards(0) { }
void NewDeck();
int NumCards() const { return nNumCards; }
void Shuffle();
void Clear();
void Reverse();
void Push(const Card card);
void Push(const CardStack &cardstack);
Card Pop();
CardStack Pop(int items);
Card Top();
CardStack Top(int items);
void Print();
Card RemoveCard(size_t index);
void InsertCard(size_t index, Card card);
//subscript capability!!
Card & operator[] (size_t index);
const Card & operator[] (size_t index) const;
CardStack &operator += (Card card);
CardStack &operator += (CardStack &cs);
CardStack operator + (Card card);
CardStack operator + (CardStack &cs);
private:
CardStack(CardStack &copythis, size_t fromindex);
Card cardlist[MAX_CARDSTACK_SIZE];
int nNumCards;
};
#endif
#ifndef CARDSTACK_INCLUDED
#define CARDSTACK_INCLUDED
#include "card.h"
#define MAX_CARDSTACK_SIZE 128
class CardStack
{
friend class CardRegion;
public:
CardStack() : nNumCards(0) { }
void NewDeck();
int NumCards() const { return nNumCards; }
void Shuffle();
void Clear();
void Reverse();
void Push(const Card card);
void Push(const CardStack &cardstack);
Card Pop();
CardStack Pop(int items);
Card Top();
CardStack Top(int items);
void Print();
Card RemoveCard(size_t index);
void InsertCard(size_t index, Card card);
//subscript capability!!
Card & operator[] (size_t index);
const Card & operator[] (size_t index) const;
CardStack &operator += (Card card);
CardStack &operator += (CardStack &cs);
CardStack operator + (Card card);
CardStack operator + (CardStack &cs);
private:
CardStack(CardStack &copythis, size_t fromindex);
Card cardlist[MAX_CARDSTACK_SIZE];
int nNumCards;
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,119 +1,119 @@
#ifndef CARDBOARD_INCLUDED
#define CARDBOARD_INCLUDED
#define MAXBUTTONS 32
#define MAXCARDSTACKS 32
#define MAXDROPZONES 8
#include "dropzone.h"
#include "cardlib.h"
class CardRegion;
class CardButton;
LRESULT CALLBACK CardWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
class CardWindow
{
friend class CardRegion;
friend class CardButton;
friend void RegisterCardWindow();
public:
CardWindow();
~CardWindow();
//
// Basic windowing support
//
BOOL Create(HWND hwndParent, DWORD dwExStyle, DWORD dwStyle, int x, int y, int width, int height);
BOOL Destroy();
operator HWND() { return m_hWnd; }
CardButton *CreateButton (int id, TCHAR *szText, UINT uStyle, bool fVisible, int x, int y, int width, int height);
CardRegion *CreateRegion (int id, bool fVisible, int x, int y, int xoffset, int yoffset);
CardButton *CardButtonFromId(int id);
CardRegion *CardRegionFromId(int id);
bool DeleteButton(CardButton *pButton);
bool DeleteRegion(CardRegion *pRegion);
bool DeleteAll();
void SetBackColor(COLORREF cr);
COLORREF GetBackColor();
void SetBackCardIdx(UINT uBackIdx);
void SetBackImage(HBITMAP hBitmap);
void EmptyStacks(void);
void Redraw(void);
void Update(void);
bool DistributeStacks(int nIdFrom, int nNumStacks, UINT xJustify, int xSpacing, int nStartX);
void SetResizeProc(pResizeWndProc proc);
int GetWidth() { return nWidth; }
int GetHeight() { return nHeight; }
//
// Dropzone support
//
bool RegisterDropZone(int id, RECT *rect, pDropZoneProc proc);
bool DeleteDropZone(int id);
private:
int GetNumDropZones() { return nNumDropZones; }
DropZone* GetDropZoneFromRect(RECT *rect);
//
// Window procedure - don't call
//
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK CardWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
//
// Private functions
//
void Paint(HDC hdc);
void PaintCardRgn(HDC hdc, int dx, int dy, int width, int height, int sx, int sy);
HPALETTE CreateCardPalette();
CardButton *CardButtonFromPoint(int x, int y);
CardRegion *CardRegionFromPoint(int x, int y);
CardRegion *GetBestStack(int x, int y, int w, int h);
//
// Private members
//
HWND m_hWnd; //window handle!
int nWidth, nHeight;
UINT nBackCardIdx; //all stacks share this card index by default
HBITMAP hbmBackImage;
HDC hdcBackImage;
CardButton * Buttons[MAXBUTTONS];
int nNumButtons;
CardRegion * Regions[MAXCARDSTACKS];
int nNumCardRegions;
DropZone * dropzone[MAXDROPZONES];
int nNumDropZones;
COLORREF crBackgnd;
pResizeWndProc ResizeWndCallback;
};
#endif
#ifndef CARDBOARD_INCLUDED
#define CARDBOARD_INCLUDED
#define MAXBUTTONS 32
#define MAXCARDSTACKS 32
#define MAXDROPZONES 8
#include "dropzone.h"
#include "cardlib.h"
class CardRegion;
class CardButton;
LRESULT CALLBACK CardWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
class CardWindow
{
friend class CardRegion;
friend class CardButton;
friend void RegisterCardWindow();
public:
CardWindow();
~CardWindow();
//
// Basic windowing support
//
BOOL Create(HWND hwndParent, DWORD dwExStyle, DWORD dwStyle, int x, int y, int width, int height);
BOOL Destroy();
operator HWND() { return m_hWnd; }
CardButton *CreateButton (int id, TCHAR *szText, UINT uStyle, bool fVisible, int x, int y, int width, int height);
CardRegion *CreateRegion (int id, bool fVisible, int x, int y, int xoffset, int yoffset);
CardButton *CardButtonFromId(int id);
CardRegion *CardRegionFromId(int id);
bool DeleteButton(CardButton *pButton);
bool DeleteRegion(CardRegion *pRegion);
bool DeleteAll();
void SetBackColor(COLORREF cr);
COLORREF GetBackColor();
void SetBackCardIdx(UINT uBackIdx);
void SetBackImage(HBITMAP hBitmap);
void EmptyStacks(void);
void Redraw(void);
void Update(void);
bool DistributeStacks(int nIdFrom, int nNumStacks, UINT xJustify, int xSpacing, int nStartX);
void SetResizeProc(pResizeWndProc proc);
int GetWidth() { return nWidth; }
int GetHeight() { return nHeight; }
//
// Dropzone support
//
bool RegisterDropZone(int id, RECT *rect, pDropZoneProc proc);
bool DeleteDropZone(int id);
private:
int GetNumDropZones() { return nNumDropZones; }
DropZone* GetDropZoneFromRect(RECT *rect);
//
// Window procedure - don't call
//
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK CardWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
//
// Private functions
//
void Paint(HDC hdc);
void PaintCardRgn(HDC hdc, int dx, int dy, int width, int height, int sx, int sy);
HPALETTE CreateCardPalette();
CardButton *CardButtonFromPoint(int x, int y);
CardRegion *CardRegionFromPoint(int x, int y);
CardRegion *GetBestStack(int x, int y, int w, int h);
//
// Private members
//
HWND m_hWnd; //window handle!
int nWidth, nHeight;
UINT nBackCardIdx; //all stacks share this card index by default
HBITMAP hbmBackImage;
HDC hdcBackImage;
CardButton * Buttons[MAXBUTTONS];
int nNumButtons;
CardRegion * Regions[MAXCARDSTACKS];
int nNumCardRegions;
DropZone * dropzone[MAXDROPZONES];
int nNumDropZones;
COLORREF crBackgnd;
pResizeWndProc ResizeWndCallback;
};
#endif

View file

@ -1,69 +1,69 @@
//
// CardLib - DropZone class
//
// Freeware
// Copyright J Brown 2001
//
#include <windows.h>
#include "cardlib.h"
#include "cardwindow.h"
#include "dropzone.h"
bool CardWindow::RegisterDropZone(int id, RECT *rect, pDropZoneProc proc)
{
if(nNumDropZones == MAXDROPZONES)
return false;
DropZone *dz = new DropZone(id, rect, proc);
dropzone[nNumDropZones++] = dz;
return false;
}
DropZone *CardWindow::GetDropZoneFromRect(RECT *rect)
{
for(int i = 0; i < nNumDropZones; i++)
{
RECT inter;
RECT zone;
//if any part of the drag rectangle falls within a drop zone,
//let that take priority over any other card stack.
dropzone[i]->GetZone(&zone);
if(IntersectRect(&inter, rect, &zone))
{
//see if the callback wants us to drop a card on
//a particular stack
return dropzone[i];
}
}
return 0;
}
bool CardWindow::DeleteDropZone(int id)
{
for(int i = 0; i < nNumDropZones; i++)
{
if(dropzone[i]->id == id)
{
DropZone *dz = dropzone[i];
//shift any after this one backwards
for(int j = i; j < nNumDropZones - 1; j++)
{
dropzone[j] = dropzone[j + 1];
}
delete dz;
nNumDropZones--;
return true;
}
}
return false;
}
//
// CardLib - DropZone class
//
// Freeware
// Copyright J Brown 2001
//
#include <windows.h>
#include "cardlib.h"
#include "cardwindow.h"
#include "dropzone.h"
bool CardWindow::RegisterDropZone(int id, RECT *rect, pDropZoneProc proc)
{
if(nNumDropZones == MAXDROPZONES)
return false;
DropZone *dz = new DropZone(id, rect, proc);
dropzone[nNumDropZones++] = dz;
return false;
}
DropZone *CardWindow::GetDropZoneFromRect(RECT *rect)
{
for(int i = 0; i < nNumDropZones; i++)
{
RECT inter;
RECT zone;
//if any part of the drag rectangle falls within a drop zone,
//let that take priority over any other card stack.
dropzone[i]->GetZone(&zone);
if(IntersectRect(&inter, rect, &zone))
{
//see if the callback wants us to drop a card on
//a particular stack
return dropzone[i];
}
}
return 0;
}
bool CardWindow::DeleteDropZone(int id)
{
for(int i = 0; i < nNumDropZones; i++)
{
if(dropzone[i]->id == id)
{
DropZone *dz = dropzone[i];
//shift any after this one backwards
for(int j = i; j < nNumDropZones - 1; j++)
{
dropzone[j] = dropzone[j + 1];
}
delete dz;
nNumDropZones--;
return true;
}
}
return false;
}

View file

@ -1,39 +1,39 @@
#ifndef DROPZONE_INCLUDED
#define DROPZONE_INCLUDED
//
// define a drop-zone, which can be used to over-ride
// drop-behaviour for any card stacks which fall under it
//
class CardStack;
class DropZone
{
friend class CardWindow;
DropZone(int Id, RECT *rect, pDropZoneProc proc) :
id(Id), DropZoneCallback(proc) { CopyRect(&zone, rect); }
public:
void SetZone(RECT *rect) { CopyRect(&zone, rect); }
void GetZone(RECT *rect) { CopyRect(rect, &zone); }
void SetCallback(pDropZoneProc callback) { DropZoneCallback = callback; }
int DropCards(CardStack &cardstack)
{
if(DropZoneCallback)
return DropZoneCallback(id, cardstack);
else
return -1;
}
private:
int id;
RECT zone;
pDropZoneProc DropZoneCallback;
};
#endif
#ifndef DROPZONE_INCLUDED
#define DROPZONE_INCLUDED
//
// define a drop-zone, which can be used to over-ride
// drop-behaviour for any card stacks which fall under it
//
class CardStack;
class DropZone
{
friend class CardWindow;
DropZone(int Id, RECT *rect, pDropZoneProc proc) :
id(Id), DropZoneCallback(proc) { CopyRect(&zone, rect); }
public:
void SetZone(RECT *rect) { CopyRect(&zone, rect); }
void GetZone(RECT *rect) { CopyRect(rect, &zone); }
void SetCallback(pDropZoneProc callback) { DropZoneCallback = callback; }
int DropCards(CardStack &cardstack)
{
if(DropZoneCallback)
return DropZoneCallback(id, cardstack);
else
return -1;
}
private:
int id;
RECT zone;
pDropZoneProc DropZoneCallback;
};
#endif

View file

@ -1,15 +1,15 @@
#ifndef GLOBALS_INCLUDED
#define GLOBALS_INCLUDED
extern int __cardwidth;
extern int __cardheight;
extern HDC __hdcCardBitmaps;
extern HBITMAP __hbmCardBitmaps;
extern HDC __hdcPlaceHolder;
extern HBITMAP __hbmPlaceHolder;
extern HPALETTE __hPalette;
#endif
#ifndef GLOBALS_INCLUDED
#define GLOBALS_INCLUDED
extern int __cardwidth;
extern int __cardheight;
extern HDC __hdcCardBitmaps;
extern HBITMAP __hbmCardBitmaps;
extern HDC __hdcPlaceHolder;
extern HBITMAP __hbmPlaceHolder;
extern HPALETTE __hPalette;
#endif

View file

@ -1,84 +1,84 @@
#include <windows.h>
#include <commctrl.h>
#include <tchar.h>
#include "resource.h"
#include "cardlib/cardlib.h"
#include "solitaire.h"
const int yBorder = 20;
const int xBorder = 20;
const int yRowStacks = yBorder + 128;
CardRegion *pDeck;
CardRegion *pPile;
CardRegion *pSuitStack[4];
CardRegion *pRowStack[NUM_ROW_STACKS];
extern CardStack activepile;
HBITMAP hbmBitmap;
HDC hdcBitmap;
void CreateSol()
{
int i;
// hbmBitmap = (HBITMAP)LoadImage(0,"test.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
// SolWnd.SetBackImage(hbmBitmap);
activepile.Clear();
pDeck = SolWnd.CreateRegion(DECK_ID, true, xBorder, yBorder, 2, 1);
pDeck->SetEmptyImage(CS_EI_SUNK);
pDeck->SetThreedCount(6);
pDeck->SetDragRule(CS_DRAG_NONE, 0);
pDeck->SetDropRule(CS_DROP_NONE, 0);
pDeck->SetClickProc(DeckClickProc);
pDeck->SetDblClickProc(DeckClickProc);
pDeck->SetFaceDirection(CS_FACE_DOWN, 0);
pPile = SolWnd.CreateRegion(PILE_ID, true, 110, yBorder, CS_DEFXOFF, 1);
pPile->SetEmptyImage(CS_EI_NONE);
pPile->SetDragRule(CS_DRAG_TOP, 0);
pPile->SetDropRule(CS_DROP_NONE, 0);
pPile->SetDblClickProc(PileDblClickProc);
pPile->SetRemoveCardProc(PileRemoveProc);
//
// Create the suit stacks
//
for(i = 0; i < 4; i++)
{
pSuitStack[i] = SolWnd.CreateRegion(SUIT_ID+i, true, 0, yBorder, 0, 0);
pSuitStack[i]->SetEmptyImage(CS_EI_SUNK);
//pSuitStack[i]->SetPlacement(CS_XJUST_RIGHT, 0, -i * (__cardwidth + 4) - xBorder, 0);
pSuitStack[i]->SetPlacement(CS_XJUST_CENTER, 0, i * (__cardwidth + 10) , 0);
pSuitStack[i]->SetDropRule(CS_DROP_CALLBACK, SuitStackDropProc);
pSuitStack[i]->SetDragRule(CS_DRAG_TOP);
pSuitStack[i]->SetAddCardProc(SuitStackAddProc);
}
//
// Create the row stacks
//
for(i = 0; i < NUM_ROW_STACKS; i++)
{
pRowStack[i] = SolWnd.CreateRegion(ROW_ID+i, true, 0, yRowStacks, 0, 14);
pRowStack[i]->SetEmptyImage(CS_EI_SUNK);
pRowStack[i]->SetFaceDirection(CS_FACE_DOWNUP, i);
pRowStack[i]->SetPlacement(CS_XJUST_CENTER, 0,
(i - NUM_ROW_STACKS/2) * (__cardwidth + 10), 0);
pRowStack[i]->SetEmptyImage(CS_EI_NONE);
pRowStack[i]->SetDragRule(CS_DRAG_CALLBACK, RowStackDragProc);
pRowStack[i]->SetDropRule(CS_DROP_CALLBACK, RowStackDropProc);
pRowStack[i]->SetClickProc(RowStackClickProc);
pRowStack[i]->SetDblClickProc(RowStackDblClickProc);
}
}
#include <windows.h>
#include <commctrl.h>
#include <tchar.h>
#include "resource.h"
#include "cardlib/cardlib.h"
#include "solitaire.h"
const int yBorder = 20;
const int xBorder = 20;
const int yRowStacks = yBorder + 128;
CardRegion *pDeck;
CardRegion *pPile;
CardRegion *pSuitStack[4];
CardRegion *pRowStack[NUM_ROW_STACKS];
extern CardStack activepile;
HBITMAP hbmBitmap;
HDC hdcBitmap;
void CreateSol()
{
int i;
// hbmBitmap = (HBITMAP)LoadImage(0,"test.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
// SolWnd.SetBackImage(hbmBitmap);
activepile.Clear();
pDeck = SolWnd.CreateRegion(DECK_ID, true, xBorder, yBorder, 2, 1);
pDeck->SetEmptyImage(CS_EI_SUNK);
pDeck->SetThreedCount(6);
pDeck->SetDragRule(CS_DRAG_NONE, 0);
pDeck->SetDropRule(CS_DROP_NONE, 0);
pDeck->SetClickProc(DeckClickProc);
pDeck->SetDblClickProc(DeckClickProc);
pDeck->SetFaceDirection(CS_FACE_DOWN, 0);
pPile = SolWnd.CreateRegion(PILE_ID, true, 110, yBorder, CS_DEFXOFF, 1);
pPile->SetEmptyImage(CS_EI_NONE);
pPile->SetDragRule(CS_DRAG_TOP, 0);
pPile->SetDropRule(CS_DROP_NONE, 0);
pPile->SetDblClickProc(PileDblClickProc);
pPile->SetRemoveCardProc(PileRemoveProc);
//
// Create the suit stacks
//
for(i = 0; i < 4; i++)
{
pSuitStack[i] = SolWnd.CreateRegion(SUIT_ID+i, true, 0, yBorder, 0, 0);
pSuitStack[i]->SetEmptyImage(CS_EI_SUNK);
//pSuitStack[i]->SetPlacement(CS_XJUST_RIGHT, 0, -i * (__cardwidth + 4) - xBorder, 0);
pSuitStack[i]->SetPlacement(CS_XJUST_CENTER, 0, i * (__cardwidth + 10) , 0);
pSuitStack[i]->SetDropRule(CS_DROP_CALLBACK, SuitStackDropProc);
pSuitStack[i]->SetDragRule(CS_DRAG_TOP);
pSuitStack[i]->SetAddCardProc(SuitStackAddProc);
}
//
// Create the row stacks
//
for(i = 0; i < NUM_ROW_STACKS; i++)
{
pRowStack[i] = SolWnd.CreateRegion(ROW_ID+i, true, 0, yRowStacks, 0, 14);
pRowStack[i]->SetEmptyImage(CS_EI_SUNK);
pRowStack[i]->SetFaceDirection(CS_FACE_DOWNUP, i);
pRowStack[i]->SetPlacement(CS_XJUST_CENTER, 0,
(i - NUM_ROW_STACKS/2) * (__cardwidth + 10), 0);
pRowStack[i]->SetEmptyImage(CS_EI_NONE);
pRowStack[i]->SetDragRule(CS_DRAG_CALLBACK, RowStackDragProc);
pRowStack[i]->SetDropRule(CS_DROP_CALLBACK, RowStackDropProc);
pRowStack[i]->SetClickProc(RowStackClickProc);
pRowStack[i]->SetDblClickProc(RowStackDblClickProc);
}
}

View file

@ -1,360 +1,360 @@
#include <windows.h>
#include <commctrl.h>
#include <tchar.h>
#include <stdio.h>
#include "resource.h"
#include "cardlib/cardlib.h"
//#include "../catch22lib/trace.h"
#include "solitaire.h"
#if 1
#define TRACE(s)
#else
#define TRACE(s) printf("%s(%i): %s",__FILE__,__LINE__,s)
#endif
CardStack activepile;
bool fGameStarted = false;
void NewGame(void)
{
TRACE("ENTER NewGame()\n");
int i, j;
SolWnd.EmptyStacks();
//create a new card-stack
CardStack deck;
deck.NewDeck();
deck.Shuffle();
activepile.Clear();
//deal to each row stack..
for(i = 0; i < NUM_ROW_STACKS; i++)
{
CardStack temp;
temp.Clear();
pRowStack[i]->SetFaceDirection(CS_FACE_DOWNUP, i);
for(j = 0; j <= i; j++)
{
temp.Push(deck.Pop());
}
pRowStack[i]->SetCardStack(temp);
}
//put the other cards onto the deck
pDeck->SetCardStack(deck);
pDeck->Update();
SolWnd.Redraw();
fGameStarted = false;
TRACE("EXIT NewGame()\n");
}
//
// Now follow the stack callback functions. This is where we
// provide the game functionality and rules
//
//
// Can only drag face-up cards
//
bool CARDLIBPROC RowStackDragProc(CardRegion &stackobj, int iNumDragCards)
{
TRACE("ENTER RowStackDragProc()\n");
int numfacedown;
int numcards;
stackobj.GetFaceDirection(&numfacedown);
numcards = stackobj.NumCards();
TRACE("EXIT RowStackDragProc()\n");
if(iNumDragCards <= numcards-numfacedown)
return true;
else
return false;
}
//
// Row a row-stack, we can only drop cards
// that are lower / different colour
//
bool CARDLIBPROC RowStackDropProc(CardRegion &stackobj, const CardStack &dragcards)
{
TRACE("ENTER RowStackDropProc()\n");
Card dragcard = dragcards[dragcards.NumCards() - 1];
//if we are empty, can only drop a stack with a King at bottom
if(stackobj.NumCards() == 0)
{
if(dragcard.LoVal() != 13)
{
TRACE("EXIT RowStackDropProc(false)\n");
return false;
}
}
else
{
const CardStack &mystack = stackobj.GetCardStack();
//can only drop if card is 1 less
if(mystack[0].LoVal() != dragcard.LoVal() + 1)
{
TRACE("EXIT RowStackDropProc(false)\n");
return false;
}
//can only drop if card is different colour
if( mystack[0].IsBlack() && !dragcard.IsRed() ||
!mystack[0].IsBlack() && dragcard.IsRed() )
{
TRACE("EXIT RowStackDropProc(false)\n");
return false;
}
}
TRACE("EXIT RowStackDropProc(true)\n");
return true;
}
//
// Can only drop a card onto a suit-stack if the
// card is 1 higher, and is the same suit
//
bool CanDrop(CardRegion &stackobj, Card card)
{
TRACE("ENTER CanDrop()\n");
int topval;
const CardStack &cardstack = stackobj.GetCardStack();
if(cardstack.NumCards() > 0)
{
if(card.Suit() != cardstack[0].Suit())
{
TRACE("EXIT CanDrop()\n");
return false;
}
topval = cardstack[0].LoVal();
}
else
{
topval = 0;
}
//make sure 1 higher
if(card.LoVal() != (topval + 1))
{
TRACE("EXIT CanDrop()\n");
return false;
}
TRACE("EXIT CanDrop()\n");
return true;
}
//
// Can only drop a card onto suit stack if it is same suit, and 1 higher
//
bool CARDLIBPROC SuitStackDropProc(CardRegion &stackobj, const CardStack &dragcards)
{
TRACE("ENTER SuitStackDropProc()\n");
//only drop 1 card at a time
if(dragcards.NumCards() != 1)
{
TRACE("EXIT SuitStackDropProc()\n");
return false;
}
bool b = CanDrop(stackobj, dragcards[0]);
TRACE("EXIT SuitStackDropProc()\n");
return b;
}
//
// Single-click on one of the row-stacks
// Turn the top-card over if they are all face-down
//
void CARDLIBPROC RowStackClickProc(CardRegion &stackobj, int iNumClicked)
{
TRACE("ENTER RowStackClickProc()\n");
int numfacedown;
stackobj.GetFaceDirection(&numfacedown);
//if all face-down, then make top card face-up
if(stackobj.NumCards() == numfacedown)
{
if(numfacedown > 0) numfacedown--;
stackobj.SetFaceDirection(CS_FACE_DOWNUP, numfacedown);
stackobj.Redraw();
}
TRACE("EXIT RowStackClickProc()\n");
}
//
// Find the suit-stack that can accept the specified card
//
CardRegion *FindSuitStackFromCard(Card card)
{
TRACE("ENTER FindSuitStackFromCard()\n");
for(int i = 0; i < 4; i++)
{
if(CanDrop(*pSuitStack[i], card))
{
TRACE("EXIT FindSuitStackFromCard()\n");
return pSuitStack[i];
}
}
TRACE("EXIT FindSuitStackFromCard()\n");
return 0;
}
//
// What happens when we add a card to one of the suit stacks?
// Well, nothing (it is already added), but we need to
// check all four stacks (not just this one) to see if
// the game has finished.
//
void CARDLIBPROC SuitStackAddProc(CardRegion &stackobj, const CardStack &added)
{
TRACE("ENTER SuitStackAddProc()\n");
bool fGameOver = true;
for(int i = 0; i < 4; i++)
{
if(pSuitStack[i]->NumCards() != 13)
{
fGameOver = false;
break;
}
}
if(fGameOver)
{
MessageBox(SolWnd, _T("Congratulations, you win!!"), szAppName, MB_OK | MB_ICONINFORMATION);
for(int i = 0; i < 4; i++)
{
pSuitStack[i]->Flash(11, 100);
}
}
TRACE("EXIT SuitStackAddProc()\n");
}
//
// Double-click on one of the row stacks
// The aim is to find a suit-stack to move the
// double-clicked card to.
//
void CARDLIBPROC RowStackDblClickProc(CardRegion &stackobj, int iNumClicked)
{
TRACE("ENTER RowStackDblClickProc()\n");
//can only move 1 card at a time
if(iNumClicked != 1)
{
TRACE("EXIT RowStackDblClickProc()\n");
return;
}
//find a suit-stack to move the card to...
const CardStack &cardstack = stackobj.GetCardStack();
CardRegion *pDest = FindSuitStackFromCard(cardstack[0]);
if(pDest != 0)
{
//stackobj.MoveCards(pDest, 1, true);
//use the SimulateDrag funcion, because we get the
//AddProc callbacks called for us on the destination stacks...
stackobj.SimulateDrag(pDest, 1, true);
}
TRACE("EXIT RowStackDblClickProc()\n");
}
//
// Face-up pile double-click
//
void CARDLIBPROC PileDblClickProc(CardRegion &stackobj, int iNumClicked)
{
TRACE("ENTER PileDblClickProc()\n");
RowStackDblClickProc(stackobj, iNumClicked);
TRACE("EXIT PileDblClickProc()\n");
}
//
// What happens when a card is removed from face-up pile?
//
void CARDLIBPROC PileRemoveProc(CardRegion &stackobj, int iItems)
{
TRACE("ENTER PileRemoveProc()\n");
//modify our "virtual" pile by removing the same card
//that was removed from the physical card stack
activepile.Pop(iItems);
//if there is just 1 card left, then modify the
//stack to contain ALL the face-up cards..the effect
//will be, the next time a card is dragged, all the
//previous card-triplets will be available underneath
if(stackobj.NumCards() == 1)
{
stackobj.SetOffsets(0,0);
stackobj.SetCardStack(activepile);
}
TRACE("EXIT PileRemoveProc()\n");
}
//
// Double-click on the deck
// Move 3 cards to the face-up pile
//
void CARDLIBPROC DeckClickProc(CardRegion &stackobj, int iNumClicked)
{
TRACE("ENTER DeckClickProc()\n");
CardStack cardstack = stackobj.GetCardStack();
CardStack pile = pPile->GetCardStack();
fGameStarted = true;
//reset the face-up pile to represent 3 cards
pPile->SetOffsets(CS_DEFXOFF, 1);
if(cardstack.NumCards() == 0)
{
pile.Clear();
activepile.Reverse();
cardstack.Push(activepile);
activepile.Clear();
}
else
{
int numcards = min(3, cardstack.NumCards());
//make a "visible" copy of these cards
CardStack temp;
temp = cardstack.Pop(numcards);
temp.Reverse();
pile.Clear();
pile.Push(temp);
//remove the top 3 from deck
activepile.Push(temp);
}
activepile.Print();
pDeck->SetCardStack(cardstack);
pPile->SetCardStack(pile);
SolWnd.Redraw();
TRACE("EXIT DeckClickProc()\n");
}
#include <windows.h>
#include <commctrl.h>
#include <tchar.h>
#include <stdio.h>
#include "resource.h"
#include "cardlib/cardlib.h"
//#include "../catch22lib/trace.h"
#include "solitaire.h"
#if 1
#define TRACE(s)
#else
#define TRACE(s) printf("%s(%i): %s",__FILE__,__LINE__,s)
#endif
CardStack activepile;
bool fGameStarted = false;
void NewGame(void)
{
TRACE("ENTER NewGame()\n");
int i, j;
SolWnd.EmptyStacks();
//create a new card-stack
CardStack deck;
deck.NewDeck();
deck.Shuffle();
activepile.Clear();
//deal to each row stack..
for(i = 0; i < NUM_ROW_STACKS; i++)
{
CardStack temp;
temp.Clear();
pRowStack[i]->SetFaceDirection(CS_FACE_DOWNUP, i);
for(j = 0; j <= i; j++)
{
temp.Push(deck.Pop());
}
pRowStack[i]->SetCardStack(temp);
}
//put the other cards onto the deck
pDeck->SetCardStack(deck);
pDeck->Update();
SolWnd.Redraw();
fGameStarted = false;
TRACE("EXIT NewGame()\n");
}
//
// Now follow the stack callback functions. This is where we
// provide the game functionality and rules
//
//
// Can only drag face-up cards
//
bool CARDLIBPROC RowStackDragProc(CardRegion &stackobj, int iNumDragCards)
{
TRACE("ENTER RowStackDragProc()\n");
int numfacedown;
int numcards;
stackobj.GetFaceDirection(&numfacedown);
numcards = stackobj.NumCards();
TRACE("EXIT RowStackDragProc()\n");
if(iNumDragCards <= numcards-numfacedown)
return true;
else
return false;
}
//
// Row a row-stack, we can only drop cards
// that are lower / different colour
//
bool CARDLIBPROC RowStackDropProc(CardRegion &stackobj, const CardStack &dragcards)
{
TRACE("ENTER RowStackDropProc()\n");
Card dragcard = dragcards[dragcards.NumCards() - 1];
//if we are empty, can only drop a stack with a King at bottom
if(stackobj.NumCards() == 0)
{
if(dragcard.LoVal() != 13)
{
TRACE("EXIT RowStackDropProc(false)\n");
return false;
}
}
else
{
const CardStack &mystack = stackobj.GetCardStack();
//can only drop if card is 1 less
if(mystack[0].LoVal() != dragcard.LoVal() + 1)
{
TRACE("EXIT RowStackDropProc(false)\n");
return false;
}
//can only drop if card is different colour
if( mystack[0].IsBlack() && !dragcard.IsRed() ||
!mystack[0].IsBlack() && dragcard.IsRed() )
{
TRACE("EXIT RowStackDropProc(false)\n");
return false;
}
}
TRACE("EXIT RowStackDropProc(true)\n");
return true;
}
//
// Can only drop a card onto a suit-stack if the
// card is 1 higher, and is the same suit
//
bool CanDrop(CardRegion &stackobj, Card card)
{
TRACE("ENTER CanDrop()\n");
int topval;
const CardStack &cardstack = stackobj.GetCardStack();
if(cardstack.NumCards() > 0)
{
if(card.Suit() != cardstack[0].Suit())
{
TRACE("EXIT CanDrop()\n");
return false;
}
topval = cardstack[0].LoVal();
}
else
{
topval = 0;
}
//make sure 1 higher
if(card.LoVal() != (topval + 1))
{
TRACE("EXIT CanDrop()\n");
return false;
}
TRACE("EXIT CanDrop()\n");
return true;
}
//
// Can only drop a card onto suit stack if it is same suit, and 1 higher
//
bool CARDLIBPROC SuitStackDropProc(CardRegion &stackobj, const CardStack &dragcards)
{
TRACE("ENTER SuitStackDropProc()\n");
//only drop 1 card at a time
if(dragcards.NumCards() != 1)
{
TRACE("EXIT SuitStackDropProc()\n");
return false;
}
bool b = CanDrop(stackobj, dragcards[0]);
TRACE("EXIT SuitStackDropProc()\n");
return b;
}
//
// Single-click on one of the row-stacks
// Turn the top-card over if they are all face-down
//
void CARDLIBPROC RowStackClickProc(CardRegion &stackobj, int iNumClicked)
{
TRACE("ENTER RowStackClickProc()\n");
int numfacedown;
stackobj.GetFaceDirection(&numfacedown);
//if all face-down, then make top card face-up
if(stackobj.NumCards() == numfacedown)
{
if(numfacedown > 0) numfacedown--;
stackobj.SetFaceDirection(CS_FACE_DOWNUP, numfacedown);
stackobj.Redraw();
}
TRACE("EXIT RowStackClickProc()\n");
}
//
// Find the suit-stack that can accept the specified card
//
CardRegion *FindSuitStackFromCard(Card card)
{
TRACE("ENTER FindSuitStackFromCard()\n");
for(int i = 0; i < 4; i++)
{
if(CanDrop(*pSuitStack[i], card))
{
TRACE("EXIT FindSuitStackFromCard()\n");
return pSuitStack[i];
}
}
TRACE("EXIT FindSuitStackFromCard()\n");
return 0;
}
//
// What happens when we add a card to one of the suit stacks?
// Well, nothing (it is already added), but we need to
// check all four stacks (not just this one) to see if
// the game has finished.
//
void CARDLIBPROC SuitStackAddProc(CardRegion &stackobj, const CardStack &added)
{
TRACE("ENTER SuitStackAddProc()\n");
bool fGameOver = true;
for(int i = 0; i < 4; i++)
{
if(pSuitStack[i]->NumCards() != 13)
{
fGameOver = false;
break;
}
}
if(fGameOver)
{
MessageBox(SolWnd, _T("Congratulations, you win!!"), szAppName, MB_OK | MB_ICONINFORMATION);
for(int i = 0; i < 4; i++)
{
pSuitStack[i]->Flash(11, 100);
}
}
TRACE("EXIT SuitStackAddProc()\n");
}
//
// Double-click on one of the row stacks
// The aim is to find a suit-stack to move the
// double-clicked card to.
//
void CARDLIBPROC RowStackDblClickProc(CardRegion &stackobj, int iNumClicked)
{
TRACE("ENTER RowStackDblClickProc()\n");
//can only move 1 card at a time
if(iNumClicked != 1)
{
TRACE("EXIT RowStackDblClickProc()\n");
return;
}
//find a suit-stack to move the card to...
const CardStack &cardstack = stackobj.GetCardStack();
CardRegion *pDest = FindSuitStackFromCard(cardstack[0]);
if(pDest != 0)
{
//stackobj.MoveCards(pDest, 1, true);
//use the SimulateDrag funcion, because we get the
//AddProc callbacks called for us on the destination stacks...
stackobj.SimulateDrag(pDest, 1, true);
}
TRACE("EXIT RowStackDblClickProc()\n");
}
//
// Face-up pile double-click
//
void CARDLIBPROC PileDblClickProc(CardRegion &stackobj, int iNumClicked)
{
TRACE("ENTER PileDblClickProc()\n");
RowStackDblClickProc(stackobj, iNumClicked);
TRACE("EXIT PileDblClickProc()\n");
}
//
// What happens when a card is removed from face-up pile?
//
void CARDLIBPROC PileRemoveProc(CardRegion &stackobj, int iItems)
{
TRACE("ENTER PileRemoveProc()\n");
//modify our "virtual" pile by removing the same card
//that was removed from the physical card stack
activepile.Pop(iItems);
//if there is just 1 card left, then modify the
//stack to contain ALL the face-up cards..the effect
//will be, the next time a card is dragged, all the
//previous card-triplets will be available underneath
if(stackobj.NumCards() == 1)
{
stackobj.SetOffsets(0,0);
stackobj.SetCardStack(activepile);
}
TRACE("EXIT PileRemoveProc()\n");
}
//
// Double-click on the deck
// Move 3 cards to the face-up pile
//
void CARDLIBPROC DeckClickProc(CardRegion &stackobj, int iNumClicked)
{
TRACE("ENTER DeckClickProc()\n");
CardStack cardstack = stackobj.GetCardStack();
CardStack pile = pPile->GetCardStack();
fGameStarted = true;
//reset the face-up pile to represent 3 cards
pPile->SetOffsets(CS_DEFXOFF, 1);
if(cardstack.NumCards() == 0)
{
pile.Clear();
activepile.Reverse();
cardstack.Push(activepile);
activepile.Clear();
}
else
{
int numcards = min(3, cardstack.NumCards());
//make a "visible" copy of these cards
CardStack temp;
temp = cardstack.Pop(numcards);
temp.Reverse();
pile.Clear();
pile.Push(temp);
//remove the top 3 from deck
activepile.Push(temp);
}
activepile.Print();
pDeck->SetCardStack(cardstack);
pPile->SetCardStack(pile);
SolWnd.Redraw();
TRACE("EXIT DeckClickProc()\n");
}

View file

@ -1,222 +1,222 @@
#include <windows.h>
#include <commctrl.h>
#include <tchar.h>
#include "resource.h"
#include "cardlib/cardlib.h"
#include "solitaire.h"
TCHAR szHelpPath[MAX_PATH];
DWORD dwAppStartTime;
HWND hwndMain;
HWND hwndStatus;
HINSTANCE hInstance;
TCHAR szAppName[] = _T("Solitaire");
CardWindow SolWnd;
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
void MakePath(TCHAR *szDest, UINT nDestLen, TCHAR *szExt)
{
TCHAR *ptr;
ptr = szDest + GetModuleFileName(GetModuleHandle(0), szDest, nDestLen) - 1;
while(*ptr-- != '.');
lstrcpy(ptr + 1, szExt);
}
int main ( int argc, char** argv )
{
return WinMain ( NULL, NULL, NULL, SW_SHOW );
}
//
// Main entry point
//
int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrev, PSTR szCmdLine, int iCmdShow)
{
HWND hwnd;
MSG msg;
WNDCLASSEX wndclass;
INITCOMMONCONTROLSEX ice;
HACCEL hAccelTable;
hInstance = hInst;
//Window class for the main application parent window
wndclass.cbSize = sizeof(wndclass);
wndclass.style = 0;//CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInst;
wndclass.hIcon = LoadIcon (hInst, MAKEINTRESOURCE(IDI_ICON1));
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)NULL;
wndclass.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
wndclass.lpszClassName = szAppName;
wndclass.hIconSm = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 16, 16, 0);
RegisterClassEx(&wndclass);
ice.dwSize = sizeof(ice);
ice.dwICC = ICC_BAR_CLASSES;
InitCommonControlsEx(&ice);
srand((unsigned)GetTickCount());//timeGetTime());
// InitCardLib();
// LoadSettings();
//Construct the path to our help file
MakePath(szHelpPath, MAX_PATH, _T(".hlp"));
hwnd = CreateWindow(szAppName, // window class name
szAppName, // window caption
WS_OVERLAPPEDWINDOW
,//|WS_CLIPCHILDREN, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // use window class menu
hInst, // program instance handle
NULL); // creation parameters
hwndMain = hwnd;
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1));
while(GetMessage(&msg, NULL,0,0))
{
if(!TranslateAccelerator(hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
// SaveSettings();
return msg.wParam;
}
//-----------------------------------------------------------------------------
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
static int nWidth, nHeight;
int nStatusHeight = 0;//20;
int parts[] = { 100, -1 };
UINT ret;
MINMAXINFO *mmi;
switch(iMsg)
{
case WM_CREATE:
hwndStatus = CreateStatusWindow(WS_CHILD | WS_VISIBLE | CCS_BOTTOM | SBARS_SIZEGRIP, "Ready", hwnd, 0);
//SendMessage(hwndStatus, SB_SIMPLE, (WPARAM)TRUE, 0);
SendMessage(hwndStatus, SB_SETPARTS, 2, (LPARAM)parts);
SendMessage(hwndStatus, SB_SETTEXT, 0 | SBT_NOBORDERS, (LPARAM)"");
ShowWindow(hwndStatus, SW_HIDE);
SolWnd.Create(hwnd, WS_EX_CLIENTEDGE, WS_CHILD|WS_VISIBLE, 0, 0, 0, 0);
CreateSol();
NewGame();
dwAppStartTime = GetTickCount();
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_SIZE:
nWidth = LOWORD(lParam);
nHeight = HIWORD(lParam);
MoveWindow(SolWnd, 0, 0, nWidth, nHeight-nStatusHeight, TRUE);
//MoveWindow(hwndStatus, 0, nHeight-nStatusHeight, nWidth, nHeight, TRUE);
//parts[0] = nWidth - 256;
//SendMessage(hwndStatus, SB_SETPARTS, 2, (LPARAM)parts);
return 0;
case WM_GETMINMAXINFO:
mmi = (MINMAXINFO *)lParam;
mmi->ptMinTrackSize.x = 600;
mmi->ptMinTrackSize.y = 400;
return 0;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDM_GAME_NEW:
//simulate a button click on the new button..
NewGame();
return 0;
case IDM_GAME_DECK:
//ShowDeckOptionsDlg(hwnd);
return 0;
case IDM_GAME_OPTIONS:
//ShowGameOptionsDlg(hwnd);
return 0;
case IDM_HELP_CONTENTS:
WinHelp(hwnd, szHelpPath, HELP_CONTENTS, 0);//HELP_KEY, (DWORD)"How to play");
return 0;
case IDM_HELP_ABOUT:
MessageBox(hwnd, _T("Solitare by J Brown\r\n\r\nCardLib version 1.0."), szAppName, MB_OK|MB_ICONINFORMATION);
return 0;
case IDM_GAME_EXIT:
PostMessage(hwnd, WM_CLOSE, 0, 0);
return 0;
}
return 0;
case WM_CLOSE:
ret = IDOK;
if(fGameStarted)
{
ret = MessageBox(hwnd, _T("Quit the current game?"), szAppName, MB_OKCANCEL|MB_ICONQUESTION);
}
if(ret == IDOK)
{
WinHelp(hwnd, szHelpPath, HELP_QUIT, 0);
DestroyWindow(hwnd);
}
return 0;
}
return DefWindowProc (hwnd, iMsg, wParam, lParam);
}
#include <windows.h>
#include <commctrl.h>
#include <tchar.h>
#include "resource.h"
#include "cardlib/cardlib.h"
#include "solitaire.h"
TCHAR szHelpPath[MAX_PATH];
DWORD dwAppStartTime;
HWND hwndMain;
HWND hwndStatus;
HINSTANCE hInstance;
TCHAR szAppName[] = _T("Solitaire");
CardWindow SolWnd;
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);
void MakePath(TCHAR *szDest, UINT nDestLen, TCHAR *szExt)
{
TCHAR *ptr;
ptr = szDest + GetModuleFileName(GetModuleHandle(0), szDest, nDestLen) - 1;
while(*ptr-- != '.');
lstrcpy(ptr + 1, szExt);
}
int main ( int argc, char** argv )
{
return WinMain ( NULL, NULL, NULL, SW_SHOW );
}
//
// Main entry point
//
int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrev, PSTR szCmdLine, int iCmdShow)
{
HWND hwnd;
MSG msg;
WNDCLASSEX wndclass;
INITCOMMONCONTROLSEX ice;
HACCEL hAccelTable;
hInstance = hInst;
//Window class for the main application parent window
wndclass.cbSize = sizeof(wndclass);
wndclass.style = 0;//CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInst;
wndclass.hIcon = LoadIcon (hInst, MAKEINTRESOURCE(IDI_ICON1));
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)NULL;
wndclass.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
wndclass.lpszClassName = szAppName;
wndclass.hIconSm = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_ICON1), IMAGE_ICON, 16, 16, 0);
RegisterClassEx(&wndclass);
ice.dwSize = sizeof(ice);
ice.dwICC = ICC_BAR_CLASSES;
InitCommonControlsEx(&ice);
srand((unsigned)GetTickCount());//timeGetTime());
// InitCardLib();
// LoadSettings();
//Construct the path to our help file
MakePath(szHelpPath, MAX_PATH, _T(".hlp"));
hwnd = CreateWindow(szAppName, // window class name
szAppName, // window caption
WS_OVERLAPPEDWINDOW
,//|WS_CLIPCHILDREN, // window style
CW_USEDEFAULT, // initial x position
CW_USEDEFAULT, // initial y position
CW_USEDEFAULT, // initial x size
CW_USEDEFAULT, // initial y size
NULL, // parent window handle
NULL, // use window class menu
hInst, // program instance handle
NULL); // creation parameters
hwndMain = hwnd;
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR1));
while(GetMessage(&msg, NULL,0,0))
{
if(!TranslateAccelerator(hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
// SaveSettings();
return msg.wParam;
}
//-----------------------------------------------------------------------------
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
static int nWidth, nHeight;
int nStatusHeight = 0;//20;
int parts[] = { 100, -1 };
UINT ret;
MINMAXINFO *mmi;
switch(iMsg)
{
case WM_CREATE:
hwndStatus = CreateStatusWindow(WS_CHILD | WS_VISIBLE | CCS_BOTTOM | SBARS_SIZEGRIP, "Ready", hwnd, 0);
//SendMessage(hwndStatus, SB_SIMPLE, (WPARAM)TRUE, 0);
SendMessage(hwndStatus, SB_SETPARTS, 2, (LPARAM)parts);
SendMessage(hwndStatus, SB_SETTEXT, 0 | SBT_NOBORDERS, (LPARAM)"");
ShowWindow(hwndStatus, SW_HIDE);
SolWnd.Create(hwnd, WS_EX_CLIENTEDGE, WS_CHILD|WS_VISIBLE, 0, 0, 0, 0);
CreateSol();
NewGame();
dwAppStartTime = GetTickCount();
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_SIZE:
nWidth = LOWORD(lParam);
nHeight = HIWORD(lParam);
MoveWindow(SolWnd, 0, 0, nWidth, nHeight-nStatusHeight, TRUE);
//MoveWindow(hwndStatus, 0, nHeight-nStatusHeight, nWidth, nHeight, TRUE);
//parts[0] = nWidth - 256;
//SendMessage(hwndStatus, SB_SETPARTS, 2, (LPARAM)parts);
return 0;
case WM_GETMINMAXINFO:
mmi = (MINMAXINFO *)lParam;
mmi->ptMinTrackSize.x = 600;
mmi->ptMinTrackSize.y = 400;
return 0;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDM_GAME_NEW:
//simulate a button click on the new button..
NewGame();
return 0;
case IDM_GAME_DECK:
//ShowDeckOptionsDlg(hwnd);
return 0;
case IDM_GAME_OPTIONS:
//ShowGameOptionsDlg(hwnd);
return 0;
case IDM_HELP_CONTENTS:
WinHelp(hwnd, szHelpPath, HELP_CONTENTS, 0);//HELP_KEY, (DWORD)"How to play");
return 0;
case IDM_HELP_ABOUT:
MessageBox(hwnd, _T("Solitare by J Brown\r\n\r\nCardLib version 1.0."), szAppName, MB_OK|MB_ICONINFORMATION);
return 0;
case IDM_GAME_EXIT:
PostMessage(hwnd, WM_CLOSE, 0, 0);
return 0;
}
return 0;
case WM_CLOSE:
ret = IDOK;
if(fGameStarted)
{
ret = MessageBox(hwnd, _T("Quit the current game?"), szAppName, MB_OKCANCEL|MB_ICONQUESTION);
}
if(ret == IDOK)
{
WinHelp(hwnd, szHelpPath, HELP_QUIT, 0);
DestroyWindow(hwnd);
}
return 0;
}
return DefWindowProc (hwnd, iMsg, wParam, lParam);
}

View file

@ -1,206 +1,206 @@
////////////////////////////////////////////////////////
//
// main.cpp
//
// Implementation of a Commandlne Interface
// for the ReactOs Package Manager
//
// Maarten Bosma, 09.01.2004
// maarten.paul@bosma.de
//
////////////////////////////////////////////////////////////////////
#include "main.h"
#include <stdio.h>
int main (int argc, char **argv)
{
wprintf(L"ReactOs PackageManager %d.%d.%d Commandline Interface \n\n", PACKMGR_VERSION_MAJOR, PACKMGR_VERSION_MINOR, PACKMGR_VERSION_PATCH_LEVEL);
Argv = argv; Argc = argc;
if(argc<2)
return Help();
// install a package
if (!strcmp(argv[1], "install"))
Install();
// install a package from source
else if (!strcmp(argv[1], "src-inst"))
{
wprintf(L"Sorry but I can't do that yet. \n");
}
// update a package
else if (!strcmp(argv[1], "update"))
{
wprintf(L"Sorry but I can't do that yet. \n");
}
// update everything
else if (!strcmp(argv[1], "dist-upgrade"))
{
wprintf(L"Sorry but I can't do that yet. \n");
}
// remove a package
else if (!strcmp(argv[1], "remove"))
{
wprintf(L"Sorry but I can't do that yet. \n");
}
// search for a package
else if (!strcmp(argv[1], "show"))
{
Show();
}
// search for a package
else if (!strcmp(argv[1], "search"))
{
wprintf(L"Sorry but I can't do that yet. \n");
}
else
Help();
//
wprintf(L"\n");
return 0;
}
int Help (void)
{
wprintf(L"Usage: ros-get [command] \n\n");
wprintf(L"Possible commands: \n");
wprintf(L" install [package name] \t Installs a package \n\n");
wprintf(L" show [package name] \t\t Shows you detailed information about a package \n");
wprintf(L"Currently unimplemented commands: \n");
wprintf(L" src-install [package name] \t Installs a package from source code \n");
wprintf(L" update [package name] \t Updates a package \n");
wprintf(L" dist-update [package name] \t Updates a package \n");
wprintf(L" remove [package name] \t Uninstalls a package \n\n");
wprintf(L" search [search agrument] \t Finds a package \n");
wprintf(L" list \t\t\t\t Lists all installed programs \n");
return 0;
}
int Ask (const WCHAR* question)
{
// ask the user
wprintf(L"%s [y/n] ", question);
char answer = getchar();
// clear keybuffer
while(getchar()!='\n');
wprintf(L"\n");
// prozess answer
if (answer == 'y')
return 1;
else if (answer == 'n')
return 0;
return Ask(question);
}
int SetStatus (int status1, int status2, WCHAR* text)
{
if(text)
wprintf(L"%s\n", text);
// If the Status is 1000 things are done
if(status1==1000)
{
wprintf(L"%s\n", PML_TransError(status2));
done = TRUE;
}
return 0;
}
int Install (void)
{
pTree tree;
int i, error;
// load the tree
error = PML_LoadTree (&tree, "tree.xml", NULL);
if(error)
{
wprintf(PML_TransError(error));
return 0;
}
// look up the item
for (i=2; i<Argc; i++)
{
int id = PML_FindItem(tree, Argv[i]);
if(id)
{
PML_LoadPackage(tree, id, NULL);
PML_SetAction(tree, id, 1, NULL, Ask);
}
else
printf("Could not find the Package \"%s\"\n", Argv[i]);
}
// do it
error = PML_DoIt (tree, SetStatus, Ask);
if(error)
{
wprintf(PML_TransError(error));
PML_CloseTree (tree);
return 0;
}
// wait
while (!done)
Sleep(1000);
// clean up
PML_CloseTree (tree);
return 0;
}
int Show (void)
{
pTree tree;
int i, error;
// load the tree
error = PML_LoadTree (&tree, "tree.xml", NULL);
if(error)
{
wprintf(PML_TransError(error));
return 0;
}
// look up the item
for (i=2; i<Argc; i++)
{
int id = PML_FindItem(tree, Argv[i]);
if(id)
printf(PML_GetDescription(tree, id));
else
printf("Could not find the Package \"%s\"\n", Argv[i]);
}
// clean up
PML_CloseTree (tree);
return 0;
}
////////////////////////////////////////////////////////
//
// main.cpp
//
// Implementation of a Commandlne Interface
// for the ReactOs Package Manager
//
// Maarten Bosma, 09.01.2004
// maarten.paul@bosma.de
//
////////////////////////////////////////////////////////////////////
#include "main.h"
#include <stdio.h>
int main (int argc, char **argv)
{
wprintf(L"ReactOs PackageManager %d.%d.%d Commandline Interface \n\n", PACKMGR_VERSION_MAJOR, PACKMGR_VERSION_MINOR, PACKMGR_VERSION_PATCH_LEVEL);
Argv = argv; Argc = argc;
if(argc<2)
return Help();
// install a package
if (!strcmp(argv[1], "install"))
Install();
// install a package from source
else if (!strcmp(argv[1], "src-inst"))
{
wprintf(L"Sorry but I can't do that yet. \n");
}
// update a package
else if (!strcmp(argv[1], "update"))
{
wprintf(L"Sorry but I can't do that yet. \n");
}
// update everything
else if (!strcmp(argv[1], "dist-upgrade"))
{
wprintf(L"Sorry but I can't do that yet. \n");
}
// remove a package
else if (!strcmp(argv[1], "remove"))
{
wprintf(L"Sorry but I can't do that yet. \n");
}
// search for a package
else if (!strcmp(argv[1], "show"))
{
Show();
}
// search for a package
else if (!strcmp(argv[1], "search"))
{
wprintf(L"Sorry but I can't do that yet. \n");
}
else
Help();
//
wprintf(L"\n");
return 0;
}
int Help (void)
{
wprintf(L"Usage: ros-get [command] \n\n");
wprintf(L"Possible commands: \n");
wprintf(L" install [package name] \t Installs a package \n\n");
wprintf(L" show [package name] \t\t Shows you detailed information about a package \n");
wprintf(L"Currently unimplemented commands: \n");
wprintf(L" src-install [package name] \t Installs a package from source code \n");
wprintf(L" update [package name] \t Updates a package \n");
wprintf(L" dist-update [package name] \t Updates a package \n");
wprintf(L" remove [package name] \t Uninstalls a package \n\n");
wprintf(L" search [search agrument] \t Finds a package \n");
wprintf(L" list \t\t\t\t Lists all installed programs \n");
return 0;
}
int Ask (const WCHAR* question)
{
// ask the user
wprintf(L"%s [y/n] ", question);
char answer = getchar();
// clear keybuffer
while(getchar()!='\n');
wprintf(L"\n");
// prozess answer
if (answer == 'y')
return 1;
else if (answer == 'n')
return 0;
return Ask(question);
}
int SetStatus (int status1, int status2, WCHAR* text)
{
if(text)
wprintf(L"%s\n", text);
// If the Status is 1000 things are done
if(status1==1000)
{
wprintf(L"%s\n", PML_TransError(status2));
done = TRUE;
}
return 0;
}
int Install (void)
{
pTree tree;
int i, error;
// load the tree
error = PML_LoadTree (&tree, "tree.xml", NULL);
if(error)
{
wprintf(PML_TransError(error));
return 0;
}
// look up the item
for (i=2; i<Argc; i++)
{
int id = PML_FindItem(tree, Argv[i]);
if(id)
{
PML_LoadPackage(tree, id, NULL);
PML_SetAction(tree, id, 1, NULL, Ask);
}
else
printf("Could not find the Package \"%s\"\n", Argv[i]);
}
// do it
error = PML_DoIt (tree, SetStatus, Ask);
if(error)
{
wprintf(PML_TransError(error));
PML_CloseTree (tree);
return 0;
}
// wait
while (!done)
Sleep(1000);
// clean up
PML_CloseTree (tree);
return 0;
}
int Show (void)
{
pTree tree;
int i, error;
// load the tree
error = PML_LoadTree (&tree, "tree.xml", NULL);
if(error)
{
wprintf(PML_TransError(error));
return 0;
}
// look up the item
for (i=2; i<Argc; i++)
{
int id = PML_FindItem(tree, Argv[i]);
if(id)
printf(PML_GetDescription(tree, id));
else
printf("Could not find the Package \"%s\"\n", Argv[i]);
}
// clean up
PML_CloseTree (tree);
return 0;
}

View file

@ -1,17 +1,17 @@
///////////////////////////////////////////////////
//
// main.h
// main.cpp's lumber room :)
///////////////////////////////////////////////////
#include <package.h>
int Argc;
char **Argv;
BOOL done = FALSE;
int Help (void);
int Install (void);
int Show (void);
int SetStatus (int status1, int status2, WCHAR* text);
///////////////////////////////////////////////////
//
// main.h
// main.cpp's lumber room :)
///////////////////////////////////////////////////
#include <package.h>
int Argc;
char **Argv;
BOOL done = FALSE;
int Help (void);
int Install (void);
int Show (void);
int SetStatus (int status1, int status2, WCHAR* text);

View file

@ -1,449 +1,449 @@
////////////////////////////////////////////////////////
//
// main.cpp
//
// Implementation of the Package Manager GUI
//
//
// Maarten Bosma, 09.01.2004
// maarten.paul@bosma.de
//
////////////////////////////////////////////////////////////////////
#include "main.h"
// This is the struct where the toolbar is defined
const TBBUTTON Buttons [] =
{
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
{0, 1, TBSTATE_INDETERMINATE, TBSTYLE_BUTTON}, // No Action
{1, 2, TBSTATE_INDETERMINATE, TBSTYLE_BUTTON}, // Install
{2, 3, TBSTATE_INDETERMINATE, TBSTYLE_BUTTON}, // Install from source
{3, 4, TBSTATE_INDETERMINATE, TBSTYLE_BUTTON}, // Update
{4, 5, TBSTATE_INDETERMINATE, TBSTYLE_BUTTON}, // Unistall
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
{5, 6, TBSTATE_ENABLED, TBSTYLE_BUTTON}, // DoIt (tm)
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
{6, 7, TBSTATE_ENABLED, TBSTYLE_BUTTON}, // Help
{7, 8, TBSTATE_ENABLED, TBSTYLE_BUTTON}, // Options
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
};
// Application's Entry Point
int WINAPI WinMain (HINSTANCE hinst, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
HWND hwnd;
MSG msg;
WNDCLASSEX wc = {0};
// Window creation
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpszClassName = L"pgkmgr";
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.hInstance = hinst;
wc.hIcon = LoadIcon(hinst, MAKEINTRESOURCE(IDI_MAIN));
wc.hbrBackground = (HBRUSH)(COLOR_SCROLLBAR);
RegisterClassEx(&wc);
hwnd = CreateWindow(L"pgkmgr",
L"ReactOS - Package Manager v0.3",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
500, 600,
NULL, NULL,
hinst,
NULL);
// Toolbar creation
InitCommonControls();
hTBar = CreateToolbarEx(hwnd, WS_CHILD|WS_VISIBLE|TBSTYLE_FLAT, 0, 8, hinst, IDB_TOOLBAR,
Buttons, sizeof(Buttons)/sizeof(TBBUTTON), TBSIZE, TBSIZE, TBSIZE, TBSIZE, sizeof(TBBUTTON));
// Show the windows
ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);
// Load the tree
int error = PML_LoadTree(&tree, "tree.xml", AddItem);
if(error)
{
MessageBox(0,PML_TransError(error),0,0);
return 0;
}
// Read the help
Help();
// Start getting messages
while(GetMessage(&msg,NULL,0,0))
{
if(!TranslateAccelerator(hwnd, hHotKeys, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
// Close our handle
PML_CloseTree (tree);
return 0;
}
// Add a item to our tree
int AddItem (int id, const char* name, int parent, int icon)
{
TV_INSERTSTRUCT tvins;
tvins.item.lParam = (UINT)id;
tvins.item.mask = TVIF_TEXT|TVIF_PARAM;
tvins.item.pszText = (WCHAR*)name; //that is ok
tvins.item.cchTextMax = strlen(name);
tvins.hInsertAfter = TVI_LAST;
if(icon)
{
tvins.item.iImage = icon;
tvins.item.iSelectedImage = icon;
tvins.item.mask |= TVIF_IMAGE | TVIF_SELECTEDIMAGE;
}
if (parent==0)
tvins.hParent = TVI_ROOT;
else
tvins.hParent = nodes[parent];
nodes[id] = (HTREEITEM)SendMessage(hTree, TVM_INSERTITEMA, 0, (LPARAM)&tvins);
return 0;
}
// Load the Help from file and display it
void Help (void)
{
int i;
char buffer [2000];
FILE* file = fopen ("help.txt", "r");
if(!file)
return;
for(i=0; i<2000; i++)
{
buffer[i] = getc(file);
if(buffer[i]==EOF) break;
}
buffer[i] = 0;
SetText(buffer);
}
// Create our Controls
void InitControls (HWND hwnd)
{
HINSTANCE hinst = GetModuleHandle(NULL);
// Create the controls
hTree = CreateWindowEx(0, WC_TREEVIEW, L"TreeView", WS_CHILD|WS_VISIBLE|WS_BORDER|TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS,
0, 0, 0, 0, hwnd, NULL, hinst, NULL);
hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, L"edit", PML_TransError(IDS_LOAD), WS_CHILD|WS_VISIBLE|ES_MULTILINE,
0, 0, 100, 100, hwnd, NULL, hinst, NULL);
hPopup = LoadMenu(hinst, MAKEINTRESOURCE(IDR_POPUP));
// Create Tree Icons
HIMAGELIST hIcon = ImageList_Create(16,16,ILC_COLOR32,1,1);
SendMessage(hTree, TVM_SETIMAGELIST, TVSIL_NORMAL, (LPARAM)(HIMAGELIST)hIcon);
ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(1)));
ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(11)));
ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(12)));
ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(13)));
ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(14)));
ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(2)));
ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(3)));
ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(4)));
ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(5)));
ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(6)));
ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(7)));
ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(8)));
ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(9)));
ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(10)));
// Setup Hotkeys
hHotKeys = LoadAccelerators (hinst, MAKEINTRESOURCE(IDR_HOTKEYS));
}
// Set the Icons
int SetIcon (int id, int icon)
{
TVITEMEX item;
item.hItem = nodes[id];
item.iImage = icon;
item.iSelectedImage = icon;
item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE;
TreeView_SetItem(hTree, &item);
return 1;
}
// Set the Icons
int Ask (const WCHAR* message)
{
int ans = MessageBox (0,message,0,MB_YESNO);
if(ans == IDYES)
return 1;
return 0;
}
// En- or Disable a Button inside of the toolbar and the Context Menu
int SetButton (DWORD id, BOOL state)
{
// Change the Toorbar Button
TBBUTTONINFO ti;
ti.cbSize = sizeof (ti);
ti.dwMask = TBIF_STATE;
if(state)
ti.fsState = TBSTATE_ENABLED;
else
ti.fsState = TBSTATE_INDETERMINATE;
SendMessage (hTBar, TB_SETBUTTONINFO, id, (LPARAM)&ti);
// Change the Context Menu item
MENUITEMINFO mi;
mi.cbSize = sizeof (mi);
mi.fMask = MIIM_STATE;
if(state)
mi.fState = MFS_ENABLED;
else
mi.fState = MFS_GRAYED;
SetMenuItemInfo(hPopup, id, FALSE, &mi);
return 0;
}
// Set the text of the text box
int SetText (const char* text)
{
int i, j;
char buffer [2000];
if(!text)
return 1;
// the windows does not need "\n"
// for new lines but "\r\n"
for(i=0,j=0; text[i]; i++,j++)
{
buffer[j] = text[i];
if(buffer[j] == '\n')
{
buffer[j] = '\r';
buffer[++j] = '\n';
}
}
buffer[j] = 0;
SetWindowTextA(hEdit, buffer);
return 0;
}
// Windows Message Callback (this is where most things happen)
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
// at the very beginning ...
case WM_CREATE:
{
InitControls(hwnd);
}
break;
// calculate the size of the controls
case WM_SIZE:
{
RECT rcl;
SendMessage(hTBar, TB_AUTOSIZE, 0L, 0L);
GetWindowRect(hTBar, &rcl);
int win_top = rcl.bottom - rcl.top;
int win_hight = HIWORD(lParam) - win_top;
MoveWindow(hTree, 0, win_top, LOWORD(lParam), splitter_pos*win_hight/100, TRUE);
MoveWindow(hEdit, 0, (splitter_pos*win_hight/100)+win_top, LOWORD(lParam), win_hight, TRUE);
}
break;
// for the treeview
case WM_NOTIFY:
{
if(((LPNMHDR)lParam)->code == TVN_SELCHANGED)
{
selected = ((LPNMTREEVIEW)lParam)->itemNew.lParam;
PML_LoadPackage (tree, selected, SetButton);
SetText(PML_GetDescription (tree, selected));
}
else if ((int)(((LPNMHDR)lParam)->code) == NM_RCLICK) // <= aarrggg LISP
{
// which item has been click on
HTREEITEM item = TreeView_GetDropHilight(hTree);
if(item != NULL)
{
// mark the one as seleacted
SendMessage (hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)item);
TreeView_EnsureVisible (hTree, item);
}
// create the context menu
if(selected != 0)
{
POINT pt;
GetCursorPos (&pt);
TrackPopupMenu (GetSubMenu(hPopup, 0), 0, (UINT)pt.x, (UINT)pt.y, 0, hwnd, NULL);
}
}
}
break;
// for the toolbar
case WM_COMMAND:
{
// All Actions
if(LOWORD(wParam) <= 5 && LOWORD(wParam) >= 1)
{
if(selected)
if(PML_SetAction(tree, selected, LOWORD(wParam)-1, SetIcon, Ask) == ERR_OK)
break;
MessageBeep(MB_ICONHAND);
}
// DoIt
else if(LOWORD(wParam)==6)
{
if(PML_DoIt(tree, SetStatus, Ask) == ERR_OK)
DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DOIT), hwnd, StatusProc);
else
MessageBeep(MB_ICONHAND);
}
// Help
else if(LOWORD(wParam)==7)
Help();
// Options
else if(LOWORD(wParam)==8)
DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_OPTIONS), hwnd, OptionsProc);
}
break;
// prozess hotkeys
case WM_HOTKEY:
{
if(PML_SetAction(tree, selected, wParam, SetIcon, Ask) != ERR_OK)
MessageBeep(MB_ICONHAND);
}
break;
// ... at the very end
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc (hwnd, message, wParam, lParam);
}
// Warning: This function is called from another thread
int SetStatus (int status1, int status2, WCHAR* text)
{
// Set the Rage to 1000
SendMessage(GetDlgItem(hStatus, IDC_STATUS1), PBM_SETRANGE32, 0, 1000);
SendMessage(GetDlgItem(hStatus, IDC_STATUS2), PBM_SETRANGE32, 0, 1000);
// The prozessbars and the text filds
if(text)
SetDlgItemText(hStatus, IDC_TSTATUS, text);
if(status1!=-1)
SendMessage(GetDlgItem(hStatus, IDC_STATUS1), PBM_SETPOS, status1, 0);
if(status2!=-1)
SendMessage(GetDlgItem(hStatus, IDC_STATUS2), PBM_SETPOS, status2, 0);
// If the Status is 1000 very thing is done
if(status1==1000)
{
EndDialog(hStatus, TRUE);
MessageBox(0,PML_TransError(status2),0,0);
}
return 0;
}
// Callback for the Status Dialog
INT_PTR CALLBACK StatusProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_INITDIALOG:
{
hStatus = hwnd;
} break;
case WM_COMMAND: // can only be the about button
case WM_CLOSE: // the close-window-[x]
{
PML_Abort();
EndDialog(hwnd, TRUE);
return 0;
}
}
return 0;
}
// Callback for the Options Dialog
INT_PTR CALLBACK OptionsProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CLOSE:
EndDialog(hwnd, TRUE);
return 0;
}
return 0;
}
////////////////////////////////////////////////////////
//
// main.cpp
//
// Implementation of the Package Manager GUI
//
//
// Maarten Bosma, 09.01.2004
// maarten.paul@bosma.de
//
////////////////////////////////////////////////////////////////////
#include "main.h"
// This is the struct where the toolbar is defined
const TBBUTTON Buttons [] =
{
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
{0, 1, TBSTATE_INDETERMINATE, TBSTYLE_BUTTON}, // No Action
{1, 2, TBSTATE_INDETERMINATE, TBSTYLE_BUTTON}, // Install
{2, 3, TBSTATE_INDETERMINATE, TBSTYLE_BUTTON}, // Install from source
{3, 4, TBSTATE_INDETERMINATE, TBSTYLE_BUTTON}, // Update
{4, 5, TBSTATE_INDETERMINATE, TBSTYLE_BUTTON}, // Unistall
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
{5, 6, TBSTATE_ENABLED, TBSTYLE_BUTTON}, // DoIt (tm)
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
{6, 7, TBSTATE_ENABLED, TBSTYLE_BUTTON}, // Help
{7, 8, TBSTATE_ENABLED, TBSTYLE_BUTTON}, // Options
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP},
};
// Application's Entry Point
int WINAPI WinMain (HINSTANCE hinst, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
HWND hwnd;
MSG msg;
WNDCLASSEX wc = {0};
// Window creation
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpszClassName = L"pgkmgr";
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.hInstance = hinst;
wc.hIcon = LoadIcon(hinst, MAKEINTRESOURCE(IDI_MAIN));
wc.hbrBackground = (HBRUSH)(COLOR_SCROLLBAR);
RegisterClassEx(&wc);
hwnd = CreateWindow(L"pgkmgr",
L"ReactOS - Package Manager v0.3",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
500, 600,
NULL, NULL,
hinst,
NULL);
// Toolbar creation
InitCommonControls();
hTBar = CreateToolbarEx(hwnd, WS_CHILD|WS_VISIBLE|TBSTYLE_FLAT, 0, 8, hinst, IDB_TOOLBAR,
Buttons, sizeof(Buttons)/sizeof(TBBUTTON), TBSIZE, TBSIZE, TBSIZE, TBSIZE, sizeof(TBBUTTON));
// Show the windows
ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);
// Load the tree
int error = PML_LoadTree(&tree, "tree.xml", AddItem);
if(error)
{
MessageBox(0,PML_TransError(error),0,0);
return 0;
}
// Read the help
Help();
// Start getting messages
while(GetMessage(&msg,NULL,0,0))
{
if(!TranslateAccelerator(hwnd, hHotKeys, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
// Close our handle
PML_CloseTree (tree);
return 0;
}
// Add a item to our tree
int AddItem (int id, const char* name, int parent, int icon)
{
TV_INSERTSTRUCT tvins;
tvins.item.lParam = (UINT)id;
tvins.item.mask = TVIF_TEXT|TVIF_PARAM;
tvins.item.pszText = (WCHAR*)name; //that is ok
tvins.item.cchTextMax = strlen(name);
tvins.hInsertAfter = TVI_LAST;
if(icon)
{
tvins.item.iImage = icon;
tvins.item.iSelectedImage = icon;
tvins.item.mask |= TVIF_IMAGE | TVIF_SELECTEDIMAGE;
}
if (parent==0)
tvins.hParent = TVI_ROOT;
else
tvins.hParent = nodes[parent];
nodes[id] = (HTREEITEM)SendMessage(hTree, TVM_INSERTITEMA, 0, (LPARAM)&tvins);
return 0;
}
// Load the Help from file and display it
void Help (void)
{
int i;
char buffer [2000];
FILE* file = fopen ("help.txt", "r");
if(!file)
return;
for(i=0; i<2000; i++)
{
buffer[i] = getc(file);
if(buffer[i]==EOF) break;
}
buffer[i] = 0;
SetText(buffer);
}
// Create our Controls
void InitControls (HWND hwnd)
{
HINSTANCE hinst = GetModuleHandle(NULL);
// Create the controls
hTree = CreateWindowEx(0, WC_TREEVIEW, L"TreeView", WS_CHILD|WS_VISIBLE|WS_BORDER|TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS,
0, 0, 0, 0, hwnd, NULL, hinst, NULL);
hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, L"edit", PML_TransError(IDS_LOAD), WS_CHILD|WS_VISIBLE|ES_MULTILINE,
0, 0, 100, 100, hwnd, NULL, hinst, NULL);
hPopup = LoadMenu(hinst, MAKEINTRESOURCE(IDR_POPUP));
// Create Tree Icons
HIMAGELIST hIcon = ImageList_Create(16,16,ILC_COLOR32,1,1);
SendMessage(hTree, TVM_SETIMAGELIST, TVSIL_NORMAL, (LPARAM)(HIMAGELIST)hIcon);
ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(1)));
ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(11)));
ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(12)));
ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(13)));
ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(14)));
ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(2)));
ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(3)));
ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(4)));
ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(5)));
ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(6)));
ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(7)));
ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(8)));
ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(9)));
ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(10)));
// Setup Hotkeys
hHotKeys = LoadAccelerators (hinst, MAKEINTRESOURCE(IDR_HOTKEYS));
}
// Set the Icons
int SetIcon (int id, int icon)
{
TVITEMEX item;
item.hItem = nodes[id];
item.iImage = icon;
item.iSelectedImage = icon;
item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE;
TreeView_SetItem(hTree, &item);
return 1;
}
// Set the Icons
int Ask (const WCHAR* message)
{
int ans = MessageBox (0,message,0,MB_YESNO);
if(ans == IDYES)
return 1;
return 0;
}
// En- or Disable a Button inside of the toolbar and the Context Menu
int SetButton (DWORD id, BOOL state)
{
// Change the Toorbar Button
TBBUTTONINFO ti;
ti.cbSize = sizeof (ti);
ti.dwMask = TBIF_STATE;
if(state)
ti.fsState = TBSTATE_ENABLED;
else
ti.fsState = TBSTATE_INDETERMINATE;
SendMessage (hTBar, TB_SETBUTTONINFO, id, (LPARAM)&ti);
// Change the Context Menu item
MENUITEMINFO mi;
mi.cbSize = sizeof (mi);
mi.fMask = MIIM_STATE;
if(state)
mi.fState = MFS_ENABLED;
else
mi.fState = MFS_GRAYED;
SetMenuItemInfo(hPopup, id, FALSE, &mi);
return 0;
}
// Set the text of the text box
int SetText (const char* text)
{
int i, j;
char buffer [2000];
if(!text)
return 1;
// the windows does not need "\n"
// for new lines but "\r\n"
for(i=0,j=0; text[i]; i++,j++)
{
buffer[j] = text[i];
if(buffer[j] == '\n')
{
buffer[j] = '\r';
buffer[++j] = '\n';
}
}
buffer[j] = 0;
SetWindowTextA(hEdit, buffer);
return 0;
}
// Windows Message Callback (this is where most things happen)
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
// at the very beginning ...
case WM_CREATE:
{
InitControls(hwnd);
}
break;
// calculate the size of the controls
case WM_SIZE:
{
RECT rcl;
SendMessage(hTBar, TB_AUTOSIZE, 0L, 0L);
GetWindowRect(hTBar, &rcl);
int win_top = rcl.bottom - rcl.top;
int win_hight = HIWORD(lParam) - win_top;
MoveWindow(hTree, 0, win_top, LOWORD(lParam), splitter_pos*win_hight/100, TRUE);
MoveWindow(hEdit, 0, (splitter_pos*win_hight/100)+win_top, LOWORD(lParam), win_hight, TRUE);
}
break;
// for the treeview
case WM_NOTIFY:
{
if(((LPNMHDR)lParam)->code == TVN_SELCHANGED)
{
selected = ((LPNMTREEVIEW)lParam)->itemNew.lParam;
PML_LoadPackage (tree, selected, SetButton);
SetText(PML_GetDescription (tree, selected));
}
else if ((int)(((LPNMHDR)lParam)->code) == NM_RCLICK) // <= aarrggg LISP
{
// which item has been click on
HTREEITEM item = TreeView_GetDropHilight(hTree);
if(item != NULL)
{
// mark the one as seleacted
SendMessage (hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)item);
TreeView_EnsureVisible (hTree, item);
}
// create the context menu
if(selected != 0)
{
POINT pt;
GetCursorPos (&pt);
TrackPopupMenu (GetSubMenu(hPopup, 0), 0, (UINT)pt.x, (UINT)pt.y, 0, hwnd, NULL);
}
}
}
break;
// for the toolbar
case WM_COMMAND:
{
// All Actions
if(LOWORD(wParam) <= 5 && LOWORD(wParam) >= 1)
{
if(selected)
if(PML_SetAction(tree, selected, LOWORD(wParam)-1, SetIcon, Ask) == ERR_OK)
break;
MessageBeep(MB_ICONHAND);
}
// DoIt
else if(LOWORD(wParam)==6)
{
if(PML_DoIt(tree, SetStatus, Ask) == ERR_OK)
DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DOIT), hwnd, StatusProc);
else
MessageBeep(MB_ICONHAND);
}
// Help
else if(LOWORD(wParam)==7)
Help();
// Options
else if(LOWORD(wParam)==8)
DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_OPTIONS), hwnd, OptionsProc);
}
break;
// prozess hotkeys
case WM_HOTKEY:
{
if(PML_SetAction(tree, selected, wParam, SetIcon, Ask) != ERR_OK)
MessageBeep(MB_ICONHAND);
}
break;
// ... at the very end
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc (hwnd, message, wParam, lParam);
}
// Warning: This function is called from another thread
int SetStatus (int status1, int status2, WCHAR* text)
{
// Set the Rage to 1000
SendMessage(GetDlgItem(hStatus, IDC_STATUS1), PBM_SETRANGE32, 0, 1000);
SendMessage(GetDlgItem(hStatus, IDC_STATUS2), PBM_SETRANGE32, 0, 1000);
// The prozessbars and the text filds
if(text)
SetDlgItemText(hStatus, IDC_TSTATUS, text);
if(status1!=-1)
SendMessage(GetDlgItem(hStatus, IDC_STATUS1), PBM_SETPOS, status1, 0);
if(status2!=-1)
SendMessage(GetDlgItem(hStatus, IDC_STATUS2), PBM_SETPOS, status2, 0);
// If the Status is 1000 very thing is done
if(status1==1000)
{
EndDialog(hStatus, TRUE);
MessageBox(0,PML_TransError(status2),0,0);
}
return 0;
}
// Callback for the Status Dialog
INT_PTR CALLBACK StatusProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_INITDIALOG:
{
hStatus = hwnd;
} break;
case WM_COMMAND: // can only be the about button
case WM_CLOSE: // the close-window-[x]
{
PML_Abort();
EndDialog(hwnd, TRUE);
return 0;
}
}
return 0;
}
// Callback for the Options Dialog
INT_PTR CALLBACK OptionsProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CLOSE:
EndDialog(hwnd, TRUE);
return 0;
}
return 0;
}

View file

@ -1,45 +1,45 @@
///////////////////////////////////////////////////
//
// main.h
// main.cpp's lumber room :)
///////////////////////////////////////////////////
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include <package.h>
#include "resource.h"
/* Some Variables */
int selected, splitter_pos = 50;
pTree tree;
HMENU hPopup;
HACCEL hHotKeys;
HWND hTBar, hTree, hEdit, hStatus;
HTREEITEM nodes [MAXNODES];
/* Window Callbacks */
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK StatusProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK OptionsProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
/* Prototypes */
void Help (void);
int AddItem (int id, const char* name, int parent, int icon);
int SetText (const char* text);
int SetStatus (int status1, int status2, WCHAR* text);
int Ask (const WCHAR* message);
/* Toolbar Releated */
#define TBSTYLE_FLAT 2048
// This is the struct where the toolbar is defined
extern const TBBUTTON Buttons [];
///////////////////////////////////////////////////
//
// main.h
// main.cpp's lumber room :)
///////////////////////////////////////////////////
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include <package.h>
#include "resource.h"
/* Some Variables */
int selected, splitter_pos = 50;
pTree tree;
HMENU hPopup;
HACCEL hHotKeys;
HWND hTBar, hTree, hEdit, hStatus;
HTREEITEM nodes [MAXNODES];
/* Window Callbacks */
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK StatusProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK OptionsProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
/* Prototypes */
void Help (void);
int AddItem (int id, const char* name, int parent, int icon);
int SetText (const char* text);
int SetStatus (int status1, int status2, WCHAR* text);
int Ask (const WCHAR* message);
/* Toolbar Releated */
#define TBSTYLE_FLAT 2048
// This is the struct where the toolbar is defined
extern const TBBUTTON Buttons [];

View file

@ -1,15 +1,15 @@
#include "../lib/error.h"
#define IDI_MAIN 0
#define TBSIZE 32
#define IDB_TOOLBAR 0x102
#define IDD_OPTIONS 0x103
#define IDD_DOIT 0x104
#define IDR_POPUP 0x105
#define IDC_STATUS1 0x110
#define IDC_STATUS2 0x111
#define IDC_CANCEL 0x112
#define IDC_TSTATUS 0x113
#define IDR_HOTKEYS 0x114
#include "../lib/error.h"
#define IDI_MAIN 0
#define TBSIZE 32
#define IDB_TOOLBAR 0x102
#define IDD_OPTIONS 0x103
#define IDD_DOIT 0x104
#define IDR_POPUP 0x105
#define IDC_STATUS1 0x110
#define IDC_STATUS2 0x111
#define IDC_CANCEL 0x112
#define IDC_TSTATUS 0x113
#define IDR_HOTKEYS 0x114

View file

@ -1,168 +1,168 @@
////////////////////////////////////////////////////////
//
// download.cpp
//
// Stuff related to downloading
//
//
// Maarten Bosma, 09.01.2004
// maarten.paul@bosma.de
//
////////////////////////////////////////////////////////
#include "package.hpp"
#include "expat.h"
#include "log.h"
#include <wine/urlmon.h>
HRESULT WINAPI URLDownloadToFileA(
LPUNKNOWN pCaller,
LPCSTR szURL,
LPCSTR szFileName,
DWORD dwReserved,
LPBINDSTATUSCALLBACK lpfnCB
);
int FindCount (string What, string Where, int start = 0, int end = -1);
// Download a file
char* PML_Download (pTree tree, const char* url, const char* server = "tree", const char* filename = "packmgr.xml")
{
UINT i;
static char downl [MAX_PATH]; // the full url
static char path [MAX_PATH]; // the full resulting Path
// It goes to the temp folder when no other path is entered (or even compleatly no filename)
// If server == "tree" it will be downloaded from the server speficied in option.xml
// File:// links are possible too
// get temp dir
if(!filename)
GetTempPathA (200, path);
else if(!strstr(filename, "\\"))
GetTempPathA (200, path);
else
strcpy(path, "");
// create the local file name
if(filename)
{
strcat(path, filename);
DeleteFileA (path);
}
else
GetTempFileNameA (path, "pml", 1, path);
// get the url
if (!server)
strcpy(downl, "");
else if(!strcmp(server, "tree"))
{
char* ret;
for (i=0; i<tree->sources.size(); i++)
{
ret = PML_Download(tree, url, tree->sources[i], filename);
if(ret)
return ret;
}
return NULL;
}
else
strcpy(downl, server);
strcat(downl, url);
// is this a file link ?
if (strstr(downl, "file://") || strstr(downl, "File://"))
{
if(!filename)
{
return &downl[7];
}
else
{
CopyFileA(filename, &downl[7], FALSE);
return (char*)filename;
}
}
// download the file
if(URLDownloadToFileA (NULL, downl, path, 0, NULL) != S_OK)
{
Log("! ERROR: Unable to download ");
LogAdd(downl);
return NULL;
}
return path;
}
// Download and prozess a xml file
int PML_XmlDownload (pTree tree, const char* url, void* usrdata,
XML_StartElementHandler start, XML_EndElementHandler end, XML_CharacterDataHandler text)
{
int done = 0;
char buffer[255];
char* filename = 0;
// logging
Log("* prozess the xml file: ");
LogAdd(url);
// download the file
if(strstr(url, "file://"))
filename = PML_Download(tree, url, NULL, NULL);
else
filename = PML_Download(tree, url);
if(!filename)
{
Log("! ERROR: Could not download the xml file");
return ERR_DOWNL;
}
// open the file
FILE* file = fopen(filename, "r");
if(!file)
{
Log("! ERROR: Could not open the xml file ");
LogAdd(filename);
return ERR_GENERIC;
}
// parse the xml file
XML_Parser parser = XML_ParserCreate(NULL);
XML_SetUserData (parser, usrdata);
XML_SetElementHandler(parser, start, end);
XML_SetCharacterDataHandler(parser, text);
while (!done)
{
size_t len = fread (buffer, 1, sizeof(buffer), file);
done = len < sizeof(buffer);
buffer[len] = 0;
if(!XML_Parse(parser, buffer, len, done))
{
Log("! ERROR: Could not parse the xml file");
return ERR_GENERIC;
}
}
XML_ParserFree(parser);
fclose(file);
return ERR_OK;
}
////////////////////////////////////////////////////////
//
// download.cpp
//
// Stuff related to downloading
//
//
// Maarten Bosma, 09.01.2004
// maarten.paul@bosma.de
//
////////////////////////////////////////////////////////
#include "package.hpp"
#include "expat.h"
#include "log.h"
#include <wine/urlmon.h>
HRESULT WINAPI URLDownloadToFileA(
LPUNKNOWN pCaller,
LPCSTR szURL,
LPCSTR szFileName,
DWORD dwReserved,
LPBINDSTATUSCALLBACK lpfnCB
);
int FindCount (string What, string Where, int start = 0, int end = -1);
// Download a file
char* PML_Download (pTree tree, const char* url, const char* server = "tree", const char* filename = "packmgr.xml")
{
UINT i;
static char downl [MAX_PATH]; // the full url
static char path [MAX_PATH]; // the full resulting Path
// It goes to the temp folder when no other path is entered (or even compleatly no filename)
// If server == "tree" it will be downloaded from the server speficied in option.xml
// File:// links are possible too
// get temp dir
if(!filename)
GetTempPathA (200, path);
else if(!strstr(filename, "\\"))
GetTempPathA (200, path);
else
strcpy(path, "");
// create the local file name
if(filename)
{
strcat(path, filename);
DeleteFileA (path);
}
else
GetTempFileNameA (path, "pml", 1, path);
// get the url
if (!server)
strcpy(downl, "");
else if(!strcmp(server, "tree"))
{
char* ret;
for (i=0; i<tree->sources.size(); i++)
{
ret = PML_Download(tree, url, tree->sources[i], filename);
if(ret)
return ret;
}
return NULL;
}
else
strcpy(downl, server);
strcat(downl, url);
// is this a file link ?
if (strstr(downl, "file://") || strstr(downl, "File://"))
{
if(!filename)
{
return &downl[7];
}
else
{
CopyFileA(filename, &downl[7], FALSE);
return (char*)filename;
}
}
// download the file
if(URLDownloadToFileA (NULL, downl, path, 0, NULL) != S_OK)
{
Log("! ERROR: Unable to download ");
LogAdd(downl);
return NULL;
}
return path;
}
// Download and prozess a xml file
int PML_XmlDownload (pTree tree, const char* url, void* usrdata,
XML_StartElementHandler start, XML_EndElementHandler end, XML_CharacterDataHandler text)
{
int done = 0;
char buffer[255];
char* filename = 0;
// logging
Log("* prozess the xml file: ");
LogAdd(url);
// download the file
if(strstr(url, "file://"))
filename = PML_Download(tree, url, NULL, NULL);
else
filename = PML_Download(tree, url);
if(!filename)
{
Log("! ERROR: Could not download the xml file");
return ERR_DOWNL;
}
// open the file
FILE* file = fopen(filename, "r");
if(!file)
{
Log("! ERROR: Could not open the xml file ");
LogAdd(filename);
return ERR_GENERIC;
}
// parse the xml file
XML_Parser parser = XML_ParserCreate(NULL);
XML_SetUserData (parser, usrdata);
XML_SetElementHandler(parser, start, end);
XML_SetCharacterDataHandler(parser, text);
while (!done)
{
size_t len = fread (buffer, 1, sizeof(buffer), file);
done = len < sizeof(buffer);
buffer[len] = 0;
if(!XML_Parse(parser, buffer, len, done))
{
Log("! ERROR: Could not parse the xml file");
return ERR_GENERIC;
}
}
XML_ParserFree(parser);
fclose(file);
return ERR_OK;
}

View file

@ -1,20 +1,20 @@
// error.h
#define ERR_OK 0x000
#define ERR_GENERIC 0x001
#define ERR_DOWNL 0x002
#define ERR_NOTODO 0x003 // without text yet
#define ERR_PACK 0x004
#define ERR_DEP1 0x005
#define ERR_DEP2 0x006
#define ERR_READY 0x007
// Script
#define ERR_SYNATX 0x011
#define ERR_CALL 0x012
#define ERR_PARAMETER 0x013
#define ERR_FILE 0x014
#define IDS_LOAD 0x254
#define NOTFOUND -1
// error.h
#define ERR_OK 0x000
#define ERR_GENERIC 0x001
#define ERR_DOWNL 0x002
#define ERR_NOTODO 0x003 // without text yet
#define ERR_PACK 0x004
#define ERR_DEP1 0x005
#define ERR_DEP2 0x006
#define ERR_READY 0x007
// Script
#define ERR_SYNATX 0x011
#define ERR_CALL 0x012
#define ERR_PARAMETER 0x013
#define ERR_FILE 0x014
#define IDS_LOAD 0x254
#define NOTFOUND -1

File diff suppressed because it is too large Load diff

View file

@ -1,101 +1,101 @@
////////////////////////////////////////////////////////
//
// functions.cpp
//
// Script Functions
//
//
// Klemens Friedl, 19.03.2005
// frik85@hotmail.com
//
////////////////////////////////////////////////////////////////////
#include "package.hpp"
#include "script.h"
#include "log.h"
extern const char* tree_server;
char* PML_Download (pTree, const char* url, const char* server, const char* filename);
int debuglog (int argc, char* argv[])
{
Log("! SCRIPT DEBUG: ");
LogAdd(argv[1]);
return ERR_OK;
}
int download (int argc, char* argv[])
{
char* result;
if (argc==3)
result = PML_Download(NULL, argv[1], argv[3], argv[2]);
else if (argc==2)
result = PML_Download(NULL, argv[1], NULL, argv[2]);
else
return ERR_GENERIC;
if(!result)
return ERR_GENERIC;
return ERR_OK;
}
int extract (int argc, char* argv[])
{
return ERR_OK;
}
int msgbox (int argc, char* argv[])
{
if (argc==1)
MessageBoxA(0,argv[1],0,0);
else if (argc==2)
MessageBoxA(0,argv[1],argv[2],0);
else
return ERR_GENERIC;
return ERR_OK;
}
int shell (int argc, char* argv[])
{
// Get the temp dir
char tmp [MAX_PATH];
GetTempPathA (MAX_PATH, tmp);
SHELLEXECUTEINFOA info = {0};
info.cbSize = sizeof(SHELLEXECUTEINFO);
info.fMask = SEE_MASK_NOCLOSEPROCESS;
info.lpVerb = "open";
info.lpFile = argv[1];
info.lpDirectory = tmp;
info.nShow = SW_SHOW;
if(argc >= 2)
info.lpParameters = "";
if(!ShellExecuteExA (&info))
return ERR_GENERIC;
WaitForSingleObject (info.hProcess, INFINITE);
return ERR_OK;
}
const FUNC_TABLE FuncTable[] =
{
/* Name */ /* Function */
{"download", download},
{"extract", extract},
{"shell", shell},
{"msgbox", msgbox},
{"debug", debuglog}
};
////////////////////////////////////////////////////////
//
// functions.cpp
//
// Script Functions
//
//
// Klemens Friedl, 19.03.2005
// frik85@hotmail.com
//
////////////////////////////////////////////////////////////////////
#include "package.hpp"
#include "script.h"
#include "log.h"
extern const char* tree_server;
char* PML_Download (pTree, const char* url, const char* server, const char* filename);
int debuglog (int argc, char* argv[])
{
Log("! SCRIPT DEBUG: ");
LogAdd(argv[1]);
return ERR_OK;
}
int download (int argc, char* argv[])
{
char* result;
if (argc==3)
result = PML_Download(NULL, argv[1], argv[3], argv[2]);
else if (argc==2)
result = PML_Download(NULL, argv[1], NULL, argv[2]);
else
return ERR_GENERIC;
if(!result)
return ERR_GENERIC;
return ERR_OK;
}
int extract (int argc, char* argv[])
{
return ERR_OK;
}
int msgbox (int argc, char* argv[])
{
if (argc==1)
MessageBoxA(0,argv[1],0,0);
else if (argc==2)
MessageBoxA(0,argv[1],argv[2],0);
else
return ERR_GENERIC;
return ERR_OK;
}
int shell (int argc, char* argv[])
{
// Get the temp dir
char tmp [MAX_PATH];
GetTempPathA (MAX_PATH, tmp);
SHELLEXECUTEINFOA info = {0};
info.cbSize = sizeof(SHELLEXECUTEINFO);
info.fMask = SEE_MASK_NOCLOSEPROCESS;
info.lpVerb = "open";
info.lpFile = argv[1];
info.lpDirectory = tmp;
info.nShow = SW_SHOW;
if(argc >= 2)
info.lpParameters = "";
if(!ShellExecuteExA (&info))
return ERR_GENERIC;
WaitForSingleObject (info.hProcess, INFINITE);
return ERR_OK;
}
const FUNC_TABLE FuncTable[] =
{
/* Name */ /* Function */
{"download", download},
{"extract", extract},
{"shell", shell},
{"msgbox", msgbox},
{"debug", debuglog}
};

View file

@ -1,117 +1,117 @@
////////////////////////////////////////////////////////
//
// log.cpp
//
// Script Functions
//
//
// Klemens Friedl, 19.03.2005
// frik85@hotmail.com
//
////////////////////////////////////////////////////////////////////
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <windows.h>
#include "log.h"
#include "package.hpp" // for Package Manager version
#include <reactos/version.h> // ReactOS version: \reactos\include\reactos\version.h
bool LogCreated = false;
void Log (const char *message)
{
FILE *file;
char GTime[80];
char version[50];
char versionos[50];
if (!LogCreated)
{
file = fopen(LOGFILE, "w");
LogCreated = true;
//HTML Header
fputs("<html><head><title>Logfile</title></head><body>\n", file);
// date and time
time_t now;
now = time(NULL);
strftime(GTime,sizeof GTime,"%Y-%m-%d",localtime(&now));
// package manager version information
wsprintfA(version, " Package Manager %d.%d.%d",
PACKMGR_VERSION_MAJOR,
PACKMGR_VERSION_MINOR,
PACKMGR_VERSION_PATCH_LEVEL);
// operating system version information
wsprintfA(versionos, " ReactOS %d.%d.%d",
KERNEL_VERSION_MAJOR,
KERNEL_VERSION_MINOR,
KERNEL_VERSION_PATCH_LEVEL);
// write the head
fputs("<h2>ReactOS Package Manager - Log File</h2>\n", file);
//fputs("WARNING: This is still pre-alpha software.<br>\n", file);
fputs("Date: ", file);
fputs(GTime, file);
fputs("<br>\n", file);
fputs("Version: ", file);
fputs(version, file);
fputs("<br>\n", file);
fputs("OS: ", file);
fputs(versionos, file);
fputs("<br>\n", file);
}
else
file = fopen(LOGFILE, "a");
if (file == NULL)
{
if (LogCreated)
LogCreated = false;
return Log(message);
}
else
{
// Save log entry (+ add time)
fputs("<br>\n", file);
time_t now;
now = time(NULL);
strftime(GTime,sizeof GTime,"%I:%M:%S %p",localtime(&now));
fputs("<b>", file);
fputs(GTime, file);
fputs("</b> ", file);
fputs(message, file);
fclose(file);
}
if (file)
fclose(file);
}
void LogAdd (const char *message)
{
FILE *file;
file = fopen(LOGFILE, "a");
// Save log entry
fputs(message, file);
fclose(file);
if (file)
fclose(file);
}
////////////////////////////////////////////////////////
//
// log.cpp
//
// Script Functions
//
//
// Klemens Friedl, 19.03.2005
// frik85@hotmail.com
//
////////////////////////////////////////////////////////////////////
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <windows.h>
#include "log.h"
#include "package.hpp" // for Package Manager version
#include <reactos/version.h> // ReactOS version: \reactos\include\reactos\version.h
bool LogCreated = false;
void Log (const char *message)
{
FILE *file;
char GTime[80];
char version[50];
char versionos[50];
if (!LogCreated)
{
file = fopen(LOGFILE, "w");
LogCreated = true;
//HTML Header
fputs("<html><head><title>Logfile</title></head><body>\n", file);
// date and time
time_t now;
now = time(NULL);
strftime(GTime,sizeof GTime,"%Y-%m-%d",localtime(&now));
// package manager version information
wsprintfA(version, " Package Manager %d.%d.%d",
PACKMGR_VERSION_MAJOR,
PACKMGR_VERSION_MINOR,
PACKMGR_VERSION_PATCH_LEVEL);
// operating system version information
wsprintfA(versionos, " ReactOS %d.%d.%d",
KERNEL_VERSION_MAJOR,
KERNEL_VERSION_MINOR,
KERNEL_VERSION_PATCH_LEVEL);
// write the head
fputs("<h2>ReactOS Package Manager - Log File</h2>\n", file);
//fputs("WARNING: This is still pre-alpha software.<br>\n", file);
fputs("Date: ", file);
fputs(GTime, file);
fputs("<br>\n", file);
fputs("Version: ", file);
fputs(version, file);
fputs("<br>\n", file);
fputs("OS: ", file);
fputs(versionos, file);
fputs("<br>\n", file);
}
else
file = fopen(LOGFILE, "a");
if (file == NULL)
{
if (LogCreated)
LogCreated = false;
return Log(message);
}
else
{
// Save log entry (+ add time)
fputs("<br>\n", file);
time_t now;
now = time(NULL);
strftime(GTime,sizeof GTime,"%I:%M:%S %p",localtime(&now));
fputs("<b>", file);
fputs(GTime, file);
fputs("</b> ", file);
fputs(message, file);
fclose(file);
}
if (file)
fclose(file);
}
void LogAdd (const char *message)
{
FILE *file;
file = fopen(LOGFILE, "a");
// Save log entry
fputs(message, file);
fclose(file);
if (file)
fclose(file);
}

View file

@ -1,21 +1,21 @@
////////////////////////////////////////////////////////
//
// log.h
//
// Script Functions
//
//
// Klemens Friedl, 19.03.2005
// frik85@hotmail.com
//
////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <string.h>
#define LOGFILE "logfile.html"
extern bool LogCreated;
void Log (const char *message);
void LogAdd (const char *message);
////////////////////////////////////////////////////////
//
// log.h
//
// Script Functions
//
//
// Klemens Friedl, 19.03.2005
// frik85@hotmail.com
//
////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <string.h>
#define LOGFILE "logfile.html"
extern bool LogCreated;
void Log (const char *message);
void LogAdd (const char *message);

View file

@ -1,192 +1,192 @@
////////////////////////////////////////////////////////
//
// main.cpp
//
// Doit stuff and
// everything that fits nowhere else.
//
//
// Maarten Bosma, 09.01.2004
// maarten.paul@bosma.de
//
////////////////////////////////////////////////////////////////////
#include <windows.h>
#include "package.hpp"
#include "log.h"
#include "script.h"
HANDLE hThread = NULL;
BOOL thread_abort = FALSE;
char* PML_Download (pTree, const char* url, const char* server = "tree", const char* filename = NULL);
// Abort other thread
extern "C" void PML_Abort (void)
{
thread_abort = TRUE;
if(hThread)
WaitForSingleObject(hThread, INFINITE);
}
// Callback function of the "doit"-thread
DWORD WINAPI DoitThread (void* lpParam)
{
UINT i;
int ret = ERR_OK;
TREE* tree = (TREE*)lpParam;
vector<SCRIPT*> scripts;
/* Load the scripts */
tree->setStatus(0, 0, L"Downloading Install instructions ...");
for(i=0; i<tree->todo.size(); i++)
{
SCRIPT* script;
char* path = PML_Download(tree, tree->todo[i]);
if(RPS_Load(&script, path) == ERR_OK)
scripts.push_back(script);
else
ret = ERR_PACK;
}
/* Preinstall */
Log("* enter preinstall");
tree->setStatus(250, 0, L"Preinstall");
for(i=0; i<scripts.size(); i++)
{
if(RPS_Execute(scripts[i], "preinstall") != ERR_OK)
ret = ERR_PACK;
}
/* Install */
Log("* enter install");
tree->setStatus(500, 0, L"Install");
for(i=0; i<scripts.size(); i++)
{
if(RPS_Execute(scripts[i], "main") != ERR_OK)
ret = ERR_PACK;
}
/* Postinstall */
Log("* enter postinstall");
tree->setStatus(750, 0, L"Postinstall");
for(i=0; i<scripts.size(); i++)
{
if(RPS_Execute(scripts[i], "after") != ERR_OK)
ret = ERR_PACK;
}
/* Finish */
for(i=0; i<tree->todo.size(); i++)
RPS_Clear(scripts[i]);
// clear the todo list
tree->todo.clear();
// set all actions to none
for(i=0; i<tree->packages.size(); i++)
PML_SetAction (tree, i, 0, tree->setIcon, NULL);
tree->setStatus(1000, ret, NULL);
return 1;
}
// Do the actions the user wants us to do
extern "C" int PML_DoIt (TREE* tree, PML_SetStatus SetStatus, PML_Ask Ask)
{
DWORD dummy;
tree->setStatus = SetStatus;
if(!tree->todo.size())
return ERR_NOTODO;
//ask
WCHAR buffer [2000];
wsprintf(buffer, PML_TransError(ERR_READY), tree->todo.size());
if(!Ask(buffer))
return ERR_GENERIC;
hThread = CreateThread(NULL, 0, DoitThread, tree, 0, &dummy);
if(!hThread)
return ERR_GENERIC;
LogAdd("\n");
return ERR_OK;
}
// Translates Errorcode into human language
extern "C" WCHAR* PML_TransError (int code)
{
// I know we, got a memory leak here
static WCHAR string [256];
if(!LoadString(GetModuleHandle(L"package"), code, string, 256))
return PML_TransError(ERR_GENERIC);
return string;
}
// Free alloced memory
extern "C" void PML_CloseTree (TREE* tree)
{
UINT i;
LogAdd ("\n");
Log("* free alloced memory");
Log("* package manager will exit now. Bye!");
for(i=0; i<tree->packages.size(); i++)
{
if(tree->packages[i].path)
delete tree->packages[i].path;
if(tree->packages[i].name)
delete tree->packages[i].name;
if(tree->packages[i].description)
delete tree->packages[i].description;
tree->packages.clear();
if(tree->packages[i].files[0])
delete tree->packages[i].files[0];
if(tree->packages[i].files[1])
delete tree->packages[i].files[1];
if(tree->packages[i].files[2])
delete tree->packages[i].files[2];
if(tree->packages[i].files[3])
delete tree->packages[i].files[3];
}
tree->descriptionPath.clear();
tree->todo.clear();
tree->packages.clear();
if(tree)
delete tree;
}
////////////////////////////////////////////////////////
//
// main.cpp
//
// Doit stuff and
// everything that fits nowhere else.
//
//
// Maarten Bosma, 09.01.2004
// maarten.paul@bosma.de
//
////////////////////////////////////////////////////////////////////
#include <windows.h>
#include "package.hpp"
#include "log.h"
#include "script.h"
HANDLE hThread = NULL;
BOOL thread_abort = FALSE;
char* PML_Download (pTree, const char* url, const char* server = "tree", const char* filename = NULL);
// Abort other thread
extern "C" void PML_Abort (void)
{
thread_abort = TRUE;
if(hThread)
WaitForSingleObject(hThread, INFINITE);
}
// Callback function of the "doit"-thread
DWORD WINAPI DoitThread (void* lpParam)
{
UINT i;
int ret = ERR_OK;
TREE* tree = (TREE*)lpParam;
vector<SCRIPT*> scripts;
/* Load the scripts */
tree->setStatus(0, 0, L"Downloading Install instructions ...");
for(i=0; i<tree->todo.size(); i++)
{
SCRIPT* script;
char* path = PML_Download(tree, tree->todo[i]);
if(RPS_Load(&script, path) == ERR_OK)
scripts.push_back(script);
else
ret = ERR_PACK;
}
/* Preinstall */
Log("* enter preinstall");
tree->setStatus(250, 0, L"Preinstall");
for(i=0; i<scripts.size(); i++)
{
if(RPS_Execute(scripts[i], "preinstall") != ERR_OK)
ret = ERR_PACK;
}
/* Install */
Log("* enter install");
tree->setStatus(500, 0, L"Install");
for(i=0; i<scripts.size(); i++)
{
if(RPS_Execute(scripts[i], "main") != ERR_OK)
ret = ERR_PACK;
}
/* Postinstall */
Log("* enter postinstall");
tree->setStatus(750, 0, L"Postinstall");
for(i=0; i<scripts.size(); i++)
{
if(RPS_Execute(scripts[i], "after") != ERR_OK)
ret = ERR_PACK;
}
/* Finish */
for(i=0; i<tree->todo.size(); i++)
RPS_Clear(scripts[i]);
// clear the todo list
tree->todo.clear();
// set all actions to none
for(i=0; i<tree->packages.size(); i++)
PML_SetAction (tree, i, 0, tree->setIcon, NULL);
tree->setStatus(1000, ret, NULL);
return 1;
}
// Do the actions the user wants us to do
extern "C" int PML_DoIt (TREE* tree, PML_SetStatus SetStatus, PML_Ask Ask)
{
DWORD dummy;
tree->setStatus = SetStatus;
if(!tree->todo.size())
return ERR_NOTODO;
//ask
WCHAR buffer [2000];
wsprintf(buffer, PML_TransError(ERR_READY), tree->todo.size());
if(!Ask(buffer))
return ERR_GENERIC;
hThread = CreateThread(NULL, 0, DoitThread, tree, 0, &dummy);
if(!hThread)
return ERR_GENERIC;
LogAdd("\n");
return ERR_OK;
}
// Translates Errorcode into human language
extern "C" WCHAR* PML_TransError (int code)
{
// I know we, got a memory leak here
static WCHAR string [256];
if(!LoadString(GetModuleHandle(L"package"), code, string, 256))
return PML_TransError(ERR_GENERIC);
return string;
}
// Free alloced memory
extern "C" void PML_CloseTree (TREE* tree)
{
UINT i;
LogAdd ("\n");
Log("* free alloced memory");
Log("* package manager will exit now. Bye!");
for(i=0; i<tree->packages.size(); i++)
{
if(tree->packages[i].path)
delete tree->packages[i].path;
if(tree->packages[i].name)
delete tree->packages[i].name;
if(tree->packages[i].description)
delete tree->packages[i].description;
tree->packages.clear();
if(tree->packages[i].files[0])
delete tree->packages[i].files[0];
if(tree->packages[i].files[1])
delete tree->packages[i].files[1];
if(tree->packages[i].files[2])
delete tree->packages[i].files[2];
if(tree->packages[i].files[3])
delete tree->packages[i].files[3];
}
tree->descriptionPath.clear();
tree->todo.clear();
tree->packages.clear();
if(tree)
delete tree;
}

View file

@ -1,101 +1,101 @@
////////////////////////////////////////////////////////
//
// options.cpp
//
// Settting and Loading Options
//
//
// Maarten Bosma, 09.01.2004
// maarten.paul@bosma.de
//
////////////////////////////////////////////////////////////////////
#include "package.hpp"
#include "log.h"
#include "expat.h"
#include <fstream>
int PML_XmlDownload (pTree tree, const char* url, void* usrdata,
XML_StartElementHandler start, XML_EndElementHandler end, XML_CharacterDataHandler text) ;
// expat callback for start of a "node" tag
void opt_start (void* usrdata, const char* tag, const char** arg)
{
TREE* tree = (TREE*)usrdata;
if (!strcmp(tag, "source"))
{
tree->sources.push_back((char*)NULL);
tree->field = &tree->sources.back();
}
}
// expat callback for end of a "node" tag
void opt_end (void* usrdata, const char* tag)
{
TREE* tree = (TREE*)usrdata;
tree->field = NULL;
}
// expat callback for end of a "node" tag
void opt_text (void* usrdata, const char* data, int len)
{
TREE* tree = (TREE*)usrdata;
if(!tree->field)
return;
*tree->field = new char[len+1];
strncpy(*tree->field, data, len);
(*tree->field)[len] = '\0';
}
// ! ! ! F I X M E ! ! ! //
/*
int CreateOptions (TREE* tree)
{
ofstream file ("options.xml");
Log("* Creating options.xml from Resources");
HRSRC hres = FindResource(GetModuleHandle(L"package"), MAKEINTRESOURCE(123), RT_RCDATA);
if (!hres)
{
Log("! ERROR: Could not load it !");
return ERR_GENERIC;
}
MessageBox(0,(WCHAR*)LockResource(LoadResource(NULL, hres)), 0, 0); // is empty
//file << (WCHAR*)LockResource(LoadResource(NULL, hres));
return ERR_OK;
}
*/
char* PML_Download (pTree, const char* url, const char* server, const char* filename);
int CreateOptions (TREE* tree)
{
Log("* Load options.xml from the Internet (Temporary Hack)");
CopyFileA( PML_Download(tree, "http://svn.reactos.com/viewcvs/*checkout*/trunk/rosapps/packmgr/lib/options.xml", NULL, "options.xml"), "options.xml", TRUE);
return ERR_OK;
}
int LoadOptions (TREE* tree)
{
int error;
error = PML_XmlDownload(tree, "file://options.xml", (void*)tree, opt_start, opt_end, opt_text);
if(!error)
return ERR_OK;
CreateOptions(tree);
return PML_XmlDownload(tree, "file://options.xml", (void*)tree, opt_start, opt_end, opt_text);
}
////////////////////////////////////////////////////////
//
// options.cpp
//
// Settting and Loading Options
//
//
// Maarten Bosma, 09.01.2004
// maarten.paul@bosma.de
//
////////////////////////////////////////////////////////////////////
#include "package.hpp"
#include "log.h"
#include "expat.h"
#include <fstream>
int PML_XmlDownload (pTree tree, const char* url, void* usrdata,
XML_StartElementHandler start, XML_EndElementHandler end, XML_CharacterDataHandler text) ;
// expat callback for start of a "node" tag
void opt_start (void* usrdata, const char* tag, const char** arg)
{
TREE* tree = (TREE*)usrdata;
if (!strcmp(tag, "source"))
{
tree->sources.push_back((char*)NULL);
tree->field = &tree->sources.back();
}
}
// expat callback for end of a "node" tag
void opt_end (void* usrdata, const char* tag)
{
TREE* tree = (TREE*)usrdata;
tree->field = NULL;
}
// expat callback for end of a "node" tag
void opt_text (void* usrdata, const char* data, int len)
{
TREE* tree = (TREE*)usrdata;
if(!tree->field)
return;
*tree->field = new char[len+1];
strncpy(*tree->field, data, len);
(*tree->field)[len] = '\0';
}
// ! ! ! F I X M E ! ! ! //
/*
int CreateOptions (TREE* tree)
{
ofstream file ("options.xml");
Log("* Creating options.xml from Resources");
HRSRC hres = FindResource(GetModuleHandle(L"package"), MAKEINTRESOURCE(123), RT_RCDATA);
if (!hres)
{
Log("! ERROR: Could not load it !");
return ERR_GENERIC;
}
MessageBox(0,(WCHAR*)LockResource(LoadResource(NULL, hres)), 0, 0); // is empty
//file << (WCHAR*)LockResource(LoadResource(NULL, hres));
return ERR_OK;
}
*/
char* PML_Download (pTree, const char* url, const char* server, const char* filename);
int CreateOptions (TREE* tree)
{
Log("* Load options.xml from the Internet (Temporary Hack)");
CopyFileA( PML_Download(tree, "http://svn.reactos.com/viewcvs/*checkout*/trunk/rosapps/packmgr/lib/options.xml", NULL, "options.xml"), "options.xml", TRUE);
return ERR_OK;
}
int LoadOptions (TREE* tree)
{
int error;
error = PML_XmlDownload(tree, "file://options.xml", (void*)tree, opt_start, opt_end, opt_text);
if(!error)
return ERR_OK;
CreateOptions(tree);
return PML_XmlDownload(tree, "file://options.xml", (void*)tree, opt_start, opt_end, opt_text);
}

View file

@ -1,288 +1,288 @@
////////////////////////////////////////////////////////
//
// package.cpp
//
// package related functions
//
//
// Maarten Bosma, 09.01.2004
// maarten.paul@bosma.de
//
////////////////////////////////////////////////////////////////////
#include "package.hpp"
#include "expat.h"
#include "log.h"
int PML_XmlDownload (pTree, const char* url, void* usrdata, XML_StartElementHandler start,
XML_EndElementHandler end, XML_CharacterDataHandler text=0);
// expat callback for start of a package tag
void pack_start (void* usrdata, const char* tag, const char** arg)
{
int i, id;
PACKAGE* pack = (PACKAGE*)usrdata;
// if the tag is a script tag ...
if(!strcmp(tag, "scripts"))
{
// ... read the arguments
for (i=0; arg[i]; i+=2)
{
if(!strcmp(arg[i], "inst"))
id = 0;
else if(!strcmp(arg[i], "update"))
id = 1;
else if(!strcmp(arg[i], "uinst"))
id = 2;
else if(!strcmp(arg[i], "srcinst"))
id = 3;
else
continue;
pack->files[id] = new char [strlen(arg[i+1])+1];
strcpy(pack->files[id], arg[i+1]);
}
}
// ... save the field
else
{
if(!strcmp(tag, "name"))
pack->field = &pack->name;
else if(!strcmp(tag, "description"))
pack->field = &pack->description;
else if (!strcmp(tag, "depent"))
{
pack->depencies.push_back((char*)NULL);
pack->field = &pack->depencies.back();
}
}
}
// expat callback for end of a package tag
void pack_end (void* usrdata, const char* tag)
{
PACKAGE* pack = (PACKAGE*)usrdata;
pack->field = NULL;
}
// expat callback for text
void pack_text (void* usrdata, const char* data, int len)
{
PACKAGE* pack = (PACKAGE*)usrdata;
if(!pack->field)
return;
*pack->field = new char[len+1];
strncpy(*pack->field, data, len);
(*pack->field)[len] = '\0';
}
// The user clicks on a package
extern "C" int PML_LoadPackage (TREE* tree, int id, PML_SetButton SetButton)
{
PACKAGE* pack = &tree->packages[id];
tree->setButton = SetButton;
if(SetButton)
{
SetButton(1, pack->action);
SetButton(2, pack->inst); // && pack->action != 0
SetButton(3, pack->src_inst);
SetButton(4, pack->update);
SetButton(5, pack->uninstall);
}
// root notes (like network) return here
if(!pack->path)
return 1;
if(!pack->loaded)
{
PML_XmlDownload (tree, pack->path, (void*)pack, pack_start, pack_end, pack_text);
pack->loaded = TRUE;
}
return ERR_OK;
}
extern "C" int PML_FindItem (TREE* tree, const char* what)
{
int i, j;
bool found;
// if we have children, same action for them
for (i=1; (UINT)i<tree->packages.size(); i++)
{
found = true;
for(j=0; (UINT)j<strlen(what); j++)
{
if(tolower(what[j]) != tolower(tree->packages[i].name[j]))
{
found = false;
break;
}
}
if(found)
return i;
}
return 0;
}
// The user chooses a actions like Install
extern "C" int PML_SetAction (TREE* tree, int id, int action, PML_SetIcon SetIcon, PML_Ask Ask)
{
UINT i;
int ret = ERR_OK;
tree->setIcon = SetIcon;
PACKAGE* pack = &tree->packages[id];
// if we have children, same action for them
for (i=0; i<pack->children.size(); i++)
ret = ret || PML_SetAction(tree, pack->children[i], action, SetIcon, Ask);
// is the action possible ?
if(!pack->actions[action])
return ERR_GENERIC;
// is it already set
if(pack->action == action)
return ERR_OK;
//
if(pack->depencies.size() && action)
{
UINT count = pack->depencies.size();
WCHAR buffer[2000], buffer2[200];
wcscpy(buffer, PML_TransError(ERR_DEP1));
for (i=0; i<pack->depencies.size(); i++)
{
int item = PML_FindItem(tree, pack->depencies[i]);
if(!item)
return ERR_GENERIC;
if(action == tree->packages[item].action)// || tree->packages[item].installed
{
count--;
continue;
}
MultiByteToWideChar (CP_ACP, 0, pack->depencies[i], strlen(pack->depencies[i])+1, buffer2, 200);
wsprintf(buffer, L"%s - %s\n", buffer, buffer2);//
}
wcscat(buffer, PML_TransError(ERR_DEP2));
if(count)
{
if(!Ask(buffer))
return ERR_GENERIC;
for (i=0; i<pack->depencies.size(); i++)
{
int item = PML_FindItem(tree, pack->depencies[i]);
tree->packages[item].neededBy.push_back(id);
PML_SetAction(tree, item, action, SetIcon, Ask);
}
}
}
// load it if it's not loaded yet
else if (!pack->loaded && pack->path)
{
PML_XmlDownload (tree, pack->path, (void*)pack, pack_start, pack_end, pack_text);
pack->loaded = TRUE;
return PML_SetAction(tree, id, action, SetIcon, Ask);
}
// set the icon
if(SetIcon && !pack->icon)
SetIcon(id, action);
// set the button(s)
if(tree->setButton && action != 2)
{
tree->setButton(1, action);
//tree->setButton(pack->action+1, action);
}
// can't do src install yet
if(action == 2)
{
MessageBox(0, L"Sorry, but source install is not implemented yet.", 0,0);
return ERR_OK;
}
// everything but undoing is done here
else if (action != 0)
{
// since we are setting a action we undo it again
if(tree->setButton)
tree->setButton(1, 1);
//tree->setButton(action+1, 0);
pack->action = action;
// root notes (like network) return here
if(!pack->path)
return ret;
// save the name of the corresponding script in a vector
tree->todo.push_back(pack->files[action-1]);
}
// undoing
else
{
for(i=0; i<pack->neededBy.size(); i++)
{
if(tree->packages[pack->neededBy[i]].action)
{
SetIcon(id, pack->action);
return ERR_GENERIC;
}
}
// root notes (like network) return here
if(!pack->path || pack->action==0)
return ret;
// erase from todo list
for(i=0; i<tree->todo.size(); i++)
if(!strcmp(tree->todo[i], pack->files[pack->action-1])) // look for right entry
tree->todo.erase(tree->todo.begin()+i); // delete it
// set action back
pack->action = 0;
}
return ret;
}
//
extern "C" char* PML_GetDescription (TREE* tree, int id)
{
PML_LoadPackage(tree, id, NULL);
return tree->packages[id].description;
}
////////////////////////////////////////////////////////
//
// package.cpp
//
// package related functions
//
//
// Maarten Bosma, 09.01.2004
// maarten.paul@bosma.de
//
////////////////////////////////////////////////////////////////////
#include "package.hpp"
#include "expat.h"
#include "log.h"
int PML_XmlDownload (pTree, const char* url, void* usrdata, XML_StartElementHandler start,
XML_EndElementHandler end, XML_CharacterDataHandler text=0);
// expat callback for start of a package tag
void pack_start (void* usrdata, const char* tag, const char** arg)
{
int i, id;
PACKAGE* pack = (PACKAGE*)usrdata;
// if the tag is a script tag ...
if(!strcmp(tag, "scripts"))
{
// ... read the arguments
for (i=0; arg[i]; i+=2)
{
if(!strcmp(arg[i], "inst"))
id = 0;
else if(!strcmp(arg[i], "update"))
id = 1;
else if(!strcmp(arg[i], "uinst"))
id = 2;
else if(!strcmp(arg[i], "srcinst"))
id = 3;
else
continue;
pack->files[id] = new char [strlen(arg[i+1])+1];
strcpy(pack->files[id], arg[i+1]);
}
}
// ... save the field
else
{
if(!strcmp(tag, "name"))
pack->field = &pack->name;
else if(!strcmp(tag, "description"))
pack->field = &pack->description;
else if (!strcmp(tag, "depent"))
{
pack->depencies.push_back((char*)NULL);
pack->field = &pack->depencies.back();
}
}
}
// expat callback for end of a package tag
void pack_end (void* usrdata, const char* tag)
{
PACKAGE* pack = (PACKAGE*)usrdata;
pack->field = NULL;
}
// expat callback for text
void pack_text (void* usrdata, const char* data, int len)
{
PACKAGE* pack = (PACKAGE*)usrdata;
if(!pack->field)
return;
*pack->field = new char[len+1];
strncpy(*pack->field, data, len);
(*pack->field)[len] = '\0';
}
// The user clicks on a package
extern "C" int PML_LoadPackage (TREE* tree, int id, PML_SetButton SetButton)
{
PACKAGE* pack = &tree->packages[id];
tree->setButton = SetButton;
if(SetButton)
{
SetButton(1, pack->action);
SetButton(2, pack->inst); // && pack->action != 0
SetButton(3, pack->src_inst);
SetButton(4, pack->update);
SetButton(5, pack->uninstall);
}
// root notes (like network) return here
if(!pack->path)
return 1;
if(!pack->loaded)
{
PML_XmlDownload (tree, pack->path, (void*)pack, pack_start, pack_end, pack_text);
pack->loaded = TRUE;
}
return ERR_OK;
}
extern "C" int PML_FindItem (TREE* tree, const char* what)
{
int i, j;
bool found;
// if we have children, same action for them
for (i=1; (UINT)i<tree->packages.size(); i++)
{
found = true;
for(j=0; (UINT)j<strlen(what); j++)
{
if(tolower(what[j]) != tolower(tree->packages[i].name[j]))
{
found = false;
break;
}
}
if(found)
return i;
}
return 0;
}
// The user chooses a actions like Install
extern "C" int PML_SetAction (TREE* tree, int id, int action, PML_SetIcon SetIcon, PML_Ask Ask)
{
UINT i;
int ret = ERR_OK;
tree->setIcon = SetIcon;
PACKAGE* pack = &tree->packages[id];
// if we have children, same action for them
for (i=0; i<pack->children.size(); i++)
ret = ret || PML_SetAction(tree, pack->children[i], action, SetIcon, Ask);
// is the action possible ?
if(!pack->actions[action])
return ERR_GENERIC;
// is it already set
if(pack->action == action)
return ERR_OK;
//
if(pack->depencies.size() && action)
{
UINT count = pack->depencies.size();
WCHAR buffer[2000], buffer2[200];
wcscpy(buffer, PML_TransError(ERR_DEP1));
for (i=0; i<pack->depencies.size(); i++)
{
int item = PML_FindItem(tree, pack->depencies[i]);
if(!item)
return ERR_GENERIC;
if(action == tree->packages[item].action)// || tree->packages[item].installed
{
count--;
continue;
}
MultiByteToWideChar (CP_ACP, 0, pack->depencies[i], strlen(pack->depencies[i])+1, buffer2, 200);
wsprintf(buffer, L"%s - %s\n", buffer, buffer2);//
}
wcscat(buffer, PML_TransError(ERR_DEP2));
if(count)
{
if(!Ask(buffer))
return ERR_GENERIC;
for (i=0; i<pack->depencies.size(); i++)
{
int item = PML_FindItem(tree, pack->depencies[i]);
tree->packages[item].neededBy.push_back(id);
PML_SetAction(tree, item, action, SetIcon, Ask);
}
}
}
// load it if it's not loaded yet
else if (!pack->loaded && pack->path)
{
PML_XmlDownload (tree, pack->path, (void*)pack, pack_start, pack_end, pack_text);
pack->loaded = TRUE;
return PML_SetAction(tree, id, action, SetIcon, Ask);
}
// set the icon
if(SetIcon && !pack->icon)
SetIcon(id, action);
// set the button(s)
if(tree->setButton && action != 2)
{
tree->setButton(1, action);
//tree->setButton(pack->action+1, action);
}
// can't do src install yet
if(action == 2)
{
MessageBox(0, L"Sorry, but source install is not implemented yet.", 0,0);
return ERR_OK;
}
// everything but undoing is done here
else if (action != 0)
{
// since we are setting a action we undo it again
if(tree->setButton)
tree->setButton(1, 1);
//tree->setButton(action+1, 0);
pack->action = action;
// root notes (like network) return here
if(!pack->path)
return ret;
// save the name of the corresponding script in a vector
tree->todo.push_back(pack->files[action-1]);
}
// undoing
else
{
for(i=0; i<pack->neededBy.size(); i++)
{
if(tree->packages[pack->neededBy[i]].action)
{
SetIcon(id, pack->action);
return ERR_GENERIC;
}
}
// root notes (like network) return here
if(!pack->path || pack->action==0)
return ret;
// erase from todo list
for(i=0; i<tree->todo.size(); i++)
if(!strcmp(tree->todo[i], pack->files[pack->action-1])) // look for right entry
tree->todo.erase(tree->todo.begin()+i); // delete it
// set action back
pack->action = 0;
}
return ret;
}
//
extern "C" char* PML_GetDescription (TREE* tree, int id)
{
PML_LoadPackage(tree, id, NULL);
return tree->packages[id].description;
}

View file

@ -1,47 +1,47 @@
////////////////////////////////////////////////
//
// package.hpp
// Package C++ Header
////////////////////////////////////////////////
#include <windows.h>
#include "error.h"
/* Callbacks */
typedef int (*PML_AddItem) (int id, const char* name, int parent, int icon);
typedef int (*PML_SetStatus) (int status1, int status2, WCHAR* text);
typedef int (*PML_SetButton) (DWORD dwID, BOOL state);
typedef int (*PML_SetIcon) (int id, int icon);
typedef int (*PML_SetText) (const char* text);
typedef int (*PML_Ask) (const WCHAR* text);
/* Structs */
typedef void* pTree;
#define MAXNODES 10000
/* Prototypes */
void PML_Abort (void);
WCHAR* PML_TransError (int code);
int PML_LoadTree (pTree*, char* url, PML_AddItem);
int PML_FindItem (pTree tree, const char* what);
int PML_LoadPackage (pTree, int id, PML_SetButton);
char* PML_GetDescription (pTree tree, int id);
int PML_SetAction (pTree, int package, int action, PML_SetIcon, PML_Ask);
int PML_DoIt (pTree, PML_SetStatus, PML_Ask);
void PML_CloseTree (pTree);
/* Version */
#define PACKMGR_VERSION_MAJOR 0
#define PACKMGR_VERSION_MINOR 3
#define PACKMGR_VERSION_PATCH_LEVEL 1
////////////////////////////////////////////////
//
// package.hpp
// Package C++ Header
////////////////////////////////////////////////
#include <windows.h>
#include "error.h"
/* Callbacks */
typedef int (*PML_AddItem) (int id, const char* name, int parent, int icon);
typedef int (*PML_SetStatus) (int status1, int status2, WCHAR* text);
typedef int (*PML_SetButton) (DWORD dwID, BOOL state);
typedef int (*PML_SetIcon) (int id, int icon);
typedef int (*PML_SetText) (const char* text);
typedef int (*PML_Ask) (const WCHAR* text);
/* Structs */
typedef void* pTree;
#define MAXNODES 10000
/* Prototypes */
void PML_Abort (void);
WCHAR* PML_TransError (int code);
int PML_LoadTree (pTree*, char* url, PML_AddItem);
int PML_FindItem (pTree tree, const char* what);
int PML_LoadPackage (pTree, int id, PML_SetButton);
char* PML_GetDescription (pTree tree, int id);
int PML_SetAction (pTree, int package, int action, PML_SetIcon, PML_Ask);
int PML_DoIt (pTree, PML_SetStatus, PML_Ask);
void PML_CloseTree (pTree);
/* Version */
#define PACKMGR_VERSION_MAJOR 0
#define PACKMGR_VERSION_MINOR 3
#define PACKMGR_VERSION_PATCH_LEVEL 1

View file

@ -1,92 +1,92 @@
////////////////////////////////////////////////
//
// package.hpp
// Package C++ Header
////////////////////////////////////////////////
#include <windows.h>
#include <vector>
#include "error.h"
using namespace std;
/* Callbacks */
typedef int (*PML_AddItem) (int id, const char* name, int parent, int icon);
typedef int (*PML_SetStatus) (int status1, int status2, WCHAR* text);
typedef int (*PML_SetButton) (DWORD dwID, BOOL state);
typedef int (*PML_SetIcon) (int id, int icon);
typedef int (*PML_SetText) (const char* text);
typedef int (*PML_Ask) (const WCHAR* text);
/* Structs */
typedef struct
{
char* path;
char* name;
char* description;
char** field;
BOOL icon;
BOOL loaded;
vector<int> neededBy;
vector<int> children;
vector<char*> depencies;
int action;
char* files [4];
union //which actions are possible
{
struct { BOOL none, inst, src_inst, update, uninstall; };
BOOL actions [4];
};
} PACKAGE;
typedef struct
{
char** field;
vector<char*> todo;
vector<char*> sources;
vector<char*> descriptionPath;
vector<PACKAGE> packages;
PML_AddItem addItem;
PML_SetButton setButton;
PML_SetStatus setStatus;
PML_SetIcon setIcon;
PML_SetText setText;
} TREE, *pTree;
#define MAXNODES 10000
/* Prototypes */
extern "C"
{
void PML_Abort (void);
WCHAR* PML_TransError (int code);
int PML_LoadTree (pTree*, char* url, PML_AddItem);
int PML_FindItem (TREE* tree, const char* what);
int PML_LoadPackage (pTree, int id, PML_SetButton);
char* PML_GetDescription (TREE* tree, int id);
int PML_SetAction (pTree, int package, int action, PML_SetIcon, PML_Ask);
int PML_DoIt (pTree, PML_SetStatus, PML_Ask);
void PML_CloseTree (pTree);
}
/* Version */
#define PACKMGR_VERSION_MAJOR 0
#define PACKMGR_VERSION_MINOR 3
#define PACKMGR_VERSION_PATCH_LEVEL 1
////////////////////////////////////////////////
//
// package.hpp
// Package C++ Header
////////////////////////////////////////////////
#include <windows.h>
#include <vector>
#include "error.h"
using namespace std;
/* Callbacks */
typedef int (*PML_AddItem) (int id, const char* name, int parent, int icon);
typedef int (*PML_SetStatus) (int status1, int status2, WCHAR* text);
typedef int (*PML_SetButton) (DWORD dwID, BOOL state);
typedef int (*PML_SetIcon) (int id, int icon);
typedef int (*PML_SetText) (const char* text);
typedef int (*PML_Ask) (const WCHAR* text);
/* Structs */
typedef struct
{
char* path;
char* name;
char* description;
char** field;
BOOL icon;
BOOL loaded;
vector<int> neededBy;
vector<int> children;
vector<char*> depencies;
int action;
char* files [4];
union //which actions are possible
{
struct { BOOL none, inst, src_inst, update, uninstall; };
BOOL actions [4];
};
} PACKAGE;
typedef struct
{
char** field;
vector<char*> todo;
vector<char*> sources;
vector<char*> descriptionPath;
vector<PACKAGE> packages;
PML_AddItem addItem;
PML_SetButton setButton;
PML_SetStatus setStatus;
PML_SetIcon setIcon;
PML_SetText setText;
} TREE, *pTree;
#define MAXNODES 10000
/* Prototypes */
extern "C"
{
void PML_Abort (void);
WCHAR* PML_TransError (int code);
int PML_LoadTree (pTree*, char* url, PML_AddItem);
int PML_FindItem (TREE* tree, const char* what);
int PML_LoadPackage (pTree, int id, PML_SetButton);
char* PML_GetDescription (TREE* tree, int id);
int PML_SetAction (pTree, int package, int action, PML_SetIcon, PML_Ask);
int PML_DoIt (pTree, PML_SetStatus, PML_Ask);
void PML_CloseTree (pTree);
}
/* Version */
#define PACKMGR_VERSION_MAJOR 0
#define PACKMGR_VERSION_MINOR 3
#define PACKMGR_VERSION_PATCH_LEVEL 1

View file

@ -1,278 +1,278 @@
////////////////////////////////////////////////////////
//
// script.cpp
//
// Implementaion of a basic basic :) interpreter
//
//
// Maarten Bosma, 09.01.2004
// maarten.paul@bosma.de
//
////////////////////////////////////////////////////////////////////
#include "package.hpp"
#include "script.h"
#include "log.h"
#include <fstream>
using namespace std;
// just a few Helpers
void Replace (string* Where, string Old, string New, int start = 0, int end = -1, int instring = 1);
int FindCount (string What, string Where, int start = 0, int end = -1);
int Find (string Where, string What, int start = 0, int end = -1, int instring = 1);
// Loads script from file, checks if it's synaxially correct
// and converts it into a easy to interprete one.
int RPS_Load (SCRIPT** script, const char* path)
{
string source;
/* We have to do it that way (doublepointer) because MinGw
calls "delete" at the end of function otherwise. */
(*script) = new SCRIPT;
// Load file to string
ifstream file(path, ios_base::in);
if (!file.is_open())
return ERR_FILE;
getline(file, source, '\0');
// make sure last char is a new line
source += "\n";
// Are all subs and strings closed ?
// FIXME: Just a quick hack sould be both checked line by line
if(FindCount(source, "\"")%2) // if count is uneven not all strings are closed
return ERR_SYNATX;
if(FindCount(source, "Sub ") != FindCount(source, "End Sub\n"))
return ERR_SYNATX;
// Delete comments
while (true)
{
int start = Find(source, "'");
if(start == NOTFOUND)
break;
int end = Find(source, "\n", start);
source.erase(start, end-start); // needs size not line
}
// Converte the file into some thing easier to interprete
Replace(&source, "(", " ");
Replace(&source, ")", " ");
Replace(&source, ";", " ");
Replace(&source, ",", " ");
Replace(&source, "\"", " \" ");
Replace(&source, "\t", " ");
Replace(&source, " ", " ");
Replace(&source, "\n ", "\n");
Replace(&source, " \n", "\n");
Replace(&source, "\n\n", "\n");
if(source[0]=='\n')
source.erase(0,1);
// copy string into struct (line by line)
UINT i, line=0;
for (i=0; i < source.size(); i++)
{
// Make everything non capital letters
if (source[i] >= 65 && source[i] <= 90) // ASCII-Code (A-Z 65-90)
{
source[i] += 32; // ASCII-Code (a-z 97-122)
}
else if (source[i] == '\"')
{
while(source[++i]!='\"');
}
else if (source[i] == '\n')
{
(*script)->code.push_back(source.substr(line, i-line));
line = i+1;
}
}
// create a sub table (with name, beginnig and end of function)
for (i=0; i < (*script)->code.size(); i++) // code.size() is the cout of lines
{
SUB sub;
if((*script)->code[i].substr(0,4) != "sub ")
return ERR_SYNATX; // script has to start with sub
sub.name = (*script)->code[i].substr(4,((*script)->code[i].size()-4));
sub.start = i+1;
while ((*script)->code[i] != "end sub")
{
i++;
//if script does not end with "end sub" we got a problem
if (i>(*script)->code.size())
return ERR_SYNATX;
}
sub.end = i;
(*script)->subs.push_back(sub);
}
return ERR_OK;
}
// Executes a subroutine of the script
int RPS_Execute (SCRIPT* script, const char* function)
{
char *argv[100];
char *buffer;
int a, b, c, nr = NOTFOUND, argc = 0;
// find the right fuction
for(a=0; (UINT)a<script->subs.size(); a++)
if(script->subs[a].name == function)
nr = a;
// if there isn't a fuction with this name we can't do anything
if(nr == NOTFOUND)
return ERR_OK;
// call the function
for (a=script->subs[nr].start; a<script->subs[nr].end; a++)
{
// create a temporarry buffer
buffer = new char[script->code[a].size()];
strcpy(buffer, script->code[a].c_str());
// make the fist argument the function's name
argv[0] = &buffer[0];
int buffer_size = (int)strlen(buffer);
for (b=0; b<buffer_size+1; b++)
{
// ignore chars in strings
if(buffer[b]=='\"')
{
argv[argc] = &buffer[b+1];
while(buffer[++b]!='\"');
buffer[b] = '\0';
}
// create a new argument
else if(buffer[b]==' ')
{
argc++;
argv[argc] = &buffer[b+1];
buffer[b] = '\0';
// we don't want buffer overflows
if(argc == 99)
return ERR_GENERIC;
}
// call the function
else if(buffer[b]=='\0')
{
int error = 0;
// log the name
Log("* excute command: ");
for(c=0; c<argc+1; c++)
{
LogAdd(argv[c]);
LogAdd(" ");
}
for(c=0; c<FUNC_COUNT; c++)
if(!strcmp(argv[0], FuncTable[c].name))
error = FuncTable[c].function(argc, &argv[0]);
if(error)
return error;
}
}
// start again with next line
delete[] buffer;
argc = 0;
}
return ERR_OK;
}
// get a Constant or a variavle
int RPS_getVar (const char* name)
{
return ERR_OK;
}
// Clears up Memory
void RPS_Clear (SCRIPT* script)
{
if(script)
delete script;
}
/* Helper Functions */
// How often do we find a string inside another one
int FindCount (string where, string what, int start, int end)
{
int counter = 0, pos;
while(true)
{
pos = (int)where.find (what, start);
//could could not be found or is outside of search area
if (pos == (int)string::npos || (end!=-1 && pos>end))
break;
start = pos+1;
counter++;
}
return counter;
}
// Find (with only or not in Strings option)
int Find (string where, string what, int start, int end, int instring)
{
int pos = (int)where.find (what, start);
//could could not be found or is outside of search area
if (pos == (int)string::npos || (end!=-1 && pos>end))
return -1;
// if the count of this quotes is eaven we are in string
int isInString = FindCount(where, "\"", start, pos)%2;
// if so we go on searching
if(isInString == instring)
return Find (where, what, pos+1, end, instring);
return pos;
}
// Replace (using Find)
void Replace (string* String, string Old, string New, int start, int end, int instring)
{
int pos = start;
while(true)
{
pos = Find(String->c_str(), Old, pos, end, instring);
if (pos == -1)
break;
String->replace (pos, Old.length(), New);
}
}
////////////////////////////////////////////////////////
//
// script.cpp
//
// Implementaion of a basic basic :) interpreter
//
//
// Maarten Bosma, 09.01.2004
// maarten.paul@bosma.de
//
////////////////////////////////////////////////////////////////////
#include "package.hpp"
#include "script.h"
#include "log.h"
#include <fstream>
using namespace std;
// just a few Helpers
void Replace (string* Where, string Old, string New, int start = 0, int end = -1, int instring = 1);
int FindCount (string What, string Where, int start = 0, int end = -1);
int Find (string Where, string What, int start = 0, int end = -1, int instring = 1);
// Loads script from file, checks if it's synaxially correct
// and converts it into a easy to interprete one.
int RPS_Load (SCRIPT** script, const char* path)
{
string source;
/* We have to do it that way (doublepointer) because MinGw
calls "delete" at the end of function otherwise. */
(*script) = new SCRIPT;
// Load file to string
ifstream file(path, ios_base::in);
if (!file.is_open())
return ERR_FILE;
getline(file, source, '\0');
// make sure last char is a new line
source += "\n";
// Are all subs and strings closed ?
// FIXME: Just a quick hack sould be both checked line by line
if(FindCount(source, "\"")%2) // if count is uneven not all strings are closed
return ERR_SYNATX;
if(FindCount(source, "Sub ") != FindCount(source, "End Sub\n"))
return ERR_SYNATX;
// Delete comments
while (true)
{
int start = Find(source, "'");
if(start == NOTFOUND)
break;
int end = Find(source, "\n", start);
source.erase(start, end-start); // needs size not line
}
// Converte the file into some thing easier to interprete
Replace(&source, "(", " ");
Replace(&source, ")", " ");
Replace(&source, ";", " ");
Replace(&source, ",", " ");
Replace(&source, "\"", " \" ");
Replace(&source, "\t", " ");
Replace(&source, " ", " ");
Replace(&source, "\n ", "\n");
Replace(&source, " \n", "\n");
Replace(&source, "\n\n", "\n");
if(source[0]=='\n')
source.erase(0,1);
// copy string into struct (line by line)
UINT i, line=0;
for (i=0; i < source.size(); i++)
{
// Make everything non capital letters
if (source[i] >= 65 && source[i] <= 90) // ASCII-Code (A-Z 65-90)
{
source[i] += 32; // ASCII-Code (a-z 97-122)
}
else if (source[i] == '\"')
{
while(source[++i]!='\"');
}
else if (source[i] == '\n')
{
(*script)->code.push_back(source.substr(line, i-line));
line = i+1;
}
}
// create a sub table (with name, beginnig and end of function)
for (i=0; i < (*script)->code.size(); i++) // code.size() is the cout of lines
{
SUB sub;
if((*script)->code[i].substr(0,4) != "sub ")
return ERR_SYNATX; // script has to start with sub
sub.name = (*script)->code[i].substr(4,((*script)->code[i].size()-4));
sub.start = i+1;
while ((*script)->code[i] != "end sub")
{
i++;
//if script does not end with "end sub" we got a problem
if (i>(*script)->code.size())
return ERR_SYNATX;
}
sub.end = i;
(*script)->subs.push_back(sub);
}
return ERR_OK;
}
// Executes a subroutine of the script
int RPS_Execute (SCRIPT* script, const char* function)
{
char *argv[100];
char *buffer;
int a, b, c, nr = NOTFOUND, argc = 0;
// find the right fuction
for(a=0; (UINT)a<script->subs.size(); a++)
if(script->subs[a].name == function)
nr = a;
// if there isn't a fuction with this name we can't do anything
if(nr == NOTFOUND)
return ERR_OK;
// call the function
for (a=script->subs[nr].start; a<script->subs[nr].end; a++)
{
// create a temporarry buffer
buffer = new char[script->code[a].size()];
strcpy(buffer, script->code[a].c_str());
// make the fist argument the function's name
argv[0] = &buffer[0];
int buffer_size = (int)strlen(buffer);
for (b=0; b<buffer_size+1; b++)
{
// ignore chars in strings
if(buffer[b]=='\"')
{
argv[argc] = &buffer[b+1];
while(buffer[++b]!='\"');
buffer[b] = '\0';
}
// create a new argument
else if(buffer[b]==' ')
{
argc++;
argv[argc] = &buffer[b+1];
buffer[b] = '\0';
// we don't want buffer overflows
if(argc == 99)
return ERR_GENERIC;
}
// call the function
else if(buffer[b]=='\0')
{
int error = 0;
// log the name
Log("* excute command: ");
for(c=0; c<argc+1; c++)
{
LogAdd(argv[c]);
LogAdd(" ");
}
for(c=0; c<FUNC_COUNT; c++)
if(!strcmp(argv[0], FuncTable[c].name))
error = FuncTable[c].function(argc, &argv[0]);
if(error)
return error;
}
}
// start again with next line
delete[] buffer;
argc = 0;
}
return ERR_OK;
}
// get a Constant or a variavle
int RPS_getVar (const char* name)
{
return ERR_OK;
}
// Clears up Memory
void RPS_Clear (SCRIPT* script)
{
if(script)
delete script;
}
/* Helper Functions */
// How often do we find a string inside another one
int FindCount (string where, string what, int start, int end)
{
int counter = 0, pos;
while(true)
{
pos = (int)where.find (what, start);
//could could not be found or is outside of search area
if (pos == (int)string::npos || (end!=-1 && pos>end))
break;
start = pos+1;
counter++;
}
return counter;
}
// Find (with only or not in Strings option)
int Find (string where, string what, int start, int end, int instring)
{
int pos = (int)where.find (what, start);
//could could not be found or is outside of search area
if (pos == (int)string::npos || (end!=-1 && pos>end))
return -1;
// if the count of this quotes is eaven we are in string
int isInString = FindCount(where, "\"", start, pos)%2;
// if so we go on searching
if(isInString == instring)
return Find (where, what, pos+1, end, instring);
return pos;
}
// Replace (using Find)
void Replace (string* String, string Old, string New, int start, int end, int instring)
{
int pos = start;
while(true)
{
pos = Find(String->c_str(), Old, pos, end, instring);
if (pos == -1)
break;
String->replace (pos, Old.length(), New);
}
}

View file

@ -1,65 +1,65 @@
////////////////////////////////////////////////
//
// package.hpp
// Header for the script stuff
////////////////////////////////////////////////
#include <vector>
#include <string>
using namespace std;
/* Structs */
typedef struct
{
string name;
int start, end;
} SUB;
typedef struct
{
vector<string> code;
vector<SUB> subs;
} SCRIPT;
/* Prototypes */
int RPS_Load (SCRIPT** script, const char* path);
int RPS_Execute (SCRIPT* script, const char* function);
int RPS_getVar (const char* name);
void RPS_Clear (SCRIPT* script);
/* Callbacks */
typedef int (*FUNC_PROC)(int, char**); // function callback
/* Function table */
typedef struct
{
char* name;
FUNC_PROC function;
} FUNC_TABLE;
// very function is listed in there
extern const FUNC_TABLE FuncTable[];
// count of functions
#define FUNC_COUNT 3
/* For the helper-funtions */
#define STR_NO 0x1;
#define STR_ONLY 0x0;
#define STR_YES 0x2;
// ^^ I would write down here that they
// mean but I don't know anymore myself :O
////////////////////////////////////////////////
//
// package.hpp
// Header for the script stuff
////////////////////////////////////////////////
#include <vector>
#include <string>
using namespace std;
/* Structs */
typedef struct
{
string name;
int start, end;
} SUB;
typedef struct
{
vector<string> code;
vector<SUB> subs;
} SCRIPT;
/* Prototypes */
int RPS_Load (SCRIPT** script, const char* path);
int RPS_Execute (SCRIPT* script, const char* function);
int RPS_getVar (const char* name);
void RPS_Clear (SCRIPT* script);
/* Callbacks */
typedef int (*FUNC_PROC)(int, char**); // function callback
/* Function table */
typedef struct
{
char* name;
FUNC_PROC function;
} FUNC_TABLE;
// very function is listed in there
extern const FUNC_TABLE FuncTable[];
// count of functions
#define FUNC_COUNT 3
/* For the helper-funtions */
#define STR_NO 0x1;
#define STR_ONLY 0x0;
#define STR_YES 0x2;
// ^^ I would write down here that they
// mean but I don't know anymore myself :O

View file

@ -1,126 +1,126 @@
////////////////////////////////////////////////////////
//
// tree.cpp
//
// Loading of the package tree
//
//
// Maarten Bosma, 09.01.2004
// maarten.paul@bosma.de
//
////////////////////////////////////////////////////////////////////
#include "package.hpp"
#include "expat.h"
vector <int> parents;
int LoadOptions (TREE* tree);
void tree_end (void* tree, const char* tag);
void tree_start (void* usrdata, const char* tag, const char** arg);
int PML_XmlDownload (pTree tree, const char* file, void* usrdata, XML_StartElementHandler start,
XML_EndElementHandler end, XML_CharacterDataHandler text=0);
// Load the tree
extern "C" int PML_LoadTree (TREE** tree, char* url, PML_AddItem AddItem)
{
// get the memory
(*tree) = new TREE;
// set every to zero
memset((*tree), 0, sizeof((*tree)));
// set addItem callback
(*tree)->addItem = AddItem;
LoadOptions(*tree);
return PML_XmlDownload (*tree, url, (void*)(*tree), tree_start, tree_end);
}
// expat callback for start of a "node" tag
void tree_start (void* usrdata, const char* tag, const char** arg)
{
int i, icon = 0;
static int id = 1;
TREE* tree = (TREE*)usrdata;
// ignore if tag is the root tag ("tree")
if(!strcmp(tag, "tree"))
return;
// set the package memory
tree->packages.resize(id+1);
memset(&tree->packages[id], 0, sizeof(tree->packages[id]));
tree->packages[id].loaded = FALSE;
tree->packages[id].icon = FALSE;
tree->packages[id].none = TRUE;
tree->packages[id].path = NULL;
tree->packages[id].name = "\0";
// read the arguments
for (i=0; arg[i]; i+=2)
{
if(!strcmp(arg[i], "name"))
{
tree->packages[id].name = new char [strlen(arg[i+1])+1];
strcpy(tree->packages[id].name, arg[i+1]);
}
if(!strcmp(arg[i], "icon"))
{
icon = atoi(arg[i+1]);
tree->packages[id].icon = TRUE;
}
if(!strcmp(arg[i], "file"))
{
tree->packages[id].path = new char [strlen(arg[i+1])+1];
strcpy(tree->packages[id].path, arg[i+1]);
if(strcmp(tag, "bin"))
tree->packages[id].inst = TRUE;
if(strcmp(tag, "src"))
tree->packages[id].src_inst = TRUE;
}
}
if(tree->packages[id].name[0] == '\0') return;
// add it
if(!parents.size())
{
if(tree->addItem)
tree->addItem(id, tree->packages[id].name, 0, icon);
}
// do some manipulation at the parent
else
{
if(tree->addItem)
tree->addItem(id, tree->packages[id].name, parents.back(), icon);
// list as child in the parent node
tree->packages[parents.back()].children.push_back(id);
// this is for the buttons
tree->packages[parents.back()].inst = tree->packages[parents.back()].inst || tree->packages[id].inst;
tree->packages[parents.back()].src_inst = tree->packages[parents.back()].src_inst || tree->packages[id].src_inst;
}
parents.push_back(id++);
}
// expat callback for end of a "node" tag
void tree_end (void* tree, const char* tag)
{
// delete last item
parents.pop_back();
}
////////////////////////////////////////////////////////
//
// tree.cpp
//
// Loading of the package tree
//
//
// Maarten Bosma, 09.01.2004
// maarten.paul@bosma.de
//
////////////////////////////////////////////////////////////////////
#include "package.hpp"
#include "expat.h"
vector <int> parents;
int LoadOptions (TREE* tree);
void tree_end (void* tree, const char* tag);
void tree_start (void* usrdata, const char* tag, const char** arg);
int PML_XmlDownload (pTree tree, const char* file, void* usrdata, XML_StartElementHandler start,
XML_EndElementHandler end, XML_CharacterDataHandler text=0);
// Load the tree
extern "C" int PML_LoadTree (TREE** tree, char* url, PML_AddItem AddItem)
{
// get the memory
(*tree) = new TREE;
// set every to zero
memset((*tree), 0, sizeof((*tree)));
// set addItem callback
(*tree)->addItem = AddItem;
LoadOptions(*tree);
return PML_XmlDownload (*tree, url, (void*)(*tree), tree_start, tree_end);
}
// expat callback for start of a "node" tag
void tree_start (void* usrdata, const char* tag, const char** arg)
{
int i, icon = 0;
static int id = 1;
TREE* tree = (TREE*)usrdata;
// ignore if tag is the root tag ("tree")
if(!strcmp(tag, "tree"))
return;
// set the package memory
tree->packages.resize(id+1);
memset(&tree->packages[id], 0, sizeof(tree->packages[id]));
tree->packages[id].loaded = FALSE;
tree->packages[id].icon = FALSE;
tree->packages[id].none = TRUE;
tree->packages[id].path = NULL;
tree->packages[id].name = "\0";
// read the arguments
for (i=0; arg[i]; i+=2)
{
if(!strcmp(arg[i], "name"))
{
tree->packages[id].name = new char [strlen(arg[i+1])+1];
strcpy(tree->packages[id].name, arg[i+1]);
}
if(!strcmp(arg[i], "icon"))
{
icon = atoi(arg[i+1]);
tree->packages[id].icon = TRUE;
}
if(!strcmp(arg[i], "file"))
{
tree->packages[id].path = new char [strlen(arg[i+1])+1];
strcpy(tree->packages[id].path, arg[i+1]);
if(strcmp(tag, "bin"))
tree->packages[id].inst = TRUE;
if(strcmp(tag, "src"))
tree->packages[id].src_inst = TRUE;
}
}
if(tree->packages[id].name[0] == '\0') return;
// add it
if(!parents.size())
{
if(tree->addItem)
tree->addItem(id, tree->packages[id].name, 0, icon);
}
// do some manipulation at the parent
else
{
if(tree->addItem)
tree->addItem(id, tree->packages[id].name, parents.back(), icon);
// list as child in the parent node
tree->packages[parents.back()].children.push_back(id);
// this is for the buttons
tree->packages[parents.back()].inst = tree->packages[parents.back()].inst || tree->packages[id].inst;
tree->packages[parents.back()].src_inst = tree->packages[parents.back()].src_inst || tree->packages[id].src_inst;
}
parents.push_back(id++);
}
// expat callback for end of a "node" tag
void tree_end (void* tree, const char* tag)
{
// delete last item
parents.pop_back();
}

View file

@ -1,44 +1,44 @@
/*
* CTM resource definitions
*
* Copyright 2004 ReactOS team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define IDS_APP_TITLE 0
#define IDS_COLUMN_IMAGENAME 10
#define IDS_COLUMN_PID 11
#define IDS_COLUMN_CPU 12
#define IDS_COLUMN_MEM 13
#define IDS_COLUMN_MEM_UNIT 14
#define IDS_COLUMN_PF 15
#define IDS_IDLE_PROCESS 100
#define IDS_YES 101
#define IDS_NO 102
#define IDS_MENU 200
#define IDS_MENU_QUIT 201
#define IDS_MENU_KILL_PROCESS 202
#define IDS_KILL_PROCESS 1000
#define IDS_KILL_PROCESS_ERR1 1001
#define IDS_KILL_PROCESS_ERR2 1002
#define IDS_CTM_GENERAL_ERR1 32768
#define IDS_CTM_GENERAL_ERR2 32769
#define IDS_CTM_GENERAL_ERR3 32770
/*
* CTM resource definitions
*
* Copyright 2004 ReactOS team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define IDS_APP_TITLE 0
#define IDS_COLUMN_IMAGENAME 10
#define IDS_COLUMN_PID 11
#define IDS_COLUMN_CPU 12
#define IDS_COLUMN_MEM 13
#define IDS_COLUMN_MEM_UNIT 14
#define IDS_COLUMN_PF 15
#define IDS_IDLE_PROCESS 100
#define IDS_YES 101
#define IDS_NO 102
#define IDS_MENU 200
#define IDS_MENU_QUIT 201
#define IDS_MENU_KILL_PROCESS 202
#define IDS_KILL_PROCESS 1000
#define IDS_KILL_PROCESS_ERR1 1001
#define IDS_KILL_PROCESS_ERR2 1002
#define IDS_CTM_GENERAL_ERR1 32768
#define IDS_CTM_GENERAL_ERR2 32769
#define IDS_CTM_GENERAL_ERR3 32770

View file

@ -1,370 +1,370 @@
/* boot.c - Read and analyze ia PC/MS-DOS boot sector */
/* Written 1993 by Werner Almesberger */
/* FAT32, VFAT, Atari format support, and various fixes additions May 1998
* by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include "common.h"
#include "dosfsck.h"
#include "io.h"
#include "boot.h"
#define ROUND_TO_MULTIPLE(n,m) ((n) && (m) ? (n)+(m)-1-((n)-1)%(m) : 0)
/* don't divide by zero */
static struct {
__u8 media;
char *descr;
} mediabytes[] = {
{ 0xf0, "5.25\" or 3.5\" HD floppy" },
{ 0xf8, "hard disk" },
{ 0xf9, "3,5\" 720k floppy 2s/80tr/9sec or "
"5.25\" 1.2M floppy 2s/80tr/15sec" },
{ 0xfa, "5.25\" 320k floppy 1s/80tr/8sec" },
{ 0xfb, "3.5\" 640k floppy 2s/80tr/8sec" },
{ 0xfc, "5.25\" 180k floppy 1s/40tr/9sec" },
{ 0xfd, "5.25\" 360k floppy 2s/40tr/9sec" },
{ 0xfe, "5.25\" 160k floppy 1s/40tr/8sec" },
{ 0xff, "5.25\" 320k floppy 2s/40tr/8sec" },
};
#if defined __alpha || defined __ia64__ || defined __s390x__ || defined __x86_64__ || defined __ppc64__
/* Unaligned fields must first be copied byte-wise */
#define GET_UNALIGNED_W(f) \
({ \
unsigned short __v; \
memcpy( &__v, &f, sizeof(__v) ); \
CF_LE_W( *(unsigned short *)&f ); \
})
#else
#define GET_UNALIGNED_W(f) CF_LE_W( *(unsigned short *)&f )
#endif
static char *get_media_descr( unsigned char media )
{
int i;
for( i = 0; i < sizeof(mediabytes)/sizeof(*mediabytes); ++i ) {
if (mediabytes[i].media == media)
return( mediabytes[i].descr );
}
return( "undefined" );
}
static void dump_boot(DOS_FS *fs,struct boot_sector *b,unsigned lss)
{
unsigned short sectors;
printf("Boot sector contents:\n");
if (!atari_format) {
char id[9];
strncpy(id,b->system_id,8);
id[8] = 0;
printf("System ID \"%s\"\n",id);
}
else {
/* On Atari, a 24 bit serial number is stored at offset 8 of the boot
* sector */
printf("Serial number 0x%x\n",
b->system_id[5] | (b->system_id[6]<<8) | (b->system_id[7]<<16));
}
printf("Media byte 0x%02x (%s)\n",b->media,get_media_descr(b->media));
printf("%10d bytes per logical sector\n",GET_UNALIGNED_W(b->sector_size));
printf("%10d bytes per cluster\n",fs->cluster_size);
printf("%10d reserved sector%s\n",CF_LE_W(b->reserved),
CF_LE_W(b->reserved) == 1 ? "" : "s");
printf("First FAT starts at byte %llu (sector %llu)\n",
(__u64)fs->fat_start,
(__u64)fs->fat_start/lss);
printf("%10d FATs, %d bit entries\n",b->fats,fs->fat_bits);
printf("%10d bytes per FAT (= %u sectors)\n",fs->fat_size,
fs->fat_size/lss);
if (!fs->root_cluster) {
printf("Root directory starts at byte %llu (sector %llu)\n",
(__u64)fs->root_start,
(__u64)fs->root_start/lss);
printf("%10d root directory entries\n",fs->root_entries);
}
else {
printf( "Root directory start at cluster %lu (arbitrary size)\n",
fs->root_cluster);
}
printf("Data area starts at byte %llu (sector %llu)\n",
(__u64)fs->data_start,
(__u64)fs->data_start/lss);
printf("%10lu data clusters (%llu bytes)\n",fs->clusters,
(__u64)fs->clusters*fs->cluster_size);
printf("%u sectors/track, %u heads\n",CF_LE_W(b->secs_track),
CF_LE_W(b->heads));
printf("%10u hidden sectors\n",
atari_format ?
/* On Atari, the hidden field is only 16 bit wide and unused */
(((unsigned char *)&b->hidden)[0] |
((unsigned char *)&b->hidden)[1] << 8) :
CF_LE_L(b->hidden));
sectors = GET_UNALIGNED_W( b->sectors );
printf("%10u sectors total\n", sectors ? sectors : CF_LE_L(b->total_sect));
}
static void check_backup_boot(DOS_FS *fs, struct boot_sector *b, int lss)
{
struct boot_sector b2;
if (!fs->backupboot_start) {
printf( "There is no backup boot sector.\n" );
if (CF_LE_W(b->reserved) < 3) {
printf( "And there is no space for creating one!\n" );
return;
}
if (interactive)
printf( "1) Create one\n2) Do without a backup\n" );
else printf( " Auto-creating backup boot block.\n" );
if (!interactive || get_key("12","?") == '1') {
int bbs;
/* The usual place for the backup boot sector is sector 6. Choose
* that or the last reserved sector. */
if (CF_LE_W(b->reserved) >= 7 && CF_LE_W(b->info_sector) != 6)
bbs = 6;
else {
bbs = CF_LE_W(b->reserved) - 1;
if (bbs == CF_LE_W(b->info_sector))
--bbs; /* this is never 0, as we checked reserved >= 3! */
}
fs->backupboot_start = bbs*lss;
b->backup_boot = CT_LE_W(bbs);
fs_write(fs->backupboot_start,sizeof(*b),b);
fs_write((off_t)offsetof(struct boot_sector,backup_boot),
sizeof(b->backup_boot),&b->backup_boot);
printf( "Created backup of boot sector in sector %d\n", bbs );
return;
}
else return;
}
fs_read(fs->backupboot_start,sizeof(b2),&b2);
if (memcmp(b,&b2,sizeof(b2)) != 0) {
/* there are any differences */
__u8 *p, *q;
int i, pos, first = 1;
char buf[20];
printf( "There are differences between boot sector and its backup.\n" );
printf( "Differences: (offset:original/backup)\n " );
pos = 2;
for( p = (__u8 *)b, q = (__u8 *)&b2, i = 0; i < sizeof(b2);
++p, ++q, ++i ) {
if (*p != *q) {
sprintf( buf, "%s%u:%02x/%02x", first ? "" : ", ",
(unsigned)(p-(__u8 *)b), *p, *q );
if (pos + strlen(buf) > 78) printf( "\n " ), pos = 2;
printf( "%s", buf );
pos += strlen(buf);
first = 0;
}
}
printf( "\n" );
if (interactive)
printf( "1) Copy original to backup\n"
"2) Copy backup to original\n"
"3) No action\n" );
else printf( " Not automatically fixing this.\n" );
switch (interactive ? get_key("123","?") : '3') {
case '1':
fs_write(fs->backupboot_start,sizeof(*b),b);
break;
case '2':
fs_write(0,sizeof(b2),&b2);
break;
default:
break;
}
}
}
static void init_fsinfo(struct info_sector *i)
{
i->magic = CT_LE_L(0x41615252);
i->signature = CT_LE_L(0x61417272);
i->free_clusters = CT_LE_L(-1);
i->next_cluster = CT_LE_L(2);
i->boot_sign = CT_LE_W(0xaa55);
}
static void read_fsinfo(DOS_FS *fs, struct boot_sector *b,int lss)
{
struct info_sector i;
if (!b->info_sector) {
printf( "No FSINFO sector\n" );
if (interactive)
printf( "1) Create one\n2) Do without FSINFO\n" );
else printf( " Not automatically creating it.\n" );
if (interactive && get_key("12","?") == '1') {
/* search for a free reserved sector (not boot sector and not
* backup boot sector) */
__u32 s;
for( s = 1; s < CF_LE_W(b->reserved); ++s )
if (s != CF_LE_W(b->backup_boot)) break;
if (s > 0 && s < CF_LE_W(b->reserved)) {
init_fsinfo(&i);
fs_write((off_t)s*lss,sizeof(i),&i);
b->info_sector = CT_LE_W(s);
fs_write((off_t)offsetof(struct boot_sector,info_sector),
sizeof(b->info_sector),&b->info_sector);
if (fs->backupboot_start)
fs_write(fs->backupboot_start+
offsetof(struct boot_sector,info_sector),
sizeof(b->info_sector),&b->info_sector);
}
else {
printf( "No free reserved sector found -- "
"no space for FSINFO sector!\n" );
return;
}
}
else return;
}
fs->fsinfo_start = CF_LE_W(b->info_sector)*lss;
fs_read(fs->fsinfo_start,sizeof(i),&i);
if (i.magic != CT_LE_L(0x41615252) ||
i.signature != CT_LE_L(0x61417272) ||
i.boot_sign != CT_LE_W(0xaa55)) {
printf( "FSINFO sector has bad magic number(s):\n" );
if (i.magic != CT_LE_L(0x41615252))
printf( " Offset %llu: 0x%08x != expected 0x%08x\n",
(__u64)offsetof(struct info_sector,magic),
CF_LE_L(i.magic),0x41615252);
if (i.signature != CT_LE_L(0x61417272))
printf( " Offset %llu: 0x%08x != expected 0x%08x\n",
(__u64)offsetof(struct info_sector,signature),
CF_LE_L(i.signature),0x61417272);
if (i.boot_sign != CT_LE_W(0xaa55))
printf( " Offset %llu: 0x%04x != expected 0x%04x\n",
(__u64)offsetof(struct info_sector,boot_sign),
CF_LE_W(i.boot_sign),0xaa55);
if (interactive)
printf( "1) Correct\n2) Don't correct (FSINFO invalid then)\n" );
else printf( " Auto-correcting it.\n" );
if (!interactive || get_key("12","?") == '1') {
init_fsinfo(&i);
fs_write(fs->fsinfo_start,sizeof(i),&i);
}
else fs->fsinfo_start = 0;
}
if (fs->fsinfo_start)
fs->free_clusters = CF_LE_L(i.free_clusters);
}
void read_boot(DOS_FS *fs)
{
struct boot_sector b;
unsigned total_sectors;
unsigned short logical_sector_size, sectors;
unsigned fat_length;
loff_t data_size;
fs_read(0,sizeof(b),&b);
logical_sector_size = GET_UNALIGNED_W(b.sector_size);
if (!logical_sector_size) die("Logical sector size is zero.");
fs->cluster_size = b.cluster_size*logical_sector_size;
if (!fs->cluster_size) die("Cluster size is zero.");
if (b.fats != 2 && b.fats != 1)
die("Currently, only 1 or 2 FATs are supported, not %d.\n",b.fats);
fs->nfats = b.fats;
sectors = GET_UNALIGNED_W(b.sectors);
total_sectors = sectors ? sectors : CF_LE_L(b.total_sect);
if (verbose) printf("Checking we can access the last sector of the filesystem\n");
/* Can't access last odd sector anyway, so round down */
fs_test((loff_t)((total_sectors & ~1)-1)*(loff_t)logical_sector_size,
logical_sector_size);
fat_length = CF_LE_W(b.fat_length) ?
CF_LE_W(b.fat_length) : CF_LE_L(b.fat32_length);
fs->fat_start = (off_t)CF_LE_W(b.reserved)*logical_sector_size;
fs->root_start = ((off_t)CF_LE_W(b.reserved)+b.fats*fat_length)*
logical_sector_size;
fs->root_entries = GET_UNALIGNED_W(b.dir_entries);
fs->data_start = fs->root_start+ROUND_TO_MULTIPLE(fs->root_entries <<
MSDOS_DIR_BITS,logical_sector_size);
data_size = (loff_t)total_sectors*logical_sector_size-fs->data_start;
fs->clusters = data_size/fs->cluster_size;
fs->root_cluster = 0; /* indicates standard, pre-FAT32 root dir */
fs->fsinfo_start = 0; /* no FSINFO structure */
fs->free_clusters = -1; /* unknown */
if (!b.fat_length && b.fat32_length) {
fs->fat_bits = 32;
fs->root_cluster = CF_LE_L(b.root_cluster);
if (!fs->root_cluster && fs->root_entries)
/* M$ hasn't specified this, but it looks reasonable: If
* root_cluster is 0 but there is a separate root dir
* (root_entries != 0), we handle the root dir the old way. Give a
* warning, but convertig to a root dir in a cluster chain seems
* to complex for now... */
printf( "Warning: FAT32 root dir not in cluster chain! "
"Compability mode...\n" );
else if (!fs->root_cluster && !fs->root_entries)
die("No root directory!");
else if (fs->root_cluster && fs->root_entries)
printf( "Warning: FAT32 root dir is in a cluster chain, but "
"a separate root dir\n"
" area is defined. Cannot fix this easily.\n" );
fs->backupboot_start = CF_LE_W(b.backup_boot)*logical_sector_size;
check_backup_boot(fs,&b,logical_sector_size);
read_fsinfo(fs,&b,logical_sector_size);
}
else if (!atari_format) {
/* On real MS-DOS, a 16 bit FAT is used whenever there would be too
* much clusers otherwise. */
fs->fat_bits = (fs->clusters > MSDOS_FAT12) ? 16 : 12;
}
else {
/* On Atari, things are more difficult: GEMDOS always uses 12bit FATs
* on floppies, and always 16 bit on harddisks. */
fs->fat_bits = 16; /* assume 16 bit FAT for now */
/* If more clusters than fat entries in 16-bit fat, we assume
* it's a real MSDOS FS with 12-bit fat. */
if (fs->clusters+2 > fat_length*logical_sector_size*8/16 ||
/* if it's a floppy disk --> 12bit fat */
device_no == 2 ||
/* if it's a ramdisk or loopback device and has one of the usual
* floppy sizes -> 12bit FAT */
((device_no == 1 || device_no == 7) &&
(total_sectors == 720 || total_sectors == 1440 ||
total_sectors == 2880)))
fs->fat_bits = 12;
}
/* On FAT32, the high 4 bits of a FAT entry are reserved */
fs->eff_fat_bits = (fs->fat_bits == 32) ? 28 : fs->fat_bits;
fs->fat_size = fat_length*logical_sector_size;
if (fs->clusters > ((__u64)fs->fat_size*8/fs->fat_bits)-2)
die("File system has %d clusters but only space for %d FAT entries.",
fs->clusters,((__u64)fs->fat_size*8/fs->fat_bits)-2);
if (!fs->root_entries && !fs->root_cluster)
die("Root directory has zero size.");
if (fs->root_entries & (MSDOS_DPS-1))
die("Root directory (%d entries) doesn't span an integral number of "
"sectors.",fs->root_entries);
if (logical_sector_size & (SECTOR_SIZE-1))
die("Logical sector size (%d bytes) is not a multiple of the physical "
"sector size.",logical_sector_size);
/* ++roman: On Atari, these two fields are often left uninitialized */
if (!atari_format && (!b.secs_track || !b.heads))
die("Invalid disk format in boot sector.");
if (verbose) dump_boot(fs,&b,logical_sector_size);
}
/* Local Variables: */
/* tab-width: 8 */
/* End: */
/* boot.c - Read and analyze ia PC/MS-DOS boot sector */
/* Written 1993 by Werner Almesberger */
/* FAT32, VFAT, Atari format support, and various fixes additions May 1998
* by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include "common.h"
#include "dosfsck.h"
#include "io.h"
#include "boot.h"
#define ROUND_TO_MULTIPLE(n,m) ((n) && (m) ? (n)+(m)-1-((n)-1)%(m) : 0)
/* don't divide by zero */
static struct {
__u8 media;
char *descr;
} mediabytes[] = {
{ 0xf0, "5.25\" or 3.5\" HD floppy" },
{ 0xf8, "hard disk" },
{ 0xf9, "3,5\" 720k floppy 2s/80tr/9sec or "
"5.25\" 1.2M floppy 2s/80tr/15sec" },
{ 0xfa, "5.25\" 320k floppy 1s/80tr/8sec" },
{ 0xfb, "3.5\" 640k floppy 2s/80tr/8sec" },
{ 0xfc, "5.25\" 180k floppy 1s/40tr/9sec" },
{ 0xfd, "5.25\" 360k floppy 2s/40tr/9sec" },
{ 0xfe, "5.25\" 160k floppy 1s/40tr/8sec" },
{ 0xff, "5.25\" 320k floppy 2s/40tr/8sec" },
};
#if defined __alpha || defined __ia64__ || defined __s390x__ || defined __x86_64__ || defined __ppc64__
/* Unaligned fields must first be copied byte-wise */
#define GET_UNALIGNED_W(f) \
({ \
unsigned short __v; \
memcpy( &__v, &f, sizeof(__v) ); \
CF_LE_W( *(unsigned short *)&f ); \
})
#else
#define GET_UNALIGNED_W(f) CF_LE_W( *(unsigned short *)&f )
#endif
static char *get_media_descr( unsigned char media )
{
int i;
for( i = 0; i < sizeof(mediabytes)/sizeof(*mediabytes); ++i ) {
if (mediabytes[i].media == media)
return( mediabytes[i].descr );
}
return( "undefined" );
}
static void dump_boot(DOS_FS *fs,struct boot_sector *b,unsigned lss)
{
unsigned short sectors;
printf("Boot sector contents:\n");
if (!atari_format) {
char id[9];
strncpy(id,b->system_id,8);
id[8] = 0;
printf("System ID \"%s\"\n",id);
}
else {
/* On Atari, a 24 bit serial number is stored at offset 8 of the boot
* sector */
printf("Serial number 0x%x\n",
b->system_id[5] | (b->system_id[6]<<8) | (b->system_id[7]<<16));
}
printf("Media byte 0x%02x (%s)\n",b->media,get_media_descr(b->media));
printf("%10d bytes per logical sector\n",GET_UNALIGNED_W(b->sector_size));
printf("%10d bytes per cluster\n",fs->cluster_size);
printf("%10d reserved sector%s\n",CF_LE_W(b->reserved),
CF_LE_W(b->reserved) == 1 ? "" : "s");
printf("First FAT starts at byte %llu (sector %llu)\n",
(__u64)fs->fat_start,
(__u64)fs->fat_start/lss);
printf("%10d FATs, %d bit entries\n",b->fats,fs->fat_bits);
printf("%10d bytes per FAT (= %u sectors)\n",fs->fat_size,
fs->fat_size/lss);
if (!fs->root_cluster) {
printf("Root directory starts at byte %llu (sector %llu)\n",
(__u64)fs->root_start,
(__u64)fs->root_start/lss);
printf("%10d root directory entries\n",fs->root_entries);
}
else {
printf( "Root directory start at cluster %lu (arbitrary size)\n",
fs->root_cluster);
}
printf("Data area starts at byte %llu (sector %llu)\n",
(__u64)fs->data_start,
(__u64)fs->data_start/lss);
printf("%10lu data clusters (%llu bytes)\n",fs->clusters,
(__u64)fs->clusters*fs->cluster_size);
printf("%u sectors/track, %u heads\n",CF_LE_W(b->secs_track),
CF_LE_W(b->heads));
printf("%10u hidden sectors\n",
atari_format ?
/* On Atari, the hidden field is only 16 bit wide and unused */
(((unsigned char *)&b->hidden)[0] |
((unsigned char *)&b->hidden)[1] << 8) :
CF_LE_L(b->hidden));
sectors = GET_UNALIGNED_W( b->sectors );
printf("%10u sectors total\n", sectors ? sectors : CF_LE_L(b->total_sect));
}
static void check_backup_boot(DOS_FS *fs, struct boot_sector *b, int lss)
{
struct boot_sector b2;
if (!fs->backupboot_start) {
printf( "There is no backup boot sector.\n" );
if (CF_LE_W(b->reserved) < 3) {
printf( "And there is no space for creating one!\n" );
return;
}
if (interactive)
printf( "1) Create one\n2) Do without a backup\n" );
else printf( " Auto-creating backup boot block.\n" );
if (!interactive || get_key("12","?") == '1') {
int bbs;
/* The usual place for the backup boot sector is sector 6. Choose
* that or the last reserved sector. */
if (CF_LE_W(b->reserved) >= 7 && CF_LE_W(b->info_sector) != 6)
bbs = 6;
else {
bbs = CF_LE_W(b->reserved) - 1;
if (bbs == CF_LE_W(b->info_sector))
--bbs; /* this is never 0, as we checked reserved >= 3! */
}
fs->backupboot_start = bbs*lss;
b->backup_boot = CT_LE_W(bbs);
fs_write(fs->backupboot_start,sizeof(*b),b);
fs_write((off_t)offsetof(struct boot_sector,backup_boot),
sizeof(b->backup_boot),&b->backup_boot);
printf( "Created backup of boot sector in sector %d\n", bbs );
return;
}
else return;
}
fs_read(fs->backupboot_start,sizeof(b2),&b2);
if (memcmp(b,&b2,sizeof(b2)) != 0) {
/* there are any differences */
__u8 *p, *q;
int i, pos, first = 1;
char buf[20];
printf( "There are differences between boot sector and its backup.\n" );
printf( "Differences: (offset:original/backup)\n " );
pos = 2;
for( p = (__u8 *)b, q = (__u8 *)&b2, i = 0; i < sizeof(b2);
++p, ++q, ++i ) {
if (*p != *q) {
sprintf( buf, "%s%u:%02x/%02x", first ? "" : ", ",
(unsigned)(p-(__u8 *)b), *p, *q );
if (pos + strlen(buf) > 78) printf( "\n " ), pos = 2;
printf( "%s", buf );
pos += strlen(buf);
first = 0;
}
}
printf( "\n" );
if (interactive)
printf( "1) Copy original to backup\n"
"2) Copy backup to original\n"
"3) No action\n" );
else printf( " Not automatically fixing this.\n" );
switch (interactive ? get_key("123","?") : '3') {
case '1':
fs_write(fs->backupboot_start,sizeof(*b),b);
break;
case '2':
fs_write(0,sizeof(b2),&b2);
break;
default:
break;
}
}
}
static void init_fsinfo(struct info_sector *i)
{
i->magic = CT_LE_L(0x41615252);
i->signature = CT_LE_L(0x61417272);
i->free_clusters = CT_LE_L(-1);
i->next_cluster = CT_LE_L(2);
i->boot_sign = CT_LE_W(0xaa55);
}
static void read_fsinfo(DOS_FS *fs, struct boot_sector *b,int lss)
{
struct info_sector i;
if (!b->info_sector) {
printf( "No FSINFO sector\n" );
if (interactive)
printf( "1) Create one\n2) Do without FSINFO\n" );
else printf( " Not automatically creating it.\n" );
if (interactive && get_key("12","?") == '1') {
/* search for a free reserved sector (not boot sector and not
* backup boot sector) */
__u32 s;
for( s = 1; s < CF_LE_W(b->reserved); ++s )
if (s != CF_LE_W(b->backup_boot)) break;
if (s > 0 && s < CF_LE_W(b->reserved)) {
init_fsinfo(&i);
fs_write((off_t)s*lss,sizeof(i),&i);
b->info_sector = CT_LE_W(s);
fs_write((off_t)offsetof(struct boot_sector,info_sector),
sizeof(b->info_sector),&b->info_sector);
if (fs->backupboot_start)
fs_write(fs->backupboot_start+
offsetof(struct boot_sector,info_sector),
sizeof(b->info_sector),&b->info_sector);
}
else {
printf( "No free reserved sector found -- "
"no space for FSINFO sector!\n" );
return;
}
}
else return;
}
fs->fsinfo_start = CF_LE_W(b->info_sector)*lss;
fs_read(fs->fsinfo_start,sizeof(i),&i);
if (i.magic != CT_LE_L(0x41615252) ||
i.signature != CT_LE_L(0x61417272) ||
i.boot_sign != CT_LE_W(0xaa55)) {
printf( "FSINFO sector has bad magic number(s):\n" );
if (i.magic != CT_LE_L(0x41615252))
printf( " Offset %llu: 0x%08x != expected 0x%08x\n",
(__u64)offsetof(struct info_sector,magic),
CF_LE_L(i.magic),0x41615252);
if (i.signature != CT_LE_L(0x61417272))
printf( " Offset %llu: 0x%08x != expected 0x%08x\n",
(__u64)offsetof(struct info_sector,signature),
CF_LE_L(i.signature),0x61417272);
if (i.boot_sign != CT_LE_W(0xaa55))
printf( " Offset %llu: 0x%04x != expected 0x%04x\n",
(__u64)offsetof(struct info_sector,boot_sign),
CF_LE_W(i.boot_sign),0xaa55);
if (interactive)
printf( "1) Correct\n2) Don't correct (FSINFO invalid then)\n" );
else printf( " Auto-correcting it.\n" );
if (!interactive || get_key("12","?") == '1') {
init_fsinfo(&i);
fs_write(fs->fsinfo_start,sizeof(i),&i);
}
else fs->fsinfo_start = 0;
}
if (fs->fsinfo_start)
fs->free_clusters = CF_LE_L(i.free_clusters);
}
void read_boot(DOS_FS *fs)
{
struct boot_sector b;
unsigned total_sectors;
unsigned short logical_sector_size, sectors;
unsigned fat_length;
loff_t data_size;
fs_read(0,sizeof(b),&b);
logical_sector_size = GET_UNALIGNED_W(b.sector_size);
if (!logical_sector_size) die("Logical sector size is zero.");
fs->cluster_size = b.cluster_size*logical_sector_size;
if (!fs->cluster_size) die("Cluster size is zero.");
if (b.fats != 2 && b.fats != 1)
die("Currently, only 1 or 2 FATs are supported, not %d.\n",b.fats);
fs->nfats = b.fats;
sectors = GET_UNALIGNED_W(b.sectors);
total_sectors = sectors ? sectors : CF_LE_L(b.total_sect);
if (verbose) printf("Checking we can access the last sector of the filesystem\n");
/* Can't access last odd sector anyway, so round down */
fs_test((loff_t)((total_sectors & ~1)-1)*(loff_t)logical_sector_size,
logical_sector_size);
fat_length = CF_LE_W(b.fat_length) ?
CF_LE_W(b.fat_length) : CF_LE_L(b.fat32_length);
fs->fat_start = (off_t)CF_LE_W(b.reserved)*logical_sector_size;
fs->root_start = ((off_t)CF_LE_W(b.reserved)+b.fats*fat_length)*
logical_sector_size;
fs->root_entries = GET_UNALIGNED_W(b.dir_entries);
fs->data_start = fs->root_start+ROUND_TO_MULTIPLE(fs->root_entries <<
MSDOS_DIR_BITS,logical_sector_size);
data_size = (loff_t)total_sectors*logical_sector_size-fs->data_start;
fs->clusters = data_size/fs->cluster_size;
fs->root_cluster = 0; /* indicates standard, pre-FAT32 root dir */
fs->fsinfo_start = 0; /* no FSINFO structure */
fs->free_clusters = -1; /* unknown */
if (!b.fat_length && b.fat32_length) {
fs->fat_bits = 32;
fs->root_cluster = CF_LE_L(b.root_cluster);
if (!fs->root_cluster && fs->root_entries)
/* M$ hasn't specified this, but it looks reasonable: If
* root_cluster is 0 but there is a separate root dir
* (root_entries != 0), we handle the root dir the old way. Give a
* warning, but convertig to a root dir in a cluster chain seems
* to complex for now... */
printf( "Warning: FAT32 root dir not in cluster chain! "
"Compability mode...\n" );
else if (!fs->root_cluster && !fs->root_entries)
die("No root directory!");
else if (fs->root_cluster && fs->root_entries)
printf( "Warning: FAT32 root dir is in a cluster chain, but "
"a separate root dir\n"
" area is defined. Cannot fix this easily.\n" );
fs->backupboot_start = CF_LE_W(b.backup_boot)*logical_sector_size;
check_backup_boot(fs,&b,logical_sector_size);
read_fsinfo(fs,&b,logical_sector_size);
}
else if (!atari_format) {
/* On real MS-DOS, a 16 bit FAT is used whenever there would be too
* much clusers otherwise. */
fs->fat_bits = (fs->clusters > MSDOS_FAT12) ? 16 : 12;
}
else {
/* On Atari, things are more difficult: GEMDOS always uses 12bit FATs
* on floppies, and always 16 bit on harddisks. */
fs->fat_bits = 16; /* assume 16 bit FAT for now */
/* If more clusters than fat entries in 16-bit fat, we assume
* it's a real MSDOS FS with 12-bit fat. */
if (fs->clusters+2 > fat_length*logical_sector_size*8/16 ||
/* if it's a floppy disk --> 12bit fat */
device_no == 2 ||
/* if it's a ramdisk or loopback device and has one of the usual
* floppy sizes -> 12bit FAT */
((device_no == 1 || device_no == 7) &&
(total_sectors == 720 || total_sectors == 1440 ||
total_sectors == 2880)))
fs->fat_bits = 12;
}
/* On FAT32, the high 4 bits of a FAT entry are reserved */
fs->eff_fat_bits = (fs->fat_bits == 32) ? 28 : fs->fat_bits;
fs->fat_size = fat_length*logical_sector_size;
if (fs->clusters > ((__u64)fs->fat_size*8/fs->fat_bits)-2)
die("File system has %d clusters but only space for %d FAT entries.",
fs->clusters,((__u64)fs->fat_size*8/fs->fat_bits)-2);
if (!fs->root_entries && !fs->root_cluster)
die("Root directory has zero size.");
if (fs->root_entries & (MSDOS_DPS-1))
die("Root directory (%d entries) doesn't span an integral number of "
"sectors.",fs->root_entries);
if (logical_sector_size & (SECTOR_SIZE-1))
die("Logical sector size (%d bytes) is not a multiple of the physical "
"sector size.",logical_sector_size);
/* ++roman: On Atari, these two fields are often left uninitialized */
if (!atari_format && (!b.secs_track || !b.heads))
die("Invalid disk format in boot sector.");
if (verbose) dump_boot(fs,&b,logical_sector_size);
}
/* Local Variables: */
/* tab-width: 8 */
/* End: */

View file

@ -1,13 +1,13 @@
/* boot.h - Read and analyze ia PC/MS-DOS boot sector */
/* Written 1993 by Werner Almesberger */
#ifndef _BOOT_H
#define _BOOT_H
void read_boot(DOS_FS *fs);
/* Reads the boot sector from the currently open device and initializes *FS */
#endif
/* boot.h - Read and analyze ia PC/MS-DOS boot sector */
/* Written 1993 by Werner Almesberger */
#ifndef _BOOT_H
#define _BOOT_H
void read_boot(DOS_FS *fs);
/* Reads the boot sector from the currently open device and initializes *FS */
#endif

View file

@ -1,59 +1,59 @@
#ifndef _I386_BYTEORDER_H
#define _I386_BYTEORDER_H
//#include "types.h"
#include "compiler.h"
#ifdef __GNUC__
/* For avoiding bswap on i386 */
//#ifdef __KERNEL__
//#include <linux/config.h>
//#endif
static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
{
#ifdef CONFIG_X86_BSWAP
__asm__("bswap %0" : "=r" (x) : "0" (x));
#else
__asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */
"rorl $16,%0\n\t" /* swap words */
"xchgb %b0,%h0" /* swap higher bytes */
:"=q" (x)
: "0" (x));
#endif
return x;
}
static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 val)
{
union {
struct { __u32 a,b; } s;
__u64 u;
} v;
v.u = val;
#ifdef CONFIG_X86_BSWAP
asm("bswapl %0 ; bswapl %1 ; xchgl %0,%1"
: "=r" (v.s.a), "=r" (v.s.b)
: "0" (v.s.a), "1" (v.s.b));
#else
v.s.a = ___arch__swab32(v.s.a);
v.s.b = ___arch__swab32(v.s.b);
asm("xchgl %0,%1" : "=r" (v.s.a), "=r" (v.s.b) : "0" (v.s.a), "1" (v.s.b));
#endif
return v.u;
}
/* Do not define swab16. Gcc is smart enough to recognize "C" version and
convert it into rotation or exhange. */
#define __arch__swab64(x) ___arch__swab64(x)
#define __arch__swab32(x) ___arch__swab32(x)
#define __BYTEORDER_HAS_U64__
#endif /* __GNUC__ */
//#include "little_endian.h"
#endif /* _I386_BYTEORDER_H */
#ifndef _I386_BYTEORDER_H
#define _I386_BYTEORDER_H
//#include "types.h"
#include "compiler.h"
#ifdef __GNUC__
/* For avoiding bswap on i386 */
//#ifdef __KERNEL__
//#include <linux/config.h>
//#endif
static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x)
{
#ifdef CONFIG_X86_BSWAP
__asm__("bswap %0" : "=r" (x) : "0" (x));
#else
__asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */
"rorl $16,%0\n\t" /* swap words */
"xchgb %b0,%h0" /* swap higher bytes */
:"=q" (x)
: "0" (x));
#endif
return x;
}
static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 val)
{
union {
struct { __u32 a,b; } s;
__u64 u;
} v;
v.u = val;
#ifdef CONFIG_X86_BSWAP
asm("bswapl %0 ; bswapl %1 ; xchgl %0,%1"
: "=r" (v.s.a), "=r" (v.s.b)
: "0" (v.s.a), "1" (v.s.b));
#else
v.s.a = ___arch__swab32(v.s.a);
v.s.b = ___arch__swab32(v.s.b);
asm("xchgl %0,%1" : "=r" (v.s.a), "=r" (v.s.b) : "0" (v.s.a), "1" (v.s.b));
#endif
return v.u;
}
/* Do not define swab16. Gcc is smart enough to recognize "C" version and
convert it into rotation or exhange. */
#define __arch__swab64(x) ___arch__swab64(x)
#define __arch__swab32(x) ___arch__swab32(x)
#define __BYTEORDER_HAS_U64__
#endif /* __GNUC__ */
//#include "little_endian.h"
#endif /* _I386_BYTEORDER_H */

View file

@ -1,40 +1,40 @@
/* Copyright (C) 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#ifndef _BYTESWAP_H
#define _BYTESWAP_H 1
/* Get the machine specific, optimized definitions. */
#include "byteswap1.h"
/* The following definitions must all be macros since otherwise some
of the possible optimizations are not possible. */
/* Return a value with all bytes in the 16 bit argument swapped. */
#define bswap_16(x) __bswap_16 (x)
/* Return a value with all bytes in the 32 bit argument swapped. */
#define bswap_32(x) __bswap_32 (x)
#if defined __GNUC__ && __GNUC__ >= 2
/* Return a value with all bytes in the 64 bit argument swapped. */
# define bswap_64(x) __bswap_64 (x)
#endif
#endif /* byteswap.h */
/* Copyright (C) 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#ifndef _BYTESWAP_H
#define _BYTESWAP_H 1
/* Get the machine specific, optimized definitions. */
#include "byteswap1.h"
/* The following definitions must all be macros since otherwise some
of the possible optimizations are not possible. */
/* Return a value with all bytes in the 16 bit argument swapped. */
#define bswap_16(x) __bswap_16 (x)
/* Return a value with all bytes in the 32 bit argument swapped. */
#define bswap_32(x) __bswap_32 (x)
#if defined __GNUC__ && __GNUC__ >= 2
/* Return a value with all bytes in the 64 bit argument swapped. */
# define bswap_64(x) __bswap_64 (x)
#endif
#endif /* byteswap.h */

View file

@ -1,133 +1,133 @@
/* Macros to swap the order of bytes in integer values.
Copyright (C) 1997, 1998, 2000, 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#if !defined _BYTESWAP_H && !defined _NETINET_IN_H
# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead."
#endif
#ifndef _BITS_BYTESWAP_H
#define _BITS_BYTESWAP_H 1
/* Swap bytes in 16 bit value. */
#define __bswap_constant_16(x) \
((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
#ifdef __GNUC__
# if __GNUC__ >= 2
# define __bswap_16(x) \
(__extension__ \
({ register unsigned short int __v, __x = (x); \
if (__builtin_constant_p (__x)) \
__v = __bswap_constant_16 (__x); \
else \
__asm__ ("rorw $8, %w0" \
: "=r" (__v) \
: "0" (__x) \
: "cc"); \
__v; }))
# else
/* This is better than nothing. */
# define __bswap_16(x) \
(__extension__ \
({ register unsigned short int __x = (x); __bswap_constant_16 (__x); }))
# endif
#else
static __inline unsigned short int
__bswap_16 (unsigned short int __bsx)
{
return __bswap_constant_16 (__bsx);
}
#endif
/* Swap bytes in 32 bit value. */
#define __bswap_constant_32(x) \
((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
#ifdef __GNUC__
# if __GNUC__ >= 2
/* To swap the bytes in a word the i486 processors and up provide the
`bswap' opcode. On i386 we have to use three instructions. */
# if !defined __i486__ && !defined __pentium__ && !defined __pentiumpro__ \
&& !defined __pentium4__
# define __bswap_32(x) \
(__extension__ \
({ register unsigned int __v, __x = (x); \
if (__builtin_constant_p (__x)) \
__v = __bswap_constant_32 (__x); \
else \
__asm__ ("rorw $8, %w0;" \
"rorl $16, %0;" \
"rorw $8, %w0" \
: "=r" (__v) \
: "0" (__x) \
: "cc"); \
__v; }))
# else
# define __bswap_32(x) \
(__extension__ \
({ register unsigned int __v, __x = (x); \
if (__builtin_constant_p (__x)) \
__v = __bswap_constant_32 (__x); \
else \
__asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); \
__v; }))
# endif
# else
# define __bswap_32(x) \
(__extension__ \
({ register unsigned int __x = (x); __bswap_constant_32 (__x); }))
# endif
#else
static __inline unsigned int
__bswap_32 (unsigned int __bsx)
{
return __bswap_constant_32 (__bsx);
}
#endif
#if defined __GNUC__ && __GNUC__ >= 2
/* Swap bytes in 64 bit value. */
#define __bswap_constant_64(x) \
((((x) & 0xff00000000000000ull) >> 56) \
| (((x) & 0x00ff000000000000ull) >> 40) \
| (((x) & 0x0000ff0000000000ull) >> 24) \
| (((x) & 0x000000ff00000000ull) >> 8) \
| (((x) & 0x00000000ff000000ull) << 8) \
| (((x) & 0x0000000000ff0000ull) << 24) \
| (((x) & 0x000000000000ff00ull) << 40) \
| (((x) & 0x00000000000000ffull) << 56))
# define __bswap_64(x) \
(__extension__ \
({ union { __extension__ unsigned long long int __ll; \
unsigned long int __l[2]; } __w, __r; \
if (__builtin_constant_p (x)) \
__r.__ll = __bswap_constant_64 (x); \
else \
{ \
__w.__ll = (x); \
__r.__l[0] = __bswap_32 (__w.__l[1]); \
__r.__l[1] = __bswap_32 (__w.__l[0]); \
} \
__r.__ll; }))
#endif
#endif /* _BITS_BYTESWAP_H */
/* Macros to swap the order of bytes in integer values.
Copyright (C) 1997, 1998, 2000, 2002, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#if !defined _BYTESWAP_H && !defined _NETINET_IN_H
# error "Never use <bits/byteswap.h> directly; include <byteswap.h> instead."
#endif
#ifndef _BITS_BYTESWAP_H
#define _BITS_BYTESWAP_H 1
/* Swap bytes in 16 bit value. */
#define __bswap_constant_16(x) \
((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
#ifdef __GNUC__
# if __GNUC__ >= 2
# define __bswap_16(x) \
(__extension__ \
({ register unsigned short int __v, __x = (x); \
if (__builtin_constant_p (__x)) \
__v = __bswap_constant_16 (__x); \
else \
__asm__ ("rorw $8, %w0" \
: "=r" (__v) \
: "0" (__x) \
: "cc"); \
__v; }))
# else
/* This is better than nothing. */
# define __bswap_16(x) \
(__extension__ \
({ register unsigned short int __x = (x); __bswap_constant_16 (__x); }))
# endif
#else
static __inline unsigned short int
__bswap_16 (unsigned short int __bsx)
{
return __bswap_constant_16 (__bsx);
}
#endif
/* Swap bytes in 32 bit value. */
#define __bswap_constant_32(x) \
((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
#ifdef __GNUC__
# if __GNUC__ >= 2
/* To swap the bytes in a word the i486 processors and up provide the
`bswap' opcode. On i386 we have to use three instructions. */
# if !defined __i486__ && !defined __pentium__ && !defined __pentiumpro__ \
&& !defined __pentium4__
# define __bswap_32(x) \
(__extension__ \
({ register unsigned int __v, __x = (x); \
if (__builtin_constant_p (__x)) \
__v = __bswap_constant_32 (__x); \
else \
__asm__ ("rorw $8, %w0;" \
"rorl $16, %0;" \
"rorw $8, %w0" \
: "=r" (__v) \
: "0" (__x) \
: "cc"); \
__v; }))
# else
# define __bswap_32(x) \
(__extension__ \
({ register unsigned int __v, __x = (x); \
if (__builtin_constant_p (__x)) \
__v = __bswap_constant_32 (__x); \
else \
__asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); \
__v; }))
# endif
# else
# define __bswap_32(x) \
(__extension__ \
({ register unsigned int __x = (x); __bswap_constant_32 (__x); }))
# endif
#else
static __inline unsigned int
__bswap_32 (unsigned int __bsx)
{
return __bswap_constant_32 (__bsx);
}
#endif
#if defined __GNUC__ && __GNUC__ >= 2
/* Swap bytes in 64 bit value. */
#define __bswap_constant_64(x) \
((((x) & 0xff00000000000000ull) >> 56) \
| (((x) & 0x00ff000000000000ull) >> 40) \
| (((x) & 0x0000ff0000000000ull) >> 24) \
| (((x) & 0x000000ff00000000ull) >> 8) \
| (((x) & 0x00000000ff000000ull) << 8) \
| (((x) & 0x0000000000ff0000ull) << 24) \
| (((x) & 0x000000000000ff00ull) << 40) \
| (((x) & 0x00000000000000ffull) << 56))
# define __bswap_64(x) \
(__extension__ \
({ union { __extension__ unsigned long long int __ll; \
unsigned long int __l[2]; } __w, __r; \
if (__builtin_constant_p (x)) \
__r.__ll = __bswap_constant_64 (x); \
else \
{ \
__w.__ll = (x); \
__r.__l[0] = __bswap_32 (__w.__l[1]); \
__r.__l[1] = __bswap_32 (__w.__l[0]); \
} \
__r.__ll; }))
#endif
#endif /* _BITS_BYTESWAP_H */

File diff suppressed because it is too large Load diff

View file

@ -1,23 +1,23 @@
/* check.h - Check and repair a PC/MS-DOS file system */
/* Written 1993 by Werner Almesberger */
#ifndef _CHECK_H
#define _CHECK_H
loff_t alloc_rootdir_entry(DOS_FS *fs, DIR_ENT *de, const char *pattern);
/* Allocate a free slot in the root directory for a new file. The file name is
constructed after 'pattern', which must include a %d type format for printf
and expand to exactly 11 characters. The name actually used is written into
the 'de' structure, the rest of *de is cleared. The offset returned is to
where in the filesystem the entry belongs. */
int scan_root(DOS_FS *fs);
/* Scans the root directory and recurses into all subdirectories. See check.c
for all the details. Returns a non-zero integer if the file system has to
be checked again. */
#endif
/* check.h - Check and repair a PC/MS-DOS file system */
/* Written 1993 by Werner Almesberger */
#ifndef _CHECK_H
#define _CHECK_H
loff_t alloc_rootdir_entry(DOS_FS *fs, DIR_ENT *de, const char *pattern);
/* Allocate a free slot in the root directory for a new file. The file name is
constructed after 'pattern', which must include a %d type format for printf
and expand to exactly 11 characters. The name actually used is written into
the 'de' structure, the rest of *de is cleared. The offset returned is to
where in the filesystem the entry belongs. */
int scan_root(DOS_FS *fs);
/* Scans the root directory and recurses into all subdirectories. See check.c
for all the details. Returns a non-zero integer if the file system has to
be checked again. */
#endif

View file

@ -1,110 +1,110 @@
/* common.c - Common functions */
/* Written 1993 by Werner Almesberger */
/* FAT32, VFAT, Atari format support, and various fixes additions May 1998
* by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include "common.h"
typedef struct _link {
void *data;
struct _link *next;
} LINK;
void die(char *msg,...)
{
va_list args;
va_start(args,msg);
vfprintf(stderr,msg,args);
va_end(args);
fprintf(stderr,"\n");
exit(1);
}
void pdie(char *msg,...)
{
va_list args;
va_start(args,msg);
vfprintf(stderr,msg,args);
va_end(args);
fprintf(stderr,":%s\n",strerror(errno));
exit(1);
}
void *alloc(int size)
{
void *this;
if ((this = malloc(size))) return this;
pdie("malloc");
return NULL; /* for GCC */
}
void *qalloc(void **root,int size)
{
LINK *link;
link = alloc(sizeof(LINK));
link->next = *root;
*root = link;
return link->data = alloc(size);
}
void qfree(void **root)
{
LINK *this;
while (*root) {
this = (LINK *) *root;
*root = this->next;
free(this->data);
free(this);
}
}
#ifdef min
#undef min
#endif
int min(int a,int b)
{
return a < b ? a : b;
}
char get_key(char *valid,char *prompt)
{
int ch,okay;
while (1) {
if (prompt) printf("%s ",prompt);
fflush(stdout);
while (ch = getchar(), ch == ' ' || ch == '\t');
if (ch == EOF) exit(1);
if (!strchr(valid,okay = ch)) okay = 0;
while (ch = getchar(), ch != '\n' && ch != EOF);
if (ch == EOF) exit(1);
if (okay) return okay;
printf("Invalid input.\n");
}
}
/* Local Variables: */
/* tab-width: 8 */
/* End: */
/* common.c - Common functions */
/* Written 1993 by Werner Almesberger */
/* FAT32, VFAT, Atari format support, and various fixes additions May 1998
* by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include "common.h"
typedef struct _link {
void *data;
struct _link *next;
} LINK;
void die(char *msg,...)
{
va_list args;
va_start(args,msg);
vfprintf(stderr,msg,args);
va_end(args);
fprintf(stderr,"\n");
exit(1);
}
void pdie(char *msg,...)
{
va_list args;
va_start(args,msg);
vfprintf(stderr,msg,args);
va_end(args);
fprintf(stderr,":%s\n",strerror(errno));
exit(1);
}
void *alloc(int size)
{
void *this;
if ((this = malloc(size))) return this;
pdie("malloc");
return NULL; /* for GCC */
}
void *qalloc(void **root,int size)
{
LINK *link;
link = alloc(sizeof(LINK));
link->next = *root;
*root = link;
return link->data = alloc(size);
}
void qfree(void **root)
{
LINK *this;
while (*root) {
this = (LINK *) *root;
*root = this->next;
free(this->data);
free(this);
}
}
#ifdef min
#undef min
#endif
int min(int a,int b)
{
return a < b ? a : b;
}
char get_key(char *valid,char *prompt)
{
int ch,okay;
while (1) {
if (prompt) printf("%s ",prompt);
fflush(stdout);
while (ch = getchar(), ch == ' ' || ch == '\t');
if (ch == EOF) exit(1);
if (!strchr(valid,okay = ch)) okay = 0;
while (ch = getchar(), ch != '\n' && ch != EOF);
if (ch == EOF) exit(1);
if (okay) return okay;
printf("Invalid input.\n");
}
}
/* Local Variables: */
/* tab-width: 8 */
/* End: */

View file

@ -1,42 +1,42 @@
/* common.h - Common functions */
# define MSDOS_FAT12 4084 /* maximum number of clusters in a 12 bit FAT */
#include "version.h"
#ifndef _COMMON_H
#define _COMMON_H
//void die(char *msg,...) __attribute((noreturn));
__declspec(noreturn) void die(char *msg,...);
/* Displays a prinf-style message and terminates the program. */
//void pdie(char *msg,...) __attribute((noreturn));
__declspec(noreturn) void pdie(char *msg,...);
/* Like die, but appends an error message according to the state of errno. */
void *alloc(int size);
/* mallocs SIZE bytes and returns a pointer to the data. Terminates the program
if malloc fails. */
void *qalloc(void **root,int size);
/* Like alloc, but registers the data area in a list described by ROOT. */
void qfree(void **root);
/* Deallocates all qalloc'ed data areas described by ROOT. */
//int min(int a,int b);
/* Returns the smaller integer value of a and b. */
char get_key(char *valid,char *prompt);
/* Displays PROMPT and waits for user input. Only characters in VALID are
accepted. Terminates the program on EOF. Returns the character. */
#endif
/* common.h - Common functions */
# define MSDOS_FAT12 4084 /* maximum number of clusters in a 12 bit FAT */
#include "version.h"
#ifndef _COMMON_H
#define _COMMON_H
//void die(char *msg,...) __attribute((noreturn));
__declspec(noreturn) void die(char *msg,...);
/* Displays a prinf-style message and terminates the program. */
//void pdie(char *msg,...) __attribute((noreturn));
__declspec(noreturn) void pdie(char *msg,...);
/* Like die, but appends an error message according to the state of errno. */
void *alloc(int size);
/* mallocs SIZE bytes and returns a pointer to the data. Terminates the program
if malloc fails. */
void *qalloc(void **root,int size);
/* Like alloc, but registers the data area in a list described by ROOT. */
void qfree(void **root);
/* Deallocates all qalloc'ed data areas described by ROOT. */
//int min(int a,int b);
/* Returns the smaller integer value of a and b. */
char get_key(char *valid,char *prompt);
/* Displays PROMPT and waits for user input. Only characters in VALID are
accepted. Terminates the program on EOF. Returns the character. */
#endif

View file

@ -1,158 +1,158 @@
#ifndef __LINUX_COMPILER_H
#define __LINUX_COMPILER_H
#ifndef __ASSEMBLY__
#ifdef __CHECKER__
# define __user __attribute__((noderef, address_space(1)))
# define __kernel /* default address space */
# define __safe __attribute__((safe))
# define __force __attribute__((force))
# define __nocast __attribute__((nocast))
# define __iomem __attribute__((noderef, address_space(2)))
# define __acquires(x) __attribute__((context(0,1)))
# define __releases(x) __attribute__((context(1,0)))
# define __acquire(x) __context__(1)
# define __release(x) __context__(-1)
# define __cond_lock(x) ((x) ? ({ __context__(1); 1; }) : 0)
extern void __chk_user_ptr(void __user *);
extern void __chk_io_ptr(void __iomem *);
#else
# define __user
# define __kernel
# define __safe
# define __force
# define __nocast
# define __iomem
# define __chk_user_ptr(x) (void)0
# define __chk_io_ptr(x) (void)0
//# define __builtin_warning(x, y...) (1)
# define __acquires(x)
# define __releases(x)
# define __acquire(x) (void)0
# define __release(x) (void)0
# define __cond_lock(x) (x)
#endif
#ifdef __KERNEL__
#if __GNUC__ > 4
#error no compiler-gcc.h file for this gcc version
#elif __GNUC__ == 4
# include <linux/compiler-gcc4.h>
#elif __GNUC__ == 3
# include <linux/compiler-gcc3.h>
#elif __GNUC__ == 2
# include <linux/compiler-gcc2.h>
#else
# error Sorry, your compiler is too old/not recognized.
#endif
/* Intel compiler defines __GNUC__. So we will overwrite implementations
* coming from above header files here
*/
#ifdef __INTEL_COMPILER
# include <linux/compiler-intel.h>
#endif
/*
* Generic compiler-dependent macros required for kernel
* build go below this comment. Actual compiler/compiler version
* specific implementations come from the above header files
*/
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
/* Optimization barrier */
#ifndef barrier
# define barrier() __memory_barrier()
#endif
#ifndef RELOC_HIDE
# define RELOC_HIDE(ptr, off) \
({ unsigned long __ptr; \
__ptr = (unsigned long) (ptr); \
(typeof(ptr)) (__ptr + (off)); })
#endif
#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
/*
* Allow us to mark functions as 'deprecated' and have gcc emit a nice
* warning for each use, in hopes of speeding the functions removal.
* Usage is:
* int __deprecated foo(void)
*/
#ifndef __deprecated
# define __deprecated /* unimplemented */
#endif
#ifdef MODULE
#define __deprecated_for_modules __deprecated
#else
#define __deprecated_for_modules
#endif
#ifndef __must_check
#define __must_check
#endif
/*
* Allow us to avoid 'defined but not used' warnings on functions and data,
* as well as force them to be emitted to the assembly file.
*
* As of gcc 3.3, static functions that are not marked with attribute((used))
* may be elided from the assembly file. As of gcc 3.3, static data not so
* marked will not be elided, but this may change in a future gcc version.
*
* In prior versions of gcc, such functions and data would be emitted, but
* would be warned about except with attribute((unused)).
*/
#ifndef __attribute_used__
# define __attribute_used__ /* unimplemented */
#endif
/*
* From the GCC manual:
*
* Many functions have no effects except the return value and their
* return value depends only on the parameters and/or global
* variables. Such a function can be subject to common subexpression
* elimination and loop optimization just as an arithmetic operator
* would be.
* [...]
*/
#ifndef __attribute_pure__
# define __attribute_pure__ /* unimplemented */
#endif
/*
* From the GCC manual:
*
* Many functions do not examine any values except their arguments,
* and have no effects except the return value. Basically this is
* just slightly more strict class than the `pure' attribute above,
* since function is not allowed to read global memory.
*
* Note that a function that has pointer arguments and examines the
* data pointed to must _not_ be declared `const'. Likewise, a
* function that calls a non-`const' function usually must not be
* `const'. It does not make sense for a `const' function to return
* `void'.
*/
#ifndef __attribute_const__
# define __attribute_const__ /* unimplemented */
#endif
#ifndef noinline
#define noinline
#endif
#ifndef __always_inline
#define __always_inline inline
#endif
#endif /* __LINUX_COMPILER_H */
#ifndef __LINUX_COMPILER_H
#define __LINUX_COMPILER_H
#ifndef __ASSEMBLY__
#ifdef __CHECKER__
# define __user __attribute__((noderef, address_space(1)))
# define __kernel /* default address space */
# define __safe __attribute__((safe))
# define __force __attribute__((force))
# define __nocast __attribute__((nocast))
# define __iomem __attribute__((noderef, address_space(2)))
# define __acquires(x) __attribute__((context(0,1)))
# define __releases(x) __attribute__((context(1,0)))
# define __acquire(x) __context__(1)
# define __release(x) __context__(-1)
# define __cond_lock(x) ((x) ? ({ __context__(1); 1; }) : 0)
extern void __chk_user_ptr(void __user *);
extern void __chk_io_ptr(void __iomem *);
#else
# define __user
# define __kernel
# define __safe
# define __force
# define __nocast
# define __iomem
# define __chk_user_ptr(x) (void)0
# define __chk_io_ptr(x) (void)0
//# define __builtin_warning(x, y...) (1)
# define __acquires(x)
# define __releases(x)
# define __acquire(x) (void)0
# define __release(x) (void)0
# define __cond_lock(x) (x)
#endif
#ifdef __KERNEL__
#if __GNUC__ > 4
#error no compiler-gcc.h file for this gcc version
#elif __GNUC__ == 4
# include <linux/compiler-gcc4.h>
#elif __GNUC__ == 3
# include <linux/compiler-gcc3.h>
#elif __GNUC__ == 2
# include <linux/compiler-gcc2.h>
#else
# error Sorry, your compiler is too old/not recognized.
#endif
/* Intel compiler defines __GNUC__. So we will overwrite implementations
* coming from above header files here
*/
#ifdef __INTEL_COMPILER
# include <linux/compiler-intel.h>
#endif
/*
* Generic compiler-dependent macros required for kernel
* build go below this comment. Actual compiler/compiler version
* specific implementations come from the above header files
*/
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
/* Optimization barrier */
#ifndef barrier
# define barrier() __memory_barrier()
#endif
#ifndef RELOC_HIDE
# define RELOC_HIDE(ptr, off) \
({ unsigned long __ptr; \
__ptr = (unsigned long) (ptr); \
(typeof(ptr)) (__ptr + (off)); })
#endif
#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
/*
* Allow us to mark functions as 'deprecated' and have gcc emit a nice
* warning for each use, in hopes of speeding the functions removal.
* Usage is:
* int __deprecated foo(void)
*/
#ifndef __deprecated
# define __deprecated /* unimplemented */
#endif
#ifdef MODULE
#define __deprecated_for_modules __deprecated
#else
#define __deprecated_for_modules
#endif
#ifndef __must_check
#define __must_check
#endif
/*
* Allow us to avoid 'defined but not used' warnings on functions and data,
* as well as force them to be emitted to the assembly file.
*
* As of gcc 3.3, static functions that are not marked with attribute((used))
* may be elided from the assembly file. As of gcc 3.3, static data not so
* marked will not be elided, but this may change in a future gcc version.
*
* In prior versions of gcc, such functions and data would be emitted, but
* would be warned about except with attribute((unused)).
*/
#ifndef __attribute_used__
# define __attribute_used__ /* unimplemented */
#endif
/*
* From the GCC manual:
*
* Many functions have no effects except the return value and their
* return value depends only on the parameters and/or global
* variables. Such a function can be subject to common subexpression
* elimination and loop optimization just as an arithmetic operator
* would be.
* [...]
*/
#ifndef __attribute_pure__
# define __attribute_pure__ /* unimplemented */
#endif
/*
* From the GCC manual:
*
* Many functions do not examine any values except their arguments,
* and have no effects except the return value. Basically this is
* just slightly more strict class than the `pure' attribute above,
* since function is not allowed to read global memory.
*
* Note that a function that has pointer arguments and examines the
* data pointed to must _not_ be declared `const'. Likewise, a
* function that calls a non-`const' function usually must not be
* `const'. It does not make sense for a `const' function to return
* `void'.
*/
#ifndef __attribute_const__
# define __attribute_const__ /* unimplemented */
#endif
#ifndef noinline
#define noinline
#endif
#ifndef __always_inline
#define __always_inline inline
#endif
#endif /* __LINUX_COMPILER_H */

View file

@ -1,184 +1,184 @@
/* dosfsck.c - User interface */
/* Written 1993 by Werner Almesberger */
/* FAT32, VFAT, Atari format support, and various fixes additions May 1998
* by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */
#include "version.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include "common.h"
#include "dosfsck.h"
#include "io.h"
#include "boot.h"
#include "fat.h"
#include "file.h"
#include "check.h"
int interactive = 0,list = 0,test = 0,verbose = 0,write_immed = 0;
int atari_format = 0;
unsigned n_files = 0;
void *mem_queue = NULL;
static void usage(char *name)
{
fprintf(stderr,"usage: %s [-aAflrtvVwy] [-d path -d ...] "
"[-u path -u ...]\n%15sdevice\n",name,"");
fprintf(stderr," -a automatically repair the file system\n");
fprintf(stderr," -A toggle Atari file system format\n");
fprintf(stderr," -d path drop that file\n");
fprintf(stderr," -f salvage unused chains to files\n");
fprintf(stderr," -l list path names\n");
fprintf(stderr," -n no-op, check non-interactively without changing\n");
fprintf(stderr," -r interactively repair the file system\n");
fprintf(stderr," -t test for bad clusters\n");
fprintf(stderr," -u path try to undelete that (non-directory) file\n");
fprintf(stderr," -v verbose mode\n");
fprintf(stderr," -V perform a verification pass\n");
fprintf(stderr," -w write changes to disk immediately\n");
fprintf(stderr," -y same as -a, for compat with other *fsck\n");
exit(2);
}
/*
* ++roman: On m68k, check if this is an Atari; if yes, turn on Atari variant
* of MS-DOS filesystem by default.
*/
static void check_atari( void )
{
#ifdef __mc68000__
FILE *f;
char line[128], *p;
if (!(f = fopen( "/proc/hardware", "r" ))) {
perror( "/proc/hardware" );
return;
}
while( fgets( line, sizeof(line), f ) ) {
if (strncmp( line, "Model:", 6 ) == 0) {
p = line + 6;
p += strspn( p, " \t" );
if (strncmp( p, "Atari ", 6 ) == 0)
atari_format = 1;
break;
}
}
fclose( f );
#endif
}
int main(int argc,char **argv)
{
DOS_FS fs;
int rw,salvage_files,verify,c;
unsigned long free_clusters;
rw = salvage_files = verify = 0;
interactive = 1;
check_atari();
while ((c = getopt(argc,argv,"Aad:flnrtu:vVwy")) != EOF)
switch (c) {
case 'A': /* toggle Atari format */
atari_format = !atari_format;
break;
case 'a':
case 'y':
rw = 1;
interactive = 0;
salvage_files = 1;
break;
case 'd':
file_add(optarg,fdt_drop);
break;
case 'f':
salvage_files = 1;
break;
case 'l':
list = 1;
break;
case 'n':
rw = 0;
interactive = 0;
break;
case 'r':
rw = 1;
interactive = 1;
break;
case 't':
test = 1;
break;
case 'u':
file_add(optarg,fdt_undelete);
break;
case 'v':
verbose = 1;
printf("dosfsck " VERSION " (" VERSION_DATE ")\n");
break;
case 'V':
verify = 1;
break;
case 'w':
write_immed = 1;
break;
default:
usage(argv[0]);
}
if ((test || write_immed) && !rw) {
fprintf(stderr,"-t and -w require -a or -r\n");
exit(2);
}
if (optind != argc-1) usage(argv[0]);
printf( "dosfsck " VERSION ", " VERSION_DATE ", FAT32, LFN\n" );
fs_open(argv[optind],rw);
read_boot(&fs);
if (verify) printf("Starting check/repair pass.\n");
while (read_fat(&fs), scan_root(&fs)) qfree(&mem_queue);
if (test) fix_bad(&fs);
if (salvage_files) reclaim_file(&fs);
else reclaim_free(&fs);
free_clusters = update_free(&fs);
file_unused();
qfree(&mem_queue);
if (verify) {
printf("Starting verification pass.\n");
read_fat(&fs);
scan_root(&fs);
reclaim_free(&fs);
qfree(&mem_queue);
}
if (fs_changed()) {
if (rw) {
if (interactive)
rw = get_key("yn","Perform changes ? (y/n)") == 'y';
else printf("Performing changes.\n");
}
else
printf("Leaving file system unchanged.\n");
}
printf( "%s: %u files, %lu/%lu clusters\n", argv[optind],
n_files, fs.clusters - free_clusters, fs.clusters );
return fs_close(rw) ? 1 : 0;
}
/* Local Variables: */
/* tab-width: 8 */
/* End: */
/* dosfsck.c - User interface */
/* Written 1993 by Werner Almesberger */
/* FAT32, VFAT, Atari format support, and various fixes additions May 1998
* by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */
#include "version.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include "common.h"
#include "dosfsck.h"
#include "io.h"
#include "boot.h"
#include "fat.h"
#include "file.h"
#include "check.h"
int interactive = 0,list = 0,test = 0,verbose = 0,write_immed = 0;
int atari_format = 0;
unsigned n_files = 0;
void *mem_queue = NULL;
static void usage(char *name)
{
fprintf(stderr,"usage: %s [-aAflrtvVwy] [-d path -d ...] "
"[-u path -u ...]\n%15sdevice\n",name,"");
fprintf(stderr," -a automatically repair the file system\n");
fprintf(stderr," -A toggle Atari file system format\n");
fprintf(stderr," -d path drop that file\n");
fprintf(stderr," -f salvage unused chains to files\n");
fprintf(stderr," -l list path names\n");
fprintf(stderr," -n no-op, check non-interactively without changing\n");
fprintf(stderr," -r interactively repair the file system\n");
fprintf(stderr," -t test for bad clusters\n");
fprintf(stderr," -u path try to undelete that (non-directory) file\n");
fprintf(stderr," -v verbose mode\n");
fprintf(stderr," -V perform a verification pass\n");
fprintf(stderr," -w write changes to disk immediately\n");
fprintf(stderr," -y same as -a, for compat with other *fsck\n");
exit(2);
}
/*
* ++roman: On m68k, check if this is an Atari; if yes, turn on Atari variant
* of MS-DOS filesystem by default.
*/
static void check_atari( void )
{
#ifdef __mc68000__
FILE *f;
char line[128], *p;
if (!(f = fopen( "/proc/hardware", "r" ))) {
perror( "/proc/hardware" );
return;
}
while( fgets( line, sizeof(line), f ) ) {
if (strncmp( line, "Model:", 6 ) == 0) {
p = line + 6;
p += strspn( p, " \t" );
if (strncmp( p, "Atari ", 6 ) == 0)
atari_format = 1;
break;
}
}
fclose( f );
#endif
}
int main(int argc,char **argv)
{
DOS_FS fs;
int rw,salvage_files,verify,c;
unsigned long free_clusters;
rw = salvage_files = verify = 0;
interactive = 1;
check_atari();
while ((c = getopt(argc,argv,"Aad:flnrtu:vVwy")) != EOF)
switch (c) {
case 'A': /* toggle Atari format */
atari_format = !atari_format;
break;
case 'a':
case 'y':
rw = 1;
interactive = 0;
salvage_files = 1;
break;
case 'd':
file_add(optarg,fdt_drop);
break;
case 'f':
salvage_files = 1;
break;
case 'l':
list = 1;
break;
case 'n':
rw = 0;
interactive = 0;
break;
case 'r':
rw = 1;
interactive = 1;
break;
case 't':
test = 1;
break;
case 'u':
file_add(optarg,fdt_undelete);
break;
case 'v':
verbose = 1;
printf("dosfsck " VERSION " (" VERSION_DATE ")\n");
break;
case 'V':
verify = 1;
break;
case 'w':
write_immed = 1;
break;
default:
usage(argv[0]);
}
if ((test || write_immed) && !rw) {
fprintf(stderr,"-t and -w require -a or -r\n");
exit(2);
}
if (optind != argc-1) usage(argv[0]);
printf( "dosfsck " VERSION ", " VERSION_DATE ", FAT32, LFN\n" );
fs_open(argv[optind],rw);
read_boot(&fs);
if (verify) printf("Starting check/repair pass.\n");
while (read_fat(&fs), scan_root(&fs)) qfree(&mem_queue);
if (test) fix_bad(&fs);
if (salvage_files) reclaim_file(&fs);
else reclaim_free(&fs);
free_clusters = update_free(&fs);
file_unused();
qfree(&mem_queue);
if (verify) {
printf("Starting verification pass.\n");
read_fat(&fs);
scan_root(&fs);
reclaim_free(&fs);
qfree(&mem_queue);
}
if (fs_changed()) {
if (rw) {
if (interactive)
rw = get_key("yn","Perform changes ? (y/n)") == 'y';
else printf("Performing changes.\n");
}
else
printf("Leaving file system unchanged.\n");
}
printf( "%s: %u files, %lu/%lu clusters\n", argv[optind],
n_files, fs.clusters - free_clusters, fs.clusters );
return fs_close(rw) ? 1 : 0;
}
/* Local Variables: */
/* tab-width: 8 */
/* End: */

View file

@ -1,187 +1,187 @@
/* dosfsck.h - Common data structures and global variables */
/* Written 1993 by Werner Almesberger */
/* FAT32, VFAT, Atari format support, and various fixes additions May 1998
* by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */
#ifndef _DOSFSCK_H
#define _DOSFSCK_H
//#include "types.h"
#ifdef _WIN32
typedef unsigned char __u8;
typedef unsigned short __u16;
typedef unsigned int __u32;
typedef unsigned __int64 __u64;
typedef unsigned short __le16;
typedef unsigned int __le32;
typedef __int64 loff_t;
typedef __int64 ll_t;
#define CF_LE_W(v) (v)
#define CF_LE_L(v) (v)
#define CT_LE_W(v) (v)
#define CT_LE_L(v) (v)
#endif
#define _LINUX_STAT_H /* hack to avoid inclusion of <linux/stat.h> */
#define _LINUX_STRING_H_ /* hack to avoid inclusion of <linux/string.h>*/
#define _LINUX_FS_H /* hack to avoid inclusion of <linux/fs.h> */
//#include <linux/version.h>
//# include "types.h"
# include "byteorder.h"
#include "msdos_fs.h"
#if 0
#undef CF_LE_W
#undef CF_LE_L
#undef CT_LE_W
#undef CT_LE_L
#endif
#if __BYTE_ORDER == __BIG_ENDIAN
#include "byteswap.h"
#if 0
#define CF_LE_W(v) bswap_16(v)
#define CF_LE_L(v) bswap_32(v)
#define CT_LE_W(v) CF_LE_W(v)
#define CT_LE_L(v) CF_LE_L(v)
#endif
#else
#define CF_LE_W(v) (v)
#define CF_LE_L(v) (v)
#define CT_LE_W(v) (v)
#define CT_LE_L(v) (v)
#endif /* __BIG_ENDIAN */
#define VFAT_LN_ATTR (ATTR_RO | ATTR_HIDDEN | ATTR_SYS | ATTR_VOLUME)
#include <pshpack1.h>
/* ++roman: Use own definition of boot sector structure -- the kernel headers'
* name for it is msdos_boot_sector in 2.0 and fat_boot_sector in 2.1 ... */
struct boot_sector {
__u8 ignored[3]; /* Boot strap short or near jump */
__u8 system_id[8]; /* Name - can be used to special case
partition manager volumes */
__u8 sector_size[2]; /* bytes per logical sector */
__u8 cluster_size; /* sectors/cluster */
__u16 reserved; /* reserved sectors */
__u8 fats; /* number of FATs */
__u8 dir_entries[2]; /* root directory entries */
__u8 sectors[2]; /* number of sectors */
__u8 media; /* media code (unused) */
__u16 fat_length; /* sectors/FAT */
__u16 secs_track; /* sectors per track */
__u16 heads; /* number of heads */
__u32 hidden; /* hidden sectors (unused) */
__u32 total_sect; /* number of sectors (if sectors == 0) */
/* The following fields are only used by FAT32 */
__u32 fat32_length; /* sectors/FAT */
__u16 flags; /* bit 8: fat mirroring, low 4: active fat */
__u8 version[2]; /* major, minor filesystem version */
__u32 root_cluster; /* first cluster in root directory */
__u16 info_sector; /* filesystem info sector */
__u16 backup_boot; /* backup boot sector */
__u16 reserved2[6]; /* Unused */
/* fill up to 512 bytes */
__u8 junk[448];
};
#include <poppack.h>
struct info_sector {
__u32 magic; /* Magic for info sector ('RRaA') */
__u8 junk[0x1dc];
__u32 reserved1; /* Nothing as far as I can tell */
__u32 signature; /* 0x61417272 ('rrAa') */
__u32 free_clusters; /* Free cluster count. -1 if unknown */
__u32 next_cluster; /* Most recently allocated cluster. */
__u32 reserved2[3];
__u16 reserved3;
__u16 boot_sign;
};
typedef struct {
__u8 name[8],ext[3]; /* name and extension */
__u8 attr; /* attribute bits */
__u8 lcase; /* Case for base and extension */
__u8 ctime_ms; /* Creation time, milliseconds */
__u16 ctime; /* Creation time */
__u16 cdate; /* Creation date */
__u16 adate; /* Last access date */
__u16 starthi; /* High 16 bits of cluster in FAT32 */
__u16 time,date,start;/* time, date and first cluster */
__u32 size; /* file size (in bytes) */
} DIR_ENT;
typedef struct _dos_file {
DIR_ENT dir_ent;
char *lfn;
loff_t offset;
struct _dos_file *parent; /* parent directory */
struct _dos_file *next; /* next entry */
struct _dos_file *first; /* first entry (directory only) */
} DOS_FILE;
typedef struct {
unsigned long value;
unsigned long reserved;
DOS_FILE *owner;
int prev; /* number of previous clusters */
} FAT_ENTRY;
typedef struct {
int nfats;
loff_t fat_start;
unsigned int fat_size; /* unit is bytes */
unsigned int fat_bits; /* size of a FAT entry */
unsigned int eff_fat_bits; /* # of used bits in a FAT entry */
unsigned long root_cluster; /* 0 for old-style root dir */
loff_t root_start;
unsigned int root_entries;
loff_t data_start;
unsigned int cluster_size;
unsigned long clusters;
loff_t fsinfo_start; /* 0 if not present */
long free_clusters;
loff_t backupboot_start; /* 0 if not present */
FAT_ENTRY *fat;
} DOS_FS;
#ifndef offsetof
#define offsetof(t,e) ((int)&(((t *)0)->e))
#endif
extern int interactive,list,verbose,test,write_immed;
extern int atari_format;
extern unsigned n_files;
extern void *mem_queue;
/* value to use as end-of-file marker */
#define FAT_EOF(fs) ((atari_format ? 0xfff : 0xff8) | FAT_EXTD(fs))
#define FAT_IS_EOF(fs,v) ((unsigned long)(v) >= (0xff8|FAT_EXTD(fs)))
/* value to mark bad clusters */
#define FAT_BAD(fs) (0xff7 | FAT_EXTD(fs))
/* range of values used for bad clusters */
#define FAT_MIN_BAD(fs) ((atari_format ? 0xff0 : 0xff7) | FAT_EXTD(fs))
#define FAT_MAX_BAD(fs) ((atari_format ? 0xff7 : 0xff7) | FAT_EXTD(fs))
#define FAT_IS_BAD(fs,v) ((v) >= FAT_MIN_BAD(fs) && (v) <= FAT_MAX_BAD(fs))
/* return -16 as a number with fs->fat_bits bits */
#define FAT_EXTD(fs) (((1 << fs->eff_fat_bits)-1) & ~0xf)
#endif
/* Local Variables: */
/* tab-width: 8 */
/* End: */
/* dosfsck.h - Common data structures and global variables */
/* Written 1993 by Werner Almesberger */
/* FAT32, VFAT, Atari format support, and various fixes additions May 1998
* by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */
#ifndef _DOSFSCK_H
#define _DOSFSCK_H
//#include "types.h"
#ifdef _WIN32
typedef unsigned char __u8;
typedef unsigned short __u16;
typedef unsigned int __u32;
typedef unsigned __int64 __u64;
typedef unsigned short __le16;
typedef unsigned int __le32;
typedef __int64 loff_t;
typedef __int64 ll_t;
#define CF_LE_W(v) (v)
#define CF_LE_L(v) (v)
#define CT_LE_W(v) (v)
#define CT_LE_L(v) (v)
#endif
#define _LINUX_STAT_H /* hack to avoid inclusion of <linux/stat.h> */
#define _LINUX_STRING_H_ /* hack to avoid inclusion of <linux/string.h>*/
#define _LINUX_FS_H /* hack to avoid inclusion of <linux/fs.h> */
//#include <linux/version.h>
//# include "types.h"
# include "byteorder.h"
#include "msdos_fs.h"
#if 0
#undef CF_LE_W
#undef CF_LE_L
#undef CT_LE_W
#undef CT_LE_L
#endif
#if __BYTE_ORDER == __BIG_ENDIAN
#include "byteswap.h"
#if 0
#define CF_LE_W(v) bswap_16(v)
#define CF_LE_L(v) bswap_32(v)
#define CT_LE_W(v) CF_LE_W(v)
#define CT_LE_L(v) CF_LE_L(v)
#endif
#else
#define CF_LE_W(v) (v)
#define CF_LE_L(v) (v)
#define CT_LE_W(v) (v)
#define CT_LE_L(v) (v)
#endif /* __BIG_ENDIAN */
#define VFAT_LN_ATTR (ATTR_RO | ATTR_HIDDEN | ATTR_SYS | ATTR_VOLUME)
#include <pshpack1.h>
/* ++roman: Use own definition of boot sector structure -- the kernel headers'
* name for it is msdos_boot_sector in 2.0 and fat_boot_sector in 2.1 ... */
struct boot_sector {
__u8 ignored[3]; /* Boot strap short or near jump */
__u8 system_id[8]; /* Name - can be used to special case
partition manager volumes */
__u8 sector_size[2]; /* bytes per logical sector */
__u8 cluster_size; /* sectors/cluster */
__u16 reserved; /* reserved sectors */
__u8 fats; /* number of FATs */
__u8 dir_entries[2]; /* root directory entries */
__u8 sectors[2]; /* number of sectors */
__u8 media; /* media code (unused) */
__u16 fat_length; /* sectors/FAT */
__u16 secs_track; /* sectors per track */
__u16 heads; /* number of heads */
__u32 hidden; /* hidden sectors (unused) */
__u32 total_sect; /* number of sectors (if sectors == 0) */
/* The following fields are only used by FAT32 */
__u32 fat32_length; /* sectors/FAT */
__u16 flags; /* bit 8: fat mirroring, low 4: active fat */
__u8 version[2]; /* major, minor filesystem version */
__u32 root_cluster; /* first cluster in root directory */
__u16 info_sector; /* filesystem info sector */
__u16 backup_boot; /* backup boot sector */
__u16 reserved2[6]; /* Unused */
/* fill up to 512 bytes */
__u8 junk[448];
};
#include <poppack.h>
struct info_sector {
__u32 magic; /* Magic for info sector ('RRaA') */
__u8 junk[0x1dc];
__u32 reserved1; /* Nothing as far as I can tell */
__u32 signature; /* 0x61417272 ('rrAa') */
__u32 free_clusters; /* Free cluster count. -1 if unknown */
__u32 next_cluster; /* Most recently allocated cluster. */
__u32 reserved2[3];
__u16 reserved3;
__u16 boot_sign;
};
typedef struct {
__u8 name[8],ext[3]; /* name and extension */
__u8 attr; /* attribute bits */
__u8 lcase; /* Case for base and extension */
__u8 ctime_ms; /* Creation time, milliseconds */
__u16 ctime; /* Creation time */
__u16 cdate; /* Creation date */
__u16 adate; /* Last access date */
__u16 starthi; /* High 16 bits of cluster in FAT32 */
__u16 time,date,start;/* time, date and first cluster */
__u32 size; /* file size (in bytes) */
} DIR_ENT;
typedef struct _dos_file {
DIR_ENT dir_ent;
char *lfn;
loff_t offset;
struct _dos_file *parent; /* parent directory */
struct _dos_file *next; /* next entry */
struct _dos_file *first; /* first entry (directory only) */
} DOS_FILE;
typedef struct {
unsigned long value;
unsigned long reserved;
DOS_FILE *owner;
int prev; /* number of previous clusters */
} FAT_ENTRY;
typedef struct {
int nfats;
loff_t fat_start;
unsigned int fat_size; /* unit is bytes */
unsigned int fat_bits; /* size of a FAT entry */
unsigned int eff_fat_bits; /* # of used bits in a FAT entry */
unsigned long root_cluster; /* 0 for old-style root dir */
loff_t root_start;
unsigned int root_entries;
loff_t data_start;
unsigned int cluster_size;
unsigned long clusters;
loff_t fsinfo_start; /* 0 if not present */
long free_clusters;
loff_t backupboot_start; /* 0 if not present */
FAT_ENTRY *fat;
} DOS_FS;
#ifndef offsetof
#define offsetof(t,e) ((int)&(((t *)0)->e))
#endif
extern int interactive,list,verbose,test,write_immed;
extern int atari_format;
extern unsigned n_files;
extern void *mem_queue;
/* value to use as end-of-file marker */
#define FAT_EOF(fs) ((atari_format ? 0xfff : 0xff8) | FAT_EXTD(fs))
#define FAT_IS_EOF(fs,v) ((unsigned long)(v) >= (0xff8|FAT_EXTD(fs)))
/* value to mark bad clusters */
#define FAT_BAD(fs) (0xff7 | FAT_EXTD(fs))
/* range of values used for bad clusters */
#define FAT_MIN_BAD(fs) ((atari_format ? 0xff0 : 0xff7) | FAT_EXTD(fs))
#define FAT_MAX_BAD(fs) ((atari_format ? 0xff7 : 0xff7) | FAT_EXTD(fs))
#define FAT_IS_BAD(fs,v) ((v) >= FAT_MIN_BAD(fs) && (v) <= FAT_MAX_BAD(fs))
/* return -16 as a number with fs->fat_bits bits */
#define FAT_EXTD(fs) (((1 << fs->eff_fat_bits)-1) & ~0xf)
#endif
/* Local Variables: */
/* tab-width: 8 */
/* End: */

View file

@ -1,366 +1,366 @@
/* fat.c - Read/write access to the FAT */
/* Written 1993 by Werner Almesberger */
/* FAT32, VFAT, Atari format support, and various fixes additions May 1998
* by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <unistd.h>
#include "common.h"
#include "dosfsck.h"
#include "io.h"
#include "check.h"
#include "fat.h"
#pragma warning(disable: 4018)
static void get_fat(FAT_ENTRY *entry,void *fat,unsigned long cluster,DOS_FS *fs)
{
unsigned char *ptr;
switch(fs->fat_bits) {
case 12:
ptr = &((unsigned char *) fat)[cluster*3/2];
entry->value = 0xfff & (cluster & 1 ? (ptr[0] >> 4) | (ptr[1] << 4) :
(ptr[0] | ptr[1] << 8));
break;
case 16:
entry->value = CF_LE_W(((unsigned short *) fat)[cluster]);
break;
case 32:
/* According to M$, the high 4 bits of a FAT32 entry are reserved and
* are not part of the cluster number. So we cut them off. */
{
unsigned long e = CF_LE_L(((unsigned int *) fat)[cluster]);
entry->value = e & 0xfffffff;
entry->reserved = e >> 28;
}
break;
default:
die("Bad FAT entry size: %d bits.",fs->fat_bits);
}
entry->owner = NULL;
}
void read_fat(DOS_FS *fs)
{
int eff_size;
unsigned long i;
void *first,*second,*use;
int first_ok,second_ok;
eff_size = ((fs->clusters+2)*fs->fat_bits+7)/8;
// TMN: Must round up to disk-sector boundary. For now, assume 512-byte disk.
if (eff_size % 512) {
eff_size += 512 - (eff_size % 512);
}
first = alloc(eff_size);
fs_read(fs->fat_start,eff_size,first);
use = first;
if (fs->nfats > 1) {
second = alloc(eff_size);
fs_read(fs->fat_start+fs->fat_size,eff_size,second);
}
else
second = NULL;
if (second && memcmp(first,second,eff_size) != 0) {
FAT_ENTRY first_media, second_media;
get_fat(&first_media,first,0,fs);
get_fat(&second_media,second,0,fs);
first_ok = (first_media.value & FAT_EXTD(fs)) == FAT_EXTD(fs);
second_ok = (second_media.value & FAT_EXTD(fs)) == FAT_EXTD(fs);
if (first_ok && !second_ok) {
printf("FATs differ - using first FAT.\n");
fs_write(fs->fat_start+fs->fat_size,eff_size,use = first);
}
if (!first_ok && second_ok) {
printf("FATs differ - using second FAT.\n");
fs_write(fs->fat_start,eff_size,use = second);
}
if (first_ok && second_ok) {
if (interactive) {
printf("FATs differ but appear to be intact. Use which FAT ?\n"
"1) Use first FAT\n2) Use second FAT\n");
if (get_key("12","?") == '1')
fs_write(fs->fat_start+fs->fat_size,eff_size,use = first);
else fs_write(fs->fat_start,eff_size,use = second);
}
else {
printf("FATs differ but appear to be intact. Using first "
"FAT.\n");
fs_write(fs->fat_start+fs->fat_size,eff_size,use = first);
}
}
if (!first_ok && !second_ok) {
printf("Both FATs appear to be corrupt. Giving up.\n");
exit(1);
}
}
fs->fat = qalloc(&mem_queue,sizeof(FAT_ENTRY)*(fs->clusters+2));
for (i = 2; i < fs->clusters+2; i++) get_fat(&fs->fat[i],use,i,fs);
for (i = 2; i < fs->clusters+2; i++)
if (fs->fat[i].value >= fs->clusters+2 &&
(fs->fat[i].value < FAT_MIN_BAD(fs))) {
printf("Cluster %ld out of range (%ld > %ld). Setting to EOF.\n",
i-2,fs->fat[i].value,fs->clusters+2-1);
set_fat(fs,i,-1);
}
free(first);
if (second)
free(second);
}
void set_fat(DOS_FS *fs,unsigned long cluster,unsigned long new)
{
unsigned char data[4];
int size;
loff_t offs;
if ((long)new == -1)
new = FAT_EOF(fs);
else if ((long)new == -2)
new = FAT_BAD(fs);
switch( fs->fat_bits ) {
case 12:
offs = fs->fat_start+cluster*3/2;
if (cluster & 1) {
data[0] = ((new & 0xf) << 4) | (fs->fat[cluster-1].value >> 8);
data[1] = new >> 4;
}
else {
data[0] = new & 0xff;
data[1] = (new >> 8) | (cluster == fs->clusters-1 ? 0 :
(0xff & fs->fat[cluster+1].value) << 4);
}
size = 2;
break;
case 16:
offs = fs->fat_start+cluster*2;
*(unsigned short *) data = CT_LE_W(new);
size = 2;
break;
case 32:
offs = fs->fat_start+cluster*4;
/* According to M$, the high 4 bits of a FAT32 entry are reserved and
* are not part of the cluster number. So we never touch them. */
*(unsigned long *) data = CT_LE_L( (new & 0xfffffff) |
(fs->fat[cluster].reserved << 28) );
size = 4;
break;
default:
die("Bad FAT entry size: %d bits.",fs->fat_bits);
}
fs->fat[cluster].value = new;
fs_write(offs,size,&data);
fs_write(offs+fs->fat_size,size,&data);
}
int bad_cluster(DOS_FS *fs,unsigned long cluster)
{
return FAT_IS_BAD(fs,fs->fat[cluster].value);
}
unsigned long next_cluster(DOS_FS *fs,unsigned long cluster)
{
unsigned long value;
value = fs->fat[cluster].value;
if (FAT_IS_BAD(fs,value))
die("Internal error: next_cluster on bad cluster");
return FAT_IS_EOF(fs,value) ? -1 : value;
}
loff_t cluster_start(DOS_FS *fs,unsigned long cluster)
{
return fs->data_start+((loff_t)cluster-2)*fs->cluster_size;
}
void set_owner(DOS_FS *fs,unsigned long cluster,DOS_FILE *owner)
{
if (owner && fs->fat[cluster].owner)
die("Internal error: attempt to change file owner");
fs->fat[cluster].owner = owner;
}
DOS_FILE *get_owner(DOS_FS *fs,unsigned long cluster)
{
return fs->fat[cluster].owner;
}
void fix_bad(DOS_FS *fs)
{
unsigned long i;
if (verbose)
printf("Checking for bad clusters.\n");
for (i = 2; i < fs->clusters+2; i++)
if (!get_owner(fs,i) && !FAT_IS_BAD(fs,fs->fat[i].value))
if (!fs_test(cluster_start(fs,i),fs->cluster_size)) {
printf("Cluster %lu is unreadable.\n",i);
set_fat(fs,i,-2);
}
}
void reclaim_free(DOS_FS *fs)
{
int reclaimed;
unsigned long i;
if (verbose)
printf("Checking for unused clusters.\n");
reclaimed = 0;
for (i = 2; i < fs->clusters+2; i++)
if (!get_owner(fs,i) && fs->fat[i].value &&
!FAT_IS_BAD(fs,fs->fat[i].value)) {
set_fat(fs,i,0);
reclaimed++;
}
if (reclaimed)
printf("Reclaimed %d unused cluster%s (%d bytes).\n",reclaimed,
reclaimed == 1 ? "" : "s",reclaimed*fs->cluster_size);
}
static void tag_free(DOS_FS *fs,DOS_FILE *ptr)
{
DOS_FILE *owner;
int prev;
unsigned long i,walk;
for (i = 2; i < fs->clusters+2; i++)
if (fs->fat[i].value && !FAT_IS_BAD(fs,fs->fat[i].value) &&
!get_owner(fs,i) && !fs->fat[i].prev) {
prev = 0;
for (walk = i; walk > 0 && walk != -1;
walk = next_cluster(fs,walk)) {
if (!(owner = get_owner(fs,walk))) set_owner(fs,walk,ptr);
else if (owner != ptr)
die("Internal error: free chain collides with file");
else {
set_fat(fs,prev,-1);
break;
}
prev = walk;
}
}
}
void reclaim_file(DOS_FS *fs)
{
DOS_FILE dummy;
int reclaimed,files,changed;
unsigned long i,next,walk;
if (verbose)
printf("Reclaiming unconnected clusters.\n");
for (i = 2; i < fs->clusters+2; i++) fs->fat[i].prev = 0;
for (i = 2; i < fs->clusters+2; i++) {
next = fs->fat[i].value;
if (!get_owner(fs,i) && next && next < fs->clusters+2) {
if (get_owner(fs,next) || !fs->fat[next].value ||
FAT_IS_BAD(fs,fs->fat[next].value)) set_fat(fs,i,-1);
else fs->fat[next].prev++;
}
}
do {
tag_free(fs,&dummy);
changed = 0;
for (i = 2; i < fs->clusters+2; i++)
if (fs->fat[i].value && !FAT_IS_BAD(fs,fs->fat[i].value) &&
!get_owner(fs, i)) {
if (!fs->fat[fs->fat[i].value].prev--)
die("Internal error: prev going below zero");
set_fat(fs,i,-1);
changed = 1;
printf("Broke cycle at cluster %lu in free chain.\n",i);
break;
}
}
while (changed);
files = reclaimed = 0;
for (i = 2; i < fs->clusters+2; i++)
if (get_owner(fs,i) == &dummy && !fs->fat[i].prev) {
DIR_ENT de;
loff_t offset;
files++;
offset = alloc_rootdir_entry(fs,&de,"FSCK%04dREC");
de.start = CT_LE_W(i&0xffff);
if (fs->fat_bits == 32)
de.starthi = CT_LE_W(i>>16);
for (walk = i; walk > 0 && walk != -1;
walk = next_cluster(fs,walk)) {
de.size = CT_LE_L(CF_LE_L(de.size)+fs->cluster_size);
reclaimed++;
}
fs_write(offset,sizeof(DIR_ENT),&de);
}
if (reclaimed)
printf("Reclaimed %d unused cluster%s (%d bytes) in %d chain%s.\n",
reclaimed,reclaimed == 1 ? "" : "s",reclaimed*fs->cluster_size,files,
files == 1 ? "" : "s");
}
unsigned long update_free(DOS_FS *fs)
{
unsigned long i;
unsigned long free = 0;
int do_set = 0;
for (i = 2; i < fs->clusters+2; i++)
if (!get_owner(fs,i) && !FAT_IS_BAD(fs,fs->fat[i].value))
++free;
if (!fs->fsinfo_start)
return free;
if (verbose)
printf("Checking free cluster summary.\n");
if (fs->free_clusters >= 0) {
if (free != fs->free_clusters) {
printf( "Free cluster summary wrong (%ld vs. really %ld)\n",
fs->free_clusters,free);
if (interactive)
printf( "1) Correct\n2) Don't correct\n" );
else printf( " Auto-correcting.\n" );
if (!interactive || get_key("12","?") == '1')
do_set = 1;
}
}
else {
printf( "Free cluster summary uninitialized (should be %ld)\n", free );
if (interactive)
printf( "1) Set it\n2) Leave it uninitialized\n" );
else printf( " Auto-setting.\n" );
if (!interactive || get_key("12","?") == '1')
do_set = 1;
}
if (do_set) {
fs->free_clusters = free;
free = CT_LE_L(free);
fs_write(fs->fsinfo_start+offsetof(struct info_sector,free_clusters),
sizeof(free),&free);
}
return free;
}
/* Local Variables: */
/* tab-width: 8 */
/* End: */
/* fat.c - Read/write access to the FAT */
/* Written 1993 by Werner Almesberger */
/* FAT32, VFAT, Atari format support, and various fixes additions May 1998
* by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//#include <unistd.h>
#include "common.h"
#include "dosfsck.h"
#include "io.h"
#include "check.h"
#include "fat.h"
#pragma warning(disable: 4018)
static void get_fat(FAT_ENTRY *entry,void *fat,unsigned long cluster,DOS_FS *fs)
{
unsigned char *ptr;
switch(fs->fat_bits) {
case 12:
ptr = &((unsigned char *) fat)[cluster*3/2];
entry->value = 0xfff & (cluster & 1 ? (ptr[0] >> 4) | (ptr[1] << 4) :
(ptr[0] | ptr[1] << 8));
break;
case 16:
entry->value = CF_LE_W(((unsigned short *) fat)[cluster]);
break;
case 32:
/* According to M$, the high 4 bits of a FAT32 entry are reserved and
* are not part of the cluster number. So we cut them off. */
{
unsigned long e = CF_LE_L(((unsigned int *) fat)[cluster]);
entry->value = e & 0xfffffff;
entry->reserved = e >> 28;
}
break;
default:
die("Bad FAT entry size: %d bits.",fs->fat_bits);
}
entry->owner = NULL;
}
void read_fat(DOS_FS *fs)
{
int eff_size;
unsigned long i;
void *first,*second,*use;
int first_ok,second_ok;
eff_size = ((fs->clusters+2)*fs->fat_bits+7)/8;
// TMN: Must round up to disk-sector boundary. For now, assume 512-byte disk.
if (eff_size % 512) {
eff_size += 512 - (eff_size % 512);
}
first = alloc(eff_size);
fs_read(fs->fat_start,eff_size,first);
use = first;
if (fs->nfats > 1) {
second = alloc(eff_size);
fs_read(fs->fat_start+fs->fat_size,eff_size,second);
}
else
second = NULL;
if (second && memcmp(first,second,eff_size) != 0) {
FAT_ENTRY first_media, second_media;
get_fat(&first_media,first,0,fs);
get_fat(&second_media,second,0,fs);
first_ok = (first_media.value & FAT_EXTD(fs)) == FAT_EXTD(fs);
second_ok = (second_media.value & FAT_EXTD(fs)) == FAT_EXTD(fs);
if (first_ok && !second_ok) {
printf("FATs differ - using first FAT.\n");
fs_write(fs->fat_start+fs->fat_size,eff_size,use = first);
}
if (!first_ok && second_ok) {
printf("FATs differ - using second FAT.\n");
fs_write(fs->fat_start,eff_size,use = second);
}
if (first_ok && second_ok) {
if (interactive) {
printf("FATs differ but appear to be intact. Use which FAT ?\n"
"1) Use first FAT\n2) Use second FAT\n");
if (get_key("12","?") == '1')
fs_write(fs->fat_start+fs->fat_size,eff_size,use = first);
else fs_write(fs->fat_start,eff_size,use = second);
}
else {
printf("FATs differ but appear to be intact. Using first "
"FAT.\n");
fs_write(fs->fat_start+fs->fat_size,eff_size,use = first);
}
}
if (!first_ok && !second_ok) {
printf("Both FATs appear to be corrupt. Giving up.\n");
exit(1);
}
}
fs->fat = qalloc(&mem_queue,sizeof(FAT_ENTRY)*(fs->clusters+2));
for (i = 2; i < fs->clusters+2; i++) get_fat(&fs->fat[i],use,i,fs);
for (i = 2; i < fs->clusters+2; i++)
if (fs->fat[i].value >= fs->clusters+2 &&
(fs->fat[i].value < FAT_MIN_BAD(fs))) {
printf("Cluster %ld out of range (%ld > %ld). Setting to EOF.\n",
i-2,fs->fat[i].value,fs->clusters+2-1);
set_fat(fs,i,-1);
}
free(first);
if (second)
free(second);
}
void set_fat(DOS_FS *fs,unsigned long cluster,unsigned long new)
{
unsigned char data[4];
int size;
loff_t offs;
if ((long)new == -1)
new = FAT_EOF(fs);
else if ((long)new == -2)
new = FAT_BAD(fs);
switch( fs->fat_bits ) {
case 12:
offs = fs->fat_start+cluster*3/2;
if (cluster & 1) {
data[0] = ((new & 0xf) << 4) | (fs->fat[cluster-1].value >> 8);
data[1] = new >> 4;
}
else {
data[0] = new & 0xff;
data[1] = (new >> 8) | (cluster == fs->clusters-1 ? 0 :
(0xff & fs->fat[cluster+1].value) << 4);
}
size = 2;
break;
case 16:
offs = fs->fat_start+cluster*2;
*(unsigned short *) data = CT_LE_W(new);
size = 2;
break;
case 32:
offs = fs->fat_start+cluster*4;
/* According to M$, the high 4 bits of a FAT32 entry are reserved and
* are not part of the cluster number. So we never touch them. */
*(unsigned long *) data = CT_LE_L( (new & 0xfffffff) |
(fs->fat[cluster].reserved << 28) );
size = 4;
break;
default:
die("Bad FAT entry size: %d bits.",fs->fat_bits);
}
fs->fat[cluster].value = new;
fs_write(offs,size,&data);
fs_write(offs+fs->fat_size,size,&data);
}
int bad_cluster(DOS_FS *fs,unsigned long cluster)
{
return FAT_IS_BAD(fs,fs->fat[cluster].value);
}
unsigned long next_cluster(DOS_FS *fs,unsigned long cluster)
{
unsigned long value;
value = fs->fat[cluster].value;
if (FAT_IS_BAD(fs,value))
die("Internal error: next_cluster on bad cluster");
return FAT_IS_EOF(fs,value) ? -1 : value;
}
loff_t cluster_start(DOS_FS *fs,unsigned long cluster)
{
return fs->data_start+((loff_t)cluster-2)*fs->cluster_size;
}
void set_owner(DOS_FS *fs,unsigned long cluster,DOS_FILE *owner)
{
if (owner && fs->fat[cluster].owner)
die("Internal error: attempt to change file owner");
fs->fat[cluster].owner = owner;
}
DOS_FILE *get_owner(DOS_FS *fs,unsigned long cluster)
{
return fs->fat[cluster].owner;
}
void fix_bad(DOS_FS *fs)
{
unsigned long i;
if (verbose)
printf("Checking for bad clusters.\n");
for (i = 2; i < fs->clusters+2; i++)
if (!get_owner(fs,i) && !FAT_IS_BAD(fs,fs->fat[i].value))
if (!fs_test(cluster_start(fs,i),fs->cluster_size)) {
printf("Cluster %lu is unreadable.\n",i);
set_fat(fs,i,-2);
}
}
void reclaim_free(DOS_FS *fs)
{
int reclaimed;
unsigned long i;
if (verbose)
printf("Checking for unused clusters.\n");
reclaimed = 0;
for (i = 2; i < fs->clusters+2; i++)
if (!get_owner(fs,i) && fs->fat[i].value &&
!FAT_IS_BAD(fs,fs->fat[i].value)) {
set_fat(fs,i,0);
reclaimed++;
}
if (reclaimed)
printf("Reclaimed %d unused cluster%s (%d bytes).\n",reclaimed,
reclaimed == 1 ? "" : "s",reclaimed*fs->cluster_size);
}
static void tag_free(DOS_FS *fs,DOS_FILE *ptr)
{
DOS_FILE *owner;
int prev;
unsigned long i,walk;
for (i = 2; i < fs->clusters+2; i++)
if (fs->fat[i].value && !FAT_IS_BAD(fs,fs->fat[i].value) &&
!get_owner(fs,i) && !fs->fat[i].prev) {
prev = 0;
for (walk = i; walk > 0 && walk != -1;
walk = next_cluster(fs,walk)) {
if (!(owner = get_owner(fs,walk))) set_owner(fs,walk,ptr);
else if (owner != ptr)
die("Internal error: free chain collides with file");
else {
set_fat(fs,prev,-1);
break;
}
prev = walk;
}
}
}
void reclaim_file(DOS_FS *fs)
{
DOS_FILE dummy;
int reclaimed,files,changed;
unsigned long i,next,walk;
if (verbose)
printf("Reclaiming unconnected clusters.\n");
for (i = 2; i < fs->clusters+2; i++) fs->fat[i].prev = 0;
for (i = 2; i < fs->clusters+2; i++) {
next = fs->fat[i].value;
if (!get_owner(fs,i) && next && next < fs->clusters+2) {
if (get_owner(fs,next) || !fs->fat[next].value ||
FAT_IS_BAD(fs,fs->fat[next].value)) set_fat(fs,i,-1);
else fs->fat[next].prev++;
}
}
do {
tag_free(fs,&dummy);
changed = 0;
for (i = 2; i < fs->clusters+2; i++)
if (fs->fat[i].value && !FAT_IS_BAD(fs,fs->fat[i].value) &&
!get_owner(fs, i)) {
if (!fs->fat[fs->fat[i].value].prev--)
die("Internal error: prev going below zero");
set_fat(fs,i,-1);
changed = 1;
printf("Broke cycle at cluster %lu in free chain.\n",i);
break;
}
}
while (changed);
files = reclaimed = 0;
for (i = 2; i < fs->clusters+2; i++)
if (get_owner(fs,i) == &dummy && !fs->fat[i].prev) {
DIR_ENT de;
loff_t offset;
files++;
offset = alloc_rootdir_entry(fs,&de,"FSCK%04dREC");
de.start = CT_LE_W(i&0xffff);
if (fs->fat_bits == 32)
de.starthi = CT_LE_W(i>>16);
for (walk = i; walk > 0 && walk != -1;
walk = next_cluster(fs,walk)) {
de.size = CT_LE_L(CF_LE_L(de.size)+fs->cluster_size);
reclaimed++;
}
fs_write(offset,sizeof(DIR_ENT),&de);
}
if (reclaimed)
printf("Reclaimed %d unused cluster%s (%d bytes) in %d chain%s.\n",
reclaimed,reclaimed == 1 ? "" : "s",reclaimed*fs->cluster_size,files,
files == 1 ? "" : "s");
}
unsigned long update_free(DOS_FS *fs)
{
unsigned long i;
unsigned long free = 0;
int do_set = 0;
for (i = 2; i < fs->clusters+2; i++)
if (!get_owner(fs,i) && !FAT_IS_BAD(fs,fs->fat[i].value))
++free;
if (!fs->fsinfo_start)
return free;
if (verbose)
printf("Checking free cluster summary.\n");
if (fs->free_clusters >= 0) {
if (free != fs->free_clusters) {
printf( "Free cluster summary wrong (%ld vs. really %ld)\n",
fs->free_clusters,free);
if (interactive)
printf( "1) Correct\n2) Don't correct\n" );
else printf( " Auto-correcting.\n" );
if (!interactive || get_key("12","?") == '1')
do_set = 1;
}
}
else {
printf( "Free cluster summary uninitialized (should be %ld)\n", free );
if (interactive)
printf( "1) Set it\n2) Leave it uninitialized\n" );
else printf( " Auto-setting.\n" );
if (!interactive || get_key("12","?") == '1')
do_set = 1;
}
if (do_set) {
fs->free_clusters = free;
free = CT_LE_L(free);
fs_write(fs->fsinfo_start+offsetof(struct info_sector,free_clusters),
sizeof(free),&free);
}
return free;
}
/* Local Variables: */
/* tab-width: 8 */
/* End: */

View file

@ -1,64 +1,64 @@
/* fat.h - Read/write access to the FAT */
/* Written 1993 by Werner Almesberger */
#ifndef _FAT_H
#define _FAT_H
void read_fat(DOS_FS *fs);
/* Loads the FAT of the file system described by FS. Initializes the FAT,
replaces broken FATs and rejects invalid cluster entries. */
void set_fat(DOS_FS *fs,unsigned long cluster,unsigned long new);
/* Changes the value of the CLUSTERth cluster of the FAT of FS to NEW. Special
values of NEW are -1 (EOF, 0xff8 or 0xfff8) and -2 (bad sector, 0xff7 or
0xfff7) */
int bad_cluster(DOS_FS *fs,unsigned long cluster);
/* Returns a non-zero integer if the CLUSTERth cluster is marked as bad or zero
otherwise. */
unsigned long next_cluster(DOS_FS *fs,unsigned long cluster);
/* Returns the number of the cluster following CLUSTER, or -1 if this is the
last cluster of the respective cluster chain. CLUSTER must not be a bad
cluster. */
loff_t cluster_start(DOS_FS *fs,unsigned long cluster);
/* Returns the byte offset of CLUSTER, relative to the respective device. */
void set_owner(DOS_FS *fs,unsigned long cluster,DOS_FILE *owner);
/* Sets the owner pointer of the respective cluster to OWNER. If OWNER was NULL
before, it can be set to NULL or any non-NULL value. Otherwise, only NULL is
accepted as the new value. */
DOS_FILE *get_owner(DOS_FS *fs,unsigned long cluster);
/* Returns the owner of the repective cluster or NULL if the cluster has no
owner. */
void fix_bad(DOS_FS *fs);
/* Scans the disk for currently unused bad clusters and marks them as bad. */
void reclaim_free(DOS_FS *fs);
/* Marks all allocated, but unused clusters as free. */
void reclaim_file(DOS_FS *fs);
/* Scans the FAT for chains of allocated, but unused clusters and creates files
for them in the root directory. Also tries to fix all inconsistencies (e.g.
loops, shared clusters, etc.) in the process. */
unsigned long update_free(DOS_FS *fs);
/* Updates free cluster count in FSINFO sector. */
#endif
/* fat.h - Read/write access to the FAT */
/* Written 1993 by Werner Almesberger */
#ifndef _FAT_H
#define _FAT_H
void read_fat(DOS_FS *fs);
/* Loads the FAT of the file system described by FS. Initializes the FAT,
replaces broken FATs and rejects invalid cluster entries. */
void set_fat(DOS_FS *fs,unsigned long cluster,unsigned long new);
/* Changes the value of the CLUSTERth cluster of the FAT of FS to NEW. Special
values of NEW are -1 (EOF, 0xff8 or 0xfff8) and -2 (bad sector, 0xff7 or
0xfff7) */
int bad_cluster(DOS_FS *fs,unsigned long cluster);
/* Returns a non-zero integer if the CLUSTERth cluster is marked as bad or zero
otherwise. */
unsigned long next_cluster(DOS_FS *fs,unsigned long cluster);
/* Returns the number of the cluster following CLUSTER, or -1 if this is the
last cluster of the respective cluster chain. CLUSTER must not be a bad
cluster. */
loff_t cluster_start(DOS_FS *fs,unsigned long cluster);
/* Returns the byte offset of CLUSTER, relative to the respective device. */
void set_owner(DOS_FS *fs,unsigned long cluster,DOS_FILE *owner);
/* Sets the owner pointer of the respective cluster to OWNER. If OWNER was NULL
before, it can be set to NULL or any non-NULL value. Otherwise, only NULL is
accepted as the new value. */
DOS_FILE *get_owner(DOS_FS *fs,unsigned long cluster);
/* Returns the owner of the repective cluster or NULL if the cluster has no
owner. */
void fix_bad(DOS_FS *fs);
/* Scans the disk for currently unused bad clusters and marks them as bad. */
void reclaim_free(DOS_FS *fs);
/* Marks all allocated, but unused clusters as free. */
void reclaim_file(DOS_FS *fs);
/* Scans the FAT for chains of allocated, but unused clusters and creates files
for them in the root directory. Also tries to fix all inconsistencies (e.g.
loops, shared clusters, etc.) in the process. */
unsigned long update_free(DOS_FS *fs);
/* Updates free cluster count in FSINFO sector. */
#endif

View file

@ -1,251 +1,251 @@
/* file.c - Additional file attributes */
/* Written 1993 by Werner Almesberger */
/* FAT32, VFAT, Atari format support, and various fixes additions May 1998
* by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
//#include <unistd.h>
#define _LINUX_STAT_H /* hack to avoid inclusion of <linux/stat.h> */
#define _LINUX_STRING_H_ /* hack to avoid inclusion of <linux/string.h>*/
#define _LINUX_FS_H /* hack to avoid inclusion of <linux/fs.h> */
//#include <linux/version.h>
//#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
//# define __KERNEL__
//# include <asm/types.h>
//# undef __KERNEL__
//#endif
#include "dosfsck.h"
#include "msdos_fs.h"
#include "common.h"
#include "file.h"
FDSC *fp_root = NULL;
static void put_char(char **p,unsigned char c)
{
if ((c >= ' ' && c < 0x7f) || c >= 0xa0) *(*p)++ = c;
else {
*(*p)++ = '\\';
*(*p)++ = '0'+(c >> 6);
*(*p)++ = '0'+((c >> 3) & 7);
*(*p)++ = '0'+(c & 7);
}
}
char *file_name(unsigned char *fixed)
{
static char path[MSDOS_NAME*4+2];
char *p;
int i,j;
p = path;
for (i = j = 0; i < 8; i++)
if (fixed[i] != ' ') {
while (j++ < i) *p++ = ' ';
put_char(&p,fixed[i]);
}
if (strncmp(fixed+8," ",3)) {
*p++ = '.';
for (i = j = 0; i < 3; i++)
if (fixed[i+8] != ' ') {
while (j++ < i) *p++ = ' ';
put_char(&p,fixed[i+8]);
}
}
*p = 0;
return path;
}
int file_cvt(unsigned char *name,unsigned char *fixed)
{
unsigned char c;
int size,ext,cnt;
size = 8;
ext = 0;
while (*name) {
c = *name;
if (c < ' ' || c > 0x7e || strchr("*?<>|\"/",c)) {
printf("Invalid character in name. Use \\ooo for special "
"characters.\n");
return 0;
}
if (c == '.') {
if (ext) {
printf("Duplicate dots in name.\n");
return 0;
}
while (size--) *fixed++ = ' ';
size = 3;
ext = 1;
name++;
continue;
}
if (c == '\\') {
c = 0;
for (cnt = 3; cnt; cnt--) {
if (*name < '0' || *name > '7') {
printf("Invalid octal character.\n");
return 0;
}
c = c*8+*name++-'0';
}
if (cnt < 4) {
printf("Expected three octal digits.\n");
return 0;
}
name += 3;
}
if (islower(c)) c = toupper(c);
if (size) {
*fixed++ = c;
size--;
}
name++;
}
if (*name || size == 8) return 0;
if (!ext) {
while (size--) *fixed++ = ' ';
size = 3;
}
while (size--) *fixed++ = ' ';
return 1;
}
void file_add(char *path,FD_TYPE type)
{
FDSC **current,*walk;
char name[MSDOS_NAME];
char *here;
current = &fp_root;
if (*path != '/') die("%s: Absolute path required.",path);
path++;
while (1) {
if ((here = strchr(path,'/'))) *here = 0;
if (!file_cvt(path,name)) exit(2);
for (walk = *current; walk; walk = walk->next)
if (!here && (!strncmp(name,walk->name,MSDOS_NAME) || (type ==
fdt_undelete && !strncmp(name+1,walk->name+1,MSDOS_NAME-1))))
die("Ambiguous name: \"%s\"",path);
else if (here && !strncmp(name,walk->name,MSDOS_NAME)) break;
if (!walk) {
walk = alloc(sizeof(FDSC));
strncpy(walk->name,name,MSDOS_NAME);
walk->type = here ? fdt_none : type;
walk->first = NULL;
walk->next = *current;
*current = walk;
}
current = &walk->first;
if (!here) break;
*here = '/';
path = here+1;
}
}
FDSC **file_cd(FDSC **curr,char *fixed)
{
FDSC **walk;
if (!curr || !*curr) return NULL;
for (walk = curr; *walk; walk = &(*walk)->next)
if (!strncmp((*walk)->name,fixed,MSDOS_NAME) && (*walk)->first)
return &(*walk)->first;
return NULL;
}
static FDSC **file_find(FDSC **dir,char *fixed)
{
if (!dir || !*dir) return NULL;
if (*(unsigned char *) fixed == DELETED_FLAG) {
while (*dir) {
if (!strncmp((*dir)->name+1,fixed+1,MSDOS_NAME-1) && !(*dir)->first)
return dir;
dir = &(*dir)->next;
}
return NULL;
}
while (*dir) {
if (!strncmp((*dir)->name,fixed,MSDOS_NAME) && !(*dir)->first)
return dir;
dir = &(*dir)->next;
}
return NULL;
}
FD_TYPE file_type(FDSC **curr,char *fixed)
{
FDSC **this;
if ((this = file_find(curr,fixed))) return (*this)->type;
return fdt_none;
}
void file_modify(FDSC **curr,char *fixed)
{
FDSC **this,*next;
if (!(this = file_find(curr,fixed)))
die("Internal error: file_find failed");
switch ((*this)->type) {
case fdt_drop:
printf("Dropping %s\n",file_name(fixed));
*(unsigned char *) fixed = DELETED_FLAG;
break;
case fdt_undelete:
*fixed = *(*this)->name;
printf("Undeleting %s\n",file_name(fixed));
break;
default:
die("Internal error: file_modify");
}
next = (*this)->next;
free(*this);
*this = next;
}
static void report_unused(FDSC *this)
{
FDSC *next;
while (this) {
next = this->next;
if (this->first) report_unused(this->first);
else if (this->type != fdt_none)
printf("Warning: did not %s file %s\n",this->type == fdt_drop ?
"drop" : "undelete",file_name(this->name));
free(this);
this = next;
}
}
void file_unused(void)
{
report_unused(fp_root);
}
/* Local Variables: */
/* tab-width: 8 */
/* End: */
/* file.c - Additional file attributes */
/* Written 1993 by Werner Almesberger */
/* FAT32, VFAT, Atari format support, and various fixes additions May 1998
* by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
//#include <unistd.h>
#define _LINUX_STAT_H /* hack to avoid inclusion of <linux/stat.h> */
#define _LINUX_STRING_H_ /* hack to avoid inclusion of <linux/string.h>*/
#define _LINUX_FS_H /* hack to avoid inclusion of <linux/fs.h> */
//#include <linux/version.h>
//#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
//# define __KERNEL__
//# include <asm/types.h>
//# undef __KERNEL__
//#endif
#include "dosfsck.h"
#include "msdos_fs.h"
#include "common.h"
#include "file.h"
FDSC *fp_root = NULL;
static void put_char(char **p,unsigned char c)
{
if ((c >= ' ' && c < 0x7f) || c >= 0xa0) *(*p)++ = c;
else {
*(*p)++ = '\\';
*(*p)++ = '0'+(c >> 6);
*(*p)++ = '0'+((c >> 3) & 7);
*(*p)++ = '0'+(c & 7);
}
}
char *file_name(unsigned char *fixed)
{
static char path[MSDOS_NAME*4+2];
char *p;
int i,j;
p = path;
for (i = j = 0; i < 8; i++)
if (fixed[i] != ' ') {
while (j++ < i) *p++ = ' ';
put_char(&p,fixed[i]);
}
if (strncmp(fixed+8," ",3)) {
*p++ = '.';
for (i = j = 0; i < 3; i++)
if (fixed[i+8] != ' ') {
while (j++ < i) *p++ = ' ';
put_char(&p,fixed[i+8]);
}
}
*p = 0;
return path;
}
int file_cvt(unsigned char *name,unsigned char *fixed)
{
unsigned char c;
int size,ext,cnt;
size = 8;
ext = 0;
while (*name) {
c = *name;
if (c < ' ' || c > 0x7e || strchr("*?<>|\"/",c)) {
printf("Invalid character in name. Use \\ooo for special "
"characters.\n");
return 0;
}
if (c == '.') {
if (ext) {
printf("Duplicate dots in name.\n");
return 0;
}
while (size--) *fixed++ = ' ';
size = 3;
ext = 1;
name++;
continue;
}
if (c == '\\') {
c = 0;
for (cnt = 3; cnt; cnt--) {
if (*name < '0' || *name > '7') {
printf("Invalid octal character.\n");
return 0;
}
c = c*8+*name++-'0';
}
if (cnt < 4) {
printf("Expected three octal digits.\n");
return 0;
}
name += 3;
}
if (islower(c)) c = toupper(c);
if (size) {
*fixed++ = c;
size--;
}
name++;
}
if (*name || size == 8) return 0;
if (!ext) {
while (size--) *fixed++ = ' ';
size = 3;
}
while (size--) *fixed++ = ' ';
return 1;
}
void file_add(char *path,FD_TYPE type)
{
FDSC **current,*walk;
char name[MSDOS_NAME];
char *here;
current = &fp_root;
if (*path != '/') die("%s: Absolute path required.",path);
path++;
while (1) {
if ((here = strchr(path,'/'))) *here = 0;
if (!file_cvt(path,name)) exit(2);
for (walk = *current; walk; walk = walk->next)
if (!here && (!strncmp(name,walk->name,MSDOS_NAME) || (type ==
fdt_undelete && !strncmp(name+1,walk->name+1,MSDOS_NAME-1))))
die("Ambiguous name: \"%s\"",path);
else if (here && !strncmp(name,walk->name,MSDOS_NAME)) break;
if (!walk) {
walk = alloc(sizeof(FDSC));
strncpy(walk->name,name,MSDOS_NAME);
walk->type = here ? fdt_none : type;
walk->first = NULL;
walk->next = *current;
*current = walk;
}
current = &walk->first;
if (!here) break;
*here = '/';
path = here+1;
}
}
FDSC **file_cd(FDSC **curr,char *fixed)
{
FDSC **walk;
if (!curr || !*curr) return NULL;
for (walk = curr; *walk; walk = &(*walk)->next)
if (!strncmp((*walk)->name,fixed,MSDOS_NAME) && (*walk)->first)
return &(*walk)->first;
return NULL;
}
static FDSC **file_find(FDSC **dir,char *fixed)
{
if (!dir || !*dir) return NULL;
if (*(unsigned char *) fixed == DELETED_FLAG) {
while (*dir) {
if (!strncmp((*dir)->name+1,fixed+1,MSDOS_NAME-1) && !(*dir)->first)
return dir;
dir = &(*dir)->next;
}
return NULL;
}
while (*dir) {
if (!strncmp((*dir)->name,fixed,MSDOS_NAME) && !(*dir)->first)
return dir;
dir = &(*dir)->next;
}
return NULL;
}
FD_TYPE file_type(FDSC **curr,char *fixed)
{
FDSC **this;
if ((this = file_find(curr,fixed))) return (*this)->type;
return fdt_none;
}
void file_modify(FDSC **curr,char *fixed)
{
FDSC **this,*next;
if (!(this = file_find(curr,fixed)))
die("Internal error: file_find failed");
switch ((*this)->type) {
case fdt_drop:
printf("Dropping %s\n",file_name(fixed));
*(unsigned char *) fixed = DELETED_FLAG;
break;
case fdt_undelete:
*fixed = *(*this)->name;
printf("Undeleting %s\n",file_name(fixed));
break;
default:
die("Internal error: file_modify");
}
next = (*this)->next;
free(*this);
*this = next;
}
static void report_unused(FDSC *this)
{
FDSC *next;
while (this) {
next = this->next;
if (this->first) report_unused(this->first);
else if (this->type != fdt_none)
printf("Warning: did not %s file %s\n",this->type == fdt_drop ?
"drop" : "undelete",file_name(this->name));
free(this);
this = next;
}
}
void file_unused(void)
{
report_unused(fp_root);
}
/* Local Variables: */
/* tab-width: 8 */
/* End: */

View file

@ -1,55 +1,55 @@
/* file.h - Additional file attributes */
/* Written 1993 by Werner Almesberger */
#ifndef _FILE_H
#define _FILE_H
typedef enum { fdt_none,fdt_drop,fdt_undelete } FD_TYPE;
typedef struct _fptr {
char name[MSDOS_NAME];
FD_TYPE type;
struct _fptr *first; /* first entry */
struct _fptr *next; /* next file in directory */
} FDSC;
extern FDSC *fp_root;
char *file_name(unsigned char *fixed);
/* Returns a pointer to a pretty-printed representation of a fixed MS-DOS file
name. */
int file_cvt(unsigned char *name,unsigned char *fixed);
/* Converts a pretty-printed file name to the fixed MS-DOS format. Returns a
non-zero integer on success, zero on failure. */
void file_add(char *path,FD_TYPE type);
/* Define special attributes for a path. TYPE can be either FDT_DROP or
FDT_UNDELETE. */
FDSC **file_cd(FDSC **curr,char *fixed);
/* Returns a pointer to the directory descriptor of the subdirectory FIXED of
CURR, or NULL if no such subdirectory exists. */
FD_TYPE file_type(FDSC **curr,char *fixed);
/* Returns the attribute of the file FIXED in directory CURR or FDT_NONE if no
such file exists or if CURR is NULL. */
void file_modify(FDSC **curr,char *fixed);
/* Performs the necessary operation on the entry of CURR that is named FIXED. */
void file_unused(void);
/* Displays warnings for all unused file attributes. */
#endif
/* file.h - Additional file attributes */
/* Written 1993 by Werner Almesberger */
#ifndef _FILE_H
#define _FILE_H
typedef enum { fdt_none,fdt_drop,fdt_undelete } FD_TYPE;
typedef struct _fptr {
char name[MSDOS_NAME];
FD_TYPE type;
struct _fptr *first; /* first entry */
struct _fptr *next; /* next file in directory */
} FDSC;
extern FDSC *fp_root;
char *file_name(unsigned char *fixed);
/* Returns a pointer to a pretty-printed representation of a fixed MS-DOS file
name. */
int file_cvt(unsigned char *name,unsigned char *fixed);
/* Converts a pretty-printed file name to the fixed MS-DOS format. Returns a
non-zero integer on success, zero on failure. */
void file_add(char *path,FD_TYPE type);
/* Define special attributes for a path. TYPE can be either FDT_DROP or
FDT_UNDELETE. */
FDSC **file_cd(FDSC **curr,char *fixed);
/* Returns a pointer to the directory descriptor of the subdirectory FIXED of
CURR, or NULL if no such subdirectory exists. */
FD_TYPE file_type(FDSC **curr,char *fixed);
/* Returns the attribute of the file FIXED in directory CURR or FDT_NONE if no
such file exists or if CURR is NULL. */
void file_modify(FDSC **curr,char *fixed);
/* Performs the necessary operation on the entry of CURR that is named FIXED. */
void file_unused(void);
/* Displays warnings for all unused file attributes. */
#endif

View file

@ -1,423 +1,423 @@
/* io.c - Virtual disk input/output */
/* Written 1993 by Werner Almesberger */
/*
* Thu Feb 26 01:15:36 CET 1998: Martin Schulze <joey@infodrom.north.de>
* Fixed nasty bug that caused every file with a name like
* xxxxxxxx.xxx to be treated as bad name that needed to be fixed.
*/
/* FAT32, VFAT, Atari format support, and various fixes additions May 1998
* by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
//#include <unistd.h>
#include <sys/stat.h>
//#include <sys/ioctl.h>
#include <errno.h>
#include <fcntl.h>
#include <assert.h>
//#include <linux/fd.h>
#ifdef _WIN32
#define _WIN32_WINNT 0x0400
#include <windows.h>
#include <winioctl.h>
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#define __BYTE_ORDER __LITTLE_ENDIAN
#define inline
#define __attribute__(x)
#define BLOCK_SIZE 512
#endif
#include "dosfsck.h"
#include "common.h"
#include "io.h"
typedef struct _change {
void *data;
loff_t pos;
int size;
struct _change *next;
} CHANGE;
static CHANGE *changes,*last;
static int fd,did_change = 0;
unsigned device_no;
static int WIN32open(const char *path, int oflag, ...);
#define open WIN32open
static int WIN32close(int fd);
#define close WIN32close
static int WIN32read(int fd, void *buf, unsigned int len);
#define read WIN32read
static int WIN32write(int fd, void *buf, unsigned int len);
#define write WIN32write
static loff_t WIN32llseek(int fd, loff_t offset, int whence);
#ifdef llseek
#undef llseek
#endif
#define llseek WIN32llseek
static int is_device = 0;
void fs_open(char *path,int rw)
{
#ifdef _WIN32
static char dev_buf[] = "\\\\.\\X:";
#else
struct stat stbuf;
#endif
if (path[1] == ':' && path[2] == '\0') {
dev_buf[4] = path[0];
path = dev_buf;
// is_device = 1;
}
if ((fd = open(path,rw ? O_RDWR : O_RDONLY)) < 0)
pdie("open %s",path);
changes = last = NULL;
did_change = 0;
#if 0
if (fstat(fd,&stbuf) < 0)
pdie("fstat %s",path);
device_no = S_ISBLK(stbuf.st_mode) ? (stbuf.st_rdev >> 8) & 0xff : 0;
#endif
}
void fs_read(loff_t pos,int size,void *data)
{
CHANGE *walk;
int got;
#if 1 // TMN
const size_t readsize_aligned = (size % 512) ? (size + (512 - (size % 512))) : size; // TMN:
const loff_t seekpos_aligned = pos - (pos % 512); // TMN:
const size_t seek_delta = (size_t)(pos - seekpos_aligned); // TMN:
const size_t readsize = (size_t)(pos - seekpos_aligned) + readsize_aligned; // TMN:
char* tmpBuf = malloc(readsize_aligned); // TMN:
#ifdef _MSC_VER
if (llseek(fd,seekpos_aligned,0) != seekpos_aligned) pdie("Seek to %I64d",pos);
if ((got = read(fd,tmpBuf,readsize_aligned)) < 0) pdie("Read %d bytes at %I64dd",size,pos);
#else
if (llseek(fd,seekpos_aligned,0) != seekpos_aligned) pdie("Seek to %lld",pos);
if ((got = read(fd,tmpBuf,readsize_aligned)) < 0) pdie("Read %d bytes at %lld",size,pos);
#endif
assert(got >= size);
got = size;
assert(seek_delta + size <= readsize);
memcpy(data, tmpBuf+seek_delta, size);
free(tmpBuf);
#else // TMN:
if (llseek(fd,pos,0) != pos) pdie("Seek to %lld",pos);
if ((got = read(fd,data,size)) < 0) pdie("Read %d bytes at %lld",size,pos);
#endif // TMN:
if (got != size) die("Got %d bytes instead of %d at %lld",got,size,pos);
for (walk = changes; walk; walk = walk->next) {
if (walk->pos < pos+size && walk->pos+walk->size > pos) {
if (walk->pos < pos)
memcpy(data,(char *) walk->data+pos-walk->pos,min((size_t)size,
(size_t)(walk->size-pos+walk->pos)));
else memcpy((char *) data+walk->pos-pos,walk->data,min((size_t)walk->size,
(size_t)(size+pos-walk->pos)));
}
}
}
int fs_test(loff_t pos,int size)
{
void *scratch;
int okay;
#if 1 // TMN
const size_t readsize_aligned = (size % 512) ? (size + (512 - (size % 512))) : size; // TMN:
const loff_t seekpos_aligned = pos - (pos % 512); // TMN:
const size_t seek_delta = (size_t)(pos - seekpos_aligned); // TMN:
const size_t readsize = (size_t)(pos - seekpos_aligned) + readsize_aligned; // TMN:
scratch = alloc(readsize_aligned);
if (llseek(fd,seekpos_aligned,0) != seekpos_aligned) pdie("Seek to %lld",pos);
okay = read(fd,scratch,readsize_aligned) == (int)readsize_aligned;
free(scratch);
#else // TMN:
if (llseek(fd,pos,0) != pos) pdie("Seek to %lld",pos);
scratch = alloc(size);
okay = read(fd,scratch,size) == size;
free(scratch);
#endif // TMN:
return okay;
}
void fs_write(loff_t pos,int size,void *data)
{
CHANGE *new;
int did;
/* io.c - Virtual disk input/output */
/* Written 1993 by Werner Almesberger */
/*
* Thu Feb 26 01:15:36 CET 1998: Martin Schulze <joey@infodrom.north.de>
* Fixed nasty bug that caused every file with a name like
* xxxxxxxx.xxx to be treated as bad name that needed to be fixed.
*/
/* FAT32, VFAT, Atari format support, and various fixes additions May 1998
* by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
//#include <unistd.h>
#include <sys/stat.h>
//#include <sys/ioctl.h>
#include <errno.h>
#include <fcntl.h>
#include <assert.h>
//#include <linux/fd.h>
#ifdef _WIN32
#define _WIN32_WINNT 0x0400
#include <windows.h>
#include <winioctl.h>
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#define __BYTE_ORDER __LITTLE_ENDIAN
#define inline
#define __attribute__(x)
#define BLOCK_SIZE 512
#endif
#include "dosfsck.h"
#include "common.h"
#include "io.h"
typedef struct _change {
void *data;
loff_t pos;
int size;
struct _change *next;
} CHANGE;
static CHANGE *changes,*last;
static int fd,did_change = 0;
unsigned device_no;
static int WIN32open(const char *path, int oflag, ...);
#define open WIN32open
static int WIN32close(int fd);
#define close WIN32close
static int WIN32read(int fd, void *buf, unsigned int len);
#define read WIN32read
static int WIN32write(int fd, void *buf, unsigned int len);
#define write WIN32write
static loff_t WIN32llseek(int fd, loff_t offset, int whence);
#ifdef llseek
#undef llseek
#endif
#define llseek WIN32llseek
static int is_device = 0;
void fs_open(char *path,int rw)
{
#ifdef _WIN32
static char dev_buf[] = "\\\\.\\X:";
#else
struct stat stbuf;
#endif
if (path[1] == ':' && path[2] == '\0') {
dev_buf[4] = path[0];
path = dev_buf;
// is_device = 1;
}
if ((fd = open(path,rw ? O_RDWR : O_RDONLY)) < 0)
pdie("open %s",path);
changes = last = NULL;
did_change = 0;
#if 0
if (fstat(fd,&stbuf) < 0)
pdie("fstat %s",path);
device_no = S_ISBLK(stbuf.st_mode) ? (stbuf.st_rdev >> 8) & 0xff : 0;
#endif
}
void fs_read(loff_t pos,int size,void *data)
{
CHANGE *walk;
int got;
#if 1 // TMN
const size_t readsize_aligned = (size % 512) ? (size + (512 - (size % 512))) : size; // TMN:
const loff_t seekpos_aligned = pos - (pos % 512); // TMN:
const size_t seek_delta = (size_t)(pos - seekpos_aligned); // TMN:
const size_t readsize = (size_t)(pos - seekpos_aligned) + readsize_aligned; // TMN:
char* tmpBuf = malloc(readsize_aligned); // TMN:
#ifdef _MSC_VER
if (llseek(fd,seekpos_aligned,0) != seekpos_aligned) pdie("Seek to %I64d",pos);
if ((got = read(fd,tmpBuf,readsize_aligned)) < 0) pdie("Read %d bytes at %I64dd",size,pos);
#else
if (llseek(fd,seekpos_aligned,0) != seekpos_aligned) pdie("Seek to %lld",pos);
if ((got = read(fd,tmpBuf,readsize_aligned)) < 0) pdie("Read %d bytes at %lld",size,pos);
#endif
assert(got >= size);
got = size;
assert(seek_delta + size <= readsize);
memcpy(data, tmpBuf+seek_delta, size);
free(tmpBuf);
#else // TMN:
if (llseek(fd,pos,0) != pos) pdie("Seek to %lld",pos);
if ((got = read(fd,data,size)) < 0) pdie("Read %d bytes at %lld",size,pos);
#endif // TMN:
if (got != size) die("Got %d bytes instead of %d at %lld",got,size,pos);
for (walk = changes; walk; walk = walk->next) {
if (walk->pos < pos+size && walk->pos+walk->size > pos) {
if (walk->pos < pos)
memcpy(data,(char *) walk->data+pos-walk->pos,min((size_t)size,
(size_t)(walk->size-pos+walk->pos)));
else memcpy((char *) data+walk->pos-pos,walk->data,min((size_t)walk->size,
(size_t)(size+pos-walk->pos)));
}
}
}
int fs_test(loff_t pos,int size)
{
void *scratch;
int okay;
#if 1 // TMN
const size_t readsize_aligned = (size % 512) ? (size + (512 - (size % 512))) : size; // TMN:
const loff_t seekpos_aligned = pos - (pos % 512); // TMN:
const size_t seek_delta = (size_t)(pos - seekpos_aligned); // TMN:
const size_t readsize = (size_t)(pos - seekpos_aligned) + readsize_aligned; // TMN:
scratch = alloc(readsize_aligned);
if (llseek(fd,seekpos_aligned,0) != seekpos_aligned) pdie("Seek to %lld",pos);
okay = read(fd,scratch,readsize_aligned) == (int)readsize_aligned;
free(scratch);
#else // TMN:
if (llseek(fd,pos,0) != pos) pdie("Seek to %lld",pos);
scratch = alloc(size);
okay = read(fd,scratch,size) == size;
free(scratch);
#endif // TMN:
return okay;
}
void fs_write(loff_t pos,int size,void *data)
{
CHANGE *new;
int did;
#if 1 //SAE
void *scratch;
const size_t readsize_aligned = (size % 512) ? (size + (512 - (size % 512))) : size;
const loff_t seekpos_aligned = pos - (pos % 512);
const size_t seek_delta = (size_t)(pos - seekpos_aligned);
const size_t readsize = (size_t)(pos - seekpos_aligned) + readsize_aligned;
const size_t readsize_aligned = (size % 512) ? (size + (512 - (size % 512))) : size;
const loff_t seekpos_aligned = pos - (pos % 512);
const size_t seek_delta = (size_t)(pos - seekpos_aligned);
const size_t readsize = (size_t)(pos - seekpos_aligned) + readsize_aligned;
scratch = alloc(readsize_aligned);
if (write_immed) {
did_change = 1;
if (llseek(fd,seekpos_aligned,0) != seekpos_aligned) pdie("Seek to %lld",pos);
if (write_immed) {
did_change = 1;
if (llseek(fd,seekpos_aligned,0) != seekpos_aligned) pdie("Seek to %lld",pos);
if ((did = write(fd,data,readsize_aligned)) == (int)readsize_aligned)
{
free(scratch);
return;
}
if (did < 0) pdie("Write %d bytes at %lld",size,pos);
die("Wrote %d bytes instead of %d at %lld",did,size,pos);
}
new = alloc(sizeof(CHANGE));
new->pos = pos;
memcpy(new->data = alloc(new->size = size),data,size);
new->next = NULL;
if (last) last->next = new;
else changes = new;
}
if (did < 0) pdie("Write %d bytes at %lld",size,pos);
die("Wrote %d bytes instead of %d at %lld",did,size,pos);
}
new = alloc(sizeof(CHANGE));
new->pos = pos;
memcpy(new->data = alloc(new->size = size),data,size);
new->next = NULL;
if (last) last->next = new;
else changes = new;
last = new;
#else //SAE
if (write_immed) {
did_change = 1;
if (llseek(fd,pos,0) != pos) pdie("Seek to %lld",pos);
if ((did = write(fd,data,size)) == size) return;
if (did < 0) pdie("Write %d bytes at %lld",size,pos);
die("Wrote %d bytes instead of %d at %lld",did,size,pos);
}
new = alloc(sizeof(CHANGE));
new->pos = pos;
memcpy(new->data = alloc(new->size = size),data,size);
new->next = NULL;
if (last) last->next = new;
else changes = new;
#else //SAE
if (write_immed) {
did_change = 1;
if (llseek(fd,pos,0) != pos) pdie("Seek to %lld",pos);
if ((did = write(fd,data,size)) == size) return;
if (did < 0) pdie("Write %d bytes at %lld",size,pos);
die("Wrote %d bytes instead of %d at %lld",did,size,pos);
}
new = alloc(sizeof(CHANGE));
new->pos = pos;
memcpy(new->data = alloc(new->size = size),data,size);
new->next = NULL;
if (last) last->next = new;
else changes = new;
last = new;
#endif //SAE
}
static void fs_flush(void)
{
CHANGE *this;
int size;
while (changes) {
this = changes;
changes = changes->next;
if (llseek(fd,this->pos,0) != this->pos)
fprintf(stderr,"Seek to %lld failed: %s\n Did not write %d bytes.\n",
(__int64)this->pos,strerror(errno),this->size);
else if ((size = write(fd,this->data,this->size)) < 0)
fprintf(stderr,"Writing %d bytes at %lld failed: %s\n",this->size,
(__int64)this->pos,strerror(errno));
else if (size != this->size)
fprintf(stderr,"Wrote %d bytes instead of %d bytes at %lld."
"\n",size,this->size,(__int64)this->pos);
free(this->data);
free(this);
}
}
int fs_close(int write)
{
CHANGE *next;
int changed;
changed = !!changes;
if (write) fs_flush();
else while (changes) {
next = changes->next;
free(changes->data);
free(changes);
changes = next;
}
if (close(fd) < 0) pdie("closing file system");
return changed || did_change;
}
int fs_changed(void)
{
return !!changes || did_change;
}
/* Local Variables: */
/* tab-width: 8 */
/* End: */
#define O_SHORT_LIVED _O_SHORT_LIVED
//#define O_ACCMODE 3
#define O_NONE 3
#define O_BACKUP 0x10000
#define O_SHARED 0x20000
static int WIN32open(const char *path, int oflag, ...)
{
HANDLE fh;
DWORD desiredAccess;
DWORD shareMode;
DWORD creationDisposition;
DWORD flagsAttributes = FILE_ATTRIBUTE_NORMAL;
SECURITY_ATTRIBUTES securityAttributes;
va_list ap;
int pmode;
int trunc = FALSE;
securityAttributes.nLength = sizeof(securityAttributes);
securityAttributes.lpSecurityDescriptor = NULL;
securityAttributes.bInheritHandle = oflag & O_NOINHERIT ? FALSE : TRUE;
switch (oflag & O_ACCMODE) {
case O_RDONLY:
desiredAccess = GENERIC_READ;
// shareMode = FILE_SHARE_READ;
shareMode = FILE_SHARE_READ|FILE_SHARE_WRITE; // TMN:
break;
case O_WRONLY:
desiredAccess = GENERIC_WRITE;
shareMode = 0;
break;
case O_RDWR:
desiredAccess = GENERIC_READ|GENERIC_WRITE;
shareMode = 0;
break;
case O_NONE:
desiredAccess = 0;
shareMode = FILE_SHARE_READ|FILE_SHARE_WRITE;
}
if (oflag & O_APPEND) {
desiredAccess |= FILE_APPEND_DATA|SYNCHRONIZE;
shareMode = FILE_SHARE_READ|FILE_SHARE_WRITE;
}
if (oflag & O_SHARED)
shareMode |= FILE_SHARE_READ|FILE_SHARE_WRITE;
switch (oflag & (O_CREAT|O_EXCL|O_TRUNC)) {
case 0:
case O_EXCL:
creationDisposition = OPEN_EXISTING;
break;
case O_CREAT:
creationDisposition = OPEN_ALWAYS;
break;
case O_CREAT|O_EXCL:
case O_CREAT|O_TRUNC|O_EXCL:
creationDisposition = CREATE_NEW;
break;
case O_TRUNC:
case O_TRUNC|O_EXCL:
creationDisposition = TRUNCATE_EXISTING;
break;
case O_CREAT|O_TRUNC:
creationDisposition = OPEN_ALWAYS;
trunc = TRUE;
break;
}
if (oflag & O_CREAT) {
va_start(ap, oflag);
pmode = va_arg(ap, int);
va_end(ap);
if ((pmode & 0222) == 0)
flagsAttributes |= FILE_ATTRIBUTE_READONLY;
}
if (oflag & O_TEMPORARY) {
flagsAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
desiredAccess |= DELETE;
}
if (oflag & O_SHORT_LIVED)
flagsAttributes |= FILE_ATTRIBUTE_TEMPORARY;
if (oflag & O_SEQUENTIAL)
flagsAttributes |= FILE_FLAG_SEQUENTIAL_SCAN;
else if (oflag & O_RANDOM)
flagsAttributes |= FILE_FLAG_RANDOM_ACCESS;
if (oflag & O_BACKUP)
flagsAttributes |= FILE_FLAG_BACKUP_SEMANTICS;
if ((fh = CreateFile(path, desiredAccess, shareMode, &securityAttributes,
creationDisposition, flagsAttributes, NULL)) == INVALID_HANDLE_VALUE) {
errno = GetLastError();
return -1;
}
if (trunc) {
if (!SetEndOfFile(fh)) {
errno = GetLastError();
CloseHandle(fh);
DeleteFile(path);
return -1;
}
}
return (int)fh;
}
static int WIN32close(int fd)
{
if (!CloseHandle((HANDLE)fd)) {
errno = GetLastError();
return -1;
}
return 0;
}
static int WIN32read(int fd, void *buf, unsigned int len)
{
DWORD actualLen;
if (!ReadFile((HANDLE)fd, buf, (DWORD)len, &actualLen, NULL)) {
errno = GetLastError();
if (errno == ERROR_BROKEN_PIPE)
return 0;
else
return -1;
}
return (int)actualLen;
}
static int WIN32write(int fd, void *buf, unsigned int len)
{
DWORD actualLen;
if (!WriteFile((HANDLE)fd, buf, (DWORD)len, &actualLen, NULL)) {
errno = GetLastError();
return -1;
}
return (int)actualLen;
}
static loff_t WIN32llseek(int fd, loff_t offset, int whence)
{
long lo, hi;
DWORD err;
lo = (long)(offset & 0xffffffff);
hi = (long)(offset >> 32);
lo = SetFilePointer((HANDLE)fd, lo, &hi, whence);
if (lo == 0xFFFFFFFF && (err = GetLastError()) != NO_ERROR) {
errno = err;
return -1;
}
return ((loff_t)hi << 32) | (__u32)lo;
}
int fsctl(int fd, int code)
{
DWORD ret;
if (!DeviceIoControl((HANDLE)fd, code, NULL, 0, NULL, 0, &ret, NULL)) {
errno = GetLastError();
return -1;
}
return 0;
}
#endif //SAE
}
static void fs_flush(void)
{
CHANGE *this;
int size;
while (changes) {
this = changes;
changes = changes->next;
if (llseek(fd,this->pos,0) != this->pos)
fprintf(stderr,"Seek to %lld failed: %s\n Did not write %d bytes.\n",
(__int64)this->pos,strerror(errno),this->size);
else if ((size = write(fd,this->data,this->size)) < 0)
fprintf(stderr,"Writing %d bytes at %lld failed: %s\n",this->size,
(__int64)this->pos,strerror(errno));
else if (size != this->size)
fprintf(stderr,"Wrote %d bytes instead of %d bytes at %lld."
"\n",size,this->size,(__int64)this->pos);
free(this->data);
free(this);
}
}
int fs_close(int write)
{
CHANGE *next;
int changed;
changed = !!changes;
if (write) fs_flush();
else while (changes) {
next = changes->next;
free(changes->data);
free(changes);
changes = next;
}
if (close(fd) < 0) pdie("closing file system");
return changed || did_change;
}
int fs_changed(void)
{
return !!changes || did_change;
}
/* Local Variables: */
/* tab-width: 8 */
/* End: */
#define O_SHORT_LIVED _O_SHORT_LIVED
//#define O_ACCMODE 3
#define O_NONE 3
#define O_BACKUP 0x10000
#define O_SHARED 0x20000
static int WIN32open(const char *path, int oflag, ...)
{
HANDLE fh;
DWORD desiredAccess;
DWORD shareMode;
DWORD creationDisposition;
DWORD flagsAttributes = FILE_ATTRIBUTE_NORMAL;
SECURITY_ATTRIBUTES securityAttributes;
va_list ap;
int pmode;
int trunc = FALSE;
securityAttributes.nLength = sizeof(securityAttributes);
securityAttributes.lpSecurityDescriptor = NULL;
securityAttributes.bInheritHandle = oflag & O_NOINHERIT ? FALSE : TRUE;
switch (oflag & O_ACCMODE) {
case O_RDONLY:
desiredAccess = GENERIC_READ;
// shareMode = FILE_SHARE_READ;
shareMode = FILE_SHARE_READ|FILE_SHARE_WRITE; // TMN:
break;
case O_WRONLY:
desiredAccess = GENERIC_WRITE;
shareMode = 0;
break;
case O_RDWR:
desiredAccess = GENERIC_READ|GENERIC_WRITE;
shareMode = 0;
break;
case O_NONE:
desiredAccess = 0;
shareMode = FILE_SHARE_READ|FILE_SHARE_WRITE;
}
if (oflag & O_APPEND) {
desiredAccess |= FILE_APPEND_DATA|SYNCHRONIZE;
shareMode = FILE_SHARE_READ|FILE_SHARE_WRITE;
}
if (oflag & O_SHARED)
shareMode |= FILE_SHARE_READ|FILE_SHARE_WRITE;
switch (oflag & (O_CREAT|O_EXCL|O_TRUNC)) {
case 0:
case O_EXCL:
creationDisposition = OPEN_EXISTING;
break;
case O_CREAT:
creationDisposition = OPEN_ALWAYS;
break;
case O_CREAT|O_EXCL:
case O_CREAT|O_TRUNC|O_EXCL:
creationDisposition = CREATE_NEW;
break;
case O_TRUNC:
case O_TRUNC|O_EXCL:
creationDisposition = TRUNCATE_EXISTING;
break;
case O_CREAT|O_TRUNC:
creationDisposition = OPEN_ALWAYS;
trunc = TRUE;
break;
}
if (oflag & O_CREAT) {
va_start(ap, oflag);
pmode = va_arg(ap, int);
va_end(ap);
if ((pmode & 0222) == 0)
flagsAttributes |= FILE_ATTRIBUTE_READONLY;
}
if (oflag & O_TEMPORARY) {
flagsAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
desiredAccess |= DELETE;
}
if (oflag & O_SHORT_LIVED)
flagsAttributes |= FILE_ATTRIBUTE_TEMPORARY;
if (oflag & O_SEQUENTIAL)
flagsAttributes |= FILE_FLAG_SEQUENTIAL_SCAN;
else if (oflag & O_RANDOM)
flagsAttributes |= FILE_FLAG_RANDOM_ACCESS;
if (oflag & O_BACKUP)
flagsAttributes |= FILE_FLAG_BACKUP_SEMANTICS;
if ((fh = CreateFile(path, desiredAccess, shareMode, &securityAttributes,
creationDisposition, flagsAttributes, NULL)) == INVALID_HANDLE_VALUE) {
errno = GetLastError();
return -1;
}
if (trunc) {
if (!SetEndOfFile(fh)) {
errno = GetLastError();
CloseHandle(fh);
DeleteFile(path);
return -1;
}
}
return (int)fh;
}
static int WIN32close(int fd)
{
if (!CloseHandle((HANDLE)fd)) {
errno = GetLastError();
return -1;
}
return 0;
}
static int WIN32read(int fd, void *buf, unsigned int len)
{
DWORD actualLen;
if (!ReadFile((HANDLE)fd, buf, (DWORD)len, &actualLen, NULL)) {
errno = GetLastError();
if (errno == ERROR_BROKEN_PIPE)
return 0;
else
return -1;
}
return (int)actualLen;
}
static int WIN32write(int fd, void *buf, unsigned int len)
{
DWORD actualLen;
if (!WriteFile((HANDLE)fd, buf, (DWORD)len, &actualLen, NULL)) {
errno = GetLastError();
return -1;
}
return (int)actualLen;
}
static loff_t WIN32llseek(int fd, loff_t offset, int whence)
{
long lo, hi;
DWORD err;
lo = (long)(offset & 0xffffffff);
hi = (long)(offset >> 32);
lo = SetFilePointer((HANDLE)fd, lo, &hi, whence);
if (lo == 0xFFFFFFFF && (err = GetLastError()) != NO_ERROR) {
errno = err;
return -1;
}
return ((loff_t)hi << 32) | (__u32)lo;
}
int fsctl(int fd, int code)
{
DWORD ret;
if (!DeviceIoControl((HANDLE)fd, code, NULL, 0, NULL, 0, &ret, NULL)) {
errno = GetLastError();
return -1;
}
return 0;
}

View file

@ -1,54 +1,54 @@
/* io.h - Virtual disk input/output */
/* Written 1993 by Werner Almesberger */
/* FAT32, VFAT, Atari format support, and various fixes additions May 1998
* by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */
#ifndef _IO_H
#define _IO_H
//#include <sys/types.h> /* for loff_t */
#include "dosfsck.h"
/* In earlier versions, an own llseek() was used, but glibc lseek() is
* sufficient (or even better :) for 64 bit offsets in the meantime */
#define llseek lseek
void fs_open(char *path,int rw);
/* Opens the file system PATH. If RW is zero, the file system is opened
read-only, otherwise, it is opened read-write. */
void fs_read(loff_t pos,int size,void *data);
/* Reads SIZE bytes starting at POS into DATA. Performs all applicable
changes. */
int fs_test(loff_t pos,int size);
/* Returns a non-zero integer if SIZE bytes starting at POS can be read without
errors. Otherwise, it returns zero. */
void fs_write(loff_t pos,int size,void *data);
/* If write_immed is non-zero, SIZE bytes are written from DATA to the disk,
starting at POS. If write_immed is zero, the change is added to a list in
memory. */
int fs_close(int write);
/* Closes the file system, performs all pending changes if WRITE is non-zero
and removes the list of changes. Returns a non-zero integer if the file
system has been changed since the last fs_open, zero otherwise. */
int fs_changed(void);
/* Determines whether the file system has changed. See fs_close. */
extern unsigned device_no;
/* Major number of device (0 if file) and size (in 512 byte sectors) */
#endif
/* io.h - Virtual disk input/output */
/* Written 1993 by Werner Almesberger */
/* FAT32, VFAT, Atari format support, and various fixes additions May 1998
* by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */
#ifndef _IO_H
#define _IO_H
//#include <sys/types.h> /* for loff_t */
#include "dosfsck.h"
/* In earlier versions, an own llseek() was used, but glibc lseek() is
* sufficient (or even better :) for 64 bit offsets in the meantime */
#define llseek lseek
void fs_open(char *path,int rw);
/* Opens the file system PATH. If RW is zero, the file system is opened
read-only, otherwise, it is opened read-write. */
void fs_read(loff_t pos,int size,void *data);
/* Reads SIZE bytes starting at POS into DATA. Performs all applicable
changes. */
int fs_test(loff_t pos,int size);
/* Returns a non-zero integer if SIZE bytes starting at POS can be read without
errors. Otherwise, it returns zero. */
void fs_write(loff_t pos,int size,void *data);
/* If write_immed is non-zero, SIZE bytes are written from DATA to the disk,
starting at POS. If write_immed is zero, the change is added to a list in
memory. */
int fs_close(int write);
/* Closes the file system, performs all pending changes if WRITE is non-zero
and removes the list of changes. Returns a non-zero integer if the file
system has been changed since the last fs_open, zero otherwise. */
int fs_changed(void);
/* Determines whether the file system has changed. See fs_close. */
extern unsigned device_no;
/* Major number of device (0 if file) and size (in 512 byte sectors) */
#endif

View file

@ -1,480 +1,480 @@
/* lfn.c - Functions for handling VFAT long filenames */
/* Written 1998 by Roman Hodek */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <time.h>
#include "common.h"
#include "io.h"
#include "dosfsck.h"
#include "lfn.h"
#include "file.h"
typedef struct {
__u8 id; /* sequence number for slot */
__u8 name0_4[10]; /* first 5 characters in name */
__u8 attr; /* attribute byte */
__u8 reserved; /* always 0 */
__u8 alias_checksum; /* checksum for 8.3 alias */
__u8 name5_10[12]; /* 6 more characters in name */
__u16 start; /* starting cluster number, 0 in long slots */
__u8 name11_12[4]; /* last 2 characters in name */
} LFN_ENT;
#define LFN_ID_START 0x40
#define LFN_ID_SLOTMASK 0x1f
#define CHARS_PER_LFN 13
/* These modul-global vars represent the state of the LFN parser */
unsigned char *lfn_unicode = NULL;
unsigned char lfn_checksum;
int lfn_slot = -1;
loff_t *lfn_offsets = NULL;
int lfn_parts = 0;
static unsigned char fat_uni2esc[64] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z', '+', '-'
};
/* This defines which unicode chars are directly convertable to ISO-8859-1 */
#define UNICODE_CONVERTABLE(cl,ch) (ch == 0 && (cl < 0x80 || cl >= 0xa0))
/* for maxlen param */
#define UNTIL_0 INT_MAX
static void copy_lfn_part( char *dst, LFN_ENT *lfn );
static char *cnv_unicode( const unsigned char *uni, int maxlen, int use_q );
/* Convert name part in 'lfn' from unicode to ASCII */
static __inline char* CNV_THIS_PART(LFN_ENT *lfn)
{ \
char __part_uni[CHARS_PER_LFN*2];
copy_lfn_part( __part_uni, lfn );
cnv_unicode( __part_uni, CHARS_PER_LFN, 0 );
}
/* Convert name parts collected so far (from previous slots) from unicode to
* ASCII */
#define CNV_PARTS_SO_FAR() \
(cnv_unicode( lfn_unicode+(lfn_slot*CHARS_PER_LFN*2), \
lfn_parts*CHARS_PER_LFN, 0 ))
/* This function converts an unicode string to a normal ASCII string, assuming
* ISO-8859-1 charset. Characters not in 8859-1 are converted to the same
* escape notation as used by the kernel, i.e. the uuencode-like ":xxx" */
static char *cnv_unicode( const unsigned char *uni, int maxlen, int use_q )
{
const unsigned char *up;
unsigned char *out, *cp;
int len, val;
for( len = 0, up = uni; (up-uni)/2 < maxlen && (up[0] || up[1]); up += 2 ){
if (UNICODE_CONVERTABLE(up[0],up[1]))
++len;
else
len += 4;
}
cp = out = use_q ? qalloc( &mem_queue, len+1 ) : alloc( len+1 );
for( up = uni; (up-uni)/2 < maxlen && (up[0] || up[1]); up += 2 ) {
if (UNICODE_CONVERTABLE(up[0],up[1]))
*cp++ = up[0];
else {
/* here the same escape notation is used as in the Linux kernel */
*cp++ = ':';
val = (up[1] << 8) + up[0];
cp[2] = fat_uni2esc[val & 0x3f];
val >>= 6;
cp[1] = fat_uni2esc[val & 0x3f];
val >>= 6;
cp[0] = fat_uni2esc[val & 0x3f];
cp += 3;
}
}
*cp = 0;
return( out );
}
static void copy_lfn_part( char *dst, LFN_ENT *lfn )
{
memcpy( dst, lfn->name0_4, 10 );
memcpy( dst+10, lfn->name5_10, 12 );
memcpy( dst+22, lfn->name11_12, 4 );
}
static void clear_lfn_slots( int start, int end )
{
int i;
LFN_ENT empty;
/* New dir entry is zeroed except first byte, which is set to 0xe5.
* This is to avoid that some FAT-reading OSes (not Linux! ;) stop reading
* a directory at the first zero entry...
*/
memset( &empty, 0, sizeof(empty) );
empty.id = DELETED_FLAG;
for( i = start; i <= end; ++i ) {
fs_write( lfn_offsets[i], sizeof(LFN_ENT), &empty );
}
}
void lfn_reset( void )
{
if (lfn_unicode)
free( lfn_unicode );
lfn_unicode = NULL;
if (lfn_offsets)
free( lfn_offsets );
lfn_offsets = NULL;
lfn_slot = -1;
}
/* This function is only called with de->attr == VFAT_LN_ATTR. It stores part
* of the long name. */
void lfn_add_slot( DIR_ENT *de, loff_t dir_offset )
{
LFN_ENT *lfn = (LFN_ENT *)de;
unsigned offset;
if (de->attr != VFAT_LN_ATTR)
die("lfn_add_slot called with non-LFN directory entry");
if (lfn->id & LFN_ID_START) {
if (lfn_slot != -1) {
int can_clear = 0;
/* There is already a LFN "in progess", so it is an error that a
* new start entry is here. */
/* Causes: 1) if slot# == expected: start bit set mysteriously, 2)
* old LFN overwritten by new one */
/* Fixes: 1) delete previous LFN 2) if slot# == expected and
* checksum ok: clear start bit */
/* XXX: Should delay that until next LFN known (then can better
* display the name) */
printf( "A new long file name starts within an old one.\n" );
if ((lfn->id & LFN_ID_SLOTMASK) == lfn_slot &&
lfn->alias_checksum == lfn_checksum) {
char *part1 = CNV_THIS_PART(lfn);
char *part2 = CNV_PARTS_SO_FAR();
printf( " It could be that the LFN start bit is wrong here\n"
" if \"%s\" seems to match \"%s\".\n", part1, part2 );
free( part1 );
free( part2 );
can_clear = 1;
}
if (interactive) {
printf( "1: Delete previous LFN\n2: Leave it as it is.\n" );
if (can_clear)
printf( "3: Clear start bit and concatenate LFNs\n" );
}
else printf( " Not auto-correcting this.\n" );
if (interactive) {
switch( get_key( can_clear ? "123" : "12", "?" )) {
case '1':
clear_lfn_slots( 0, lfn_parts-1 );
lfn_reset();
break;
case '2':
break;
case '3':
lfn->id &= ~LFN_ID_START;
fs_write( dir_offset+offsetof(LFN_ENT,id),
sizeof(lfn->id), &lfn->id );
break;
}
}
}
lfn_slot = lfn->id & LFN_ID_SLOTMASK;
lfn_checksum = lfn->alias_checksum;
lfn_unicode = alloc( (lfn_slot*CHARS_PER_LFN+1)*2 );
lfn_offsets = alloc( lfn_slot*sizeof(loff_t) );
lfn_parts = 0;
}
else if (lfn_slot == -1) {
/* No LFN in progress, but slot found; start bit missing */
/* Causes: 1) start bit got lost, 2) Previous slot with start bit got
* lost */
/* Fixes: 1) delete LFN, 2) set start bit */
char *part = CNV_THIS_PART(lfn);
printf( "Long filename fragment \"%s\" found outside a LFN "
"sequence.\n (Maybe the start bit is missing on the "
"last fragment)\n", part );
if (interactive) {
printf( "1: Delete fragment\n2: Leave it as it is.\n"
"3: Set start bit\n" );
}
else printf( " Not auto-correcting this.\n" );
if (interactive) {
switch( get_key( "123", "?" )) {
case '1':
if (!lfn_offsets)
lfn_offsets = alloc( sizeof(loff_t) );
lfn_offsets[0] = dir_offset;
clear_lfn_slots( 0, 0 );
lfn_reset();
return;
case '2':
lfn_reset();
return;
case '3':
lfn->id |= LFN_ID_START;
fs_write( dir_offset+offsetof(LFN_ENT,id),
sizeof(lfn->id), &lfn->id );
lfn_slot = lfn->id & LFN_ID_SLOTMASK;
lfn_checksum = lfn->alias_checksum;
lfn_unicode = alloc( (lfn_slot*CHARS_PER_LFN+1)*2 );
lfn_offsets = alloc( lfn_slot*sizeof(loff_t) );
lfn_parts = 0;
break;
}
}
}
else if ((lfn->id & LFN_ID_SLOTMASK) != lfn_slot) {
/* wrong sequence number */
/* Causes: 1) seq-no destroyed */
/* Fixes: 1) delete LFN, 2) fix number (maybe only if following parts
* are ok?, maybe only if checksum is ok?) (Attention: space
* for name was allocated before!) */
int can_fix = 0;
printf( "Unexpected long filename sequence number "
"(%d vs. expected %d).\n",
(lfn->id & LFN_ID_SLOTMASK), lfn_slot );
if (lfn->alias_checksum == lfn_checksum) {
char *part1 = CNV_THIS_PART(lfn);
char *part2 = CNV_PARTS_SO_FAR();
printf( " It could be that just the number is wrong\n"
" if \"%s\" seems to match \"%s\".\n", part1, part2 );
free( part1 );
free( part2 );
can_fix = 1;
}
if (interactive) {
printf( "1: Delete LFN\n2: Leave it as it is (and ignore LFN so far)\n" );
if (can_fix)
printf( "3: Correct sequence number\n" );
}
else printf( " Not auto-correcting this.\n" );
if (interactive) {
switch( get_key( can_fix ? "123" : "12", "?" )) {
case '1':
lfn_offsets[lfn_parts++] = dir_offset;
clear_lfn_slots( 0, lfn_parts-1 );
lfn_reset();
return;
case '2':
lfn_reset();
return;
case '3':
lfn->id = (lfn->id & ~LFN_ID_SLOTMASK) | lfn_slot;
fs_write( dir_offset+offsetof(LFN_ENT,id),
sizeof(lfn->id), &lfn->id );
break;
}
}
}
if (lfn->alias_checksum != lfn_checksum) {
/* checksum mismatch */
/* Causes: 1) checksum field here destroyed */
/* Fixes: 1) delete LFN, 2) fix checksum */
printf( "Checksum in long filename part wrong "
"(%02x vs. expected %02x).\n",
lfn->alias_checksum, lfn_checksum );
if (interactive) {
printf( "1: Delete LFN\n2: Leave it as it is.\n"
"3: Correct checksum\n" );
}
else printf( " Not auto-correcting this.\n" );
if (interactive) {
switch( get_key( "123", "?" )) {
case '1':
lfn_offsets[lfn_parts++] = dir_offset;
clear_lfn_slots( 0, lfn_parts-1 );
lfn_reset();
return;
case '2':
break;
case '3':
lfn->alias_checksum = lfn_checksum;
fs_write( dir_offset+offsetof(LFN_ENT,alias_checksum),
sizeof(lfn->alias_checksum), &lfn->alias_checksum );
break;
}
}
}
if (lfn_slot != -1) {
lfn_slot--;
offset = lfn_slot * CHARS_PER_LFN*2;
copy_lfn_part( lfn_unicode+offset, lfn );
if (lfn->id & LFN_ID_START)
lfn_unicode[offset+26] = lfn_unicode[offset+27] = 0;
lfn_offsets[lfn_parts++] = dir_offset;
}
if (lfn->reserved != 0) {
printf( "Reserved field in VFAT long filename slot is not 0 "
"(but 0x%02x).\n", lfn->reserved );
if (interactive)
printf( "1: Fix.\n2: Leave it.\n" );
else printf( "Auto-setting to 0.\n" );
if (!interactive || get_key("12","?") == '1') {
lfn->reserved = 0;
fs_write( dir_offset+offsetof(LFN_ENT,reserved),
sizeof(lfn->reserved), &lfn->reserved );
}
}
if (lfn->start != CT_LE_W(0)) {
printf( "Start cluster field in VFAT long filename slot is not 0 "
"(but 0x%04x).\n", lfn->start );
if (interactive)
printf( "1: Fix.\n2: Leave it.\n" );
else printf( "Auto-setting to 0.\n" );
if (!interactive || get_key("12","?") == '1') {
lfn->start = CT_LE_W(0);
fs_write( dir_offset+offsetof(LFN_ENT,start),
sizeof(lfn->start),&lfn->start );
}
}
}
/* This function is always called when de->attr != VFAT_LN_ATTR is found, to
* retrieve the previously constructed LFN. */
char *lfn_get( DIR_ENT *de )
{
char *lfn;
__u8 sum;
int i;
if (de->attr == VFAT_LN_ATTR)
die("lfn_get called with LFN directory entry");
#if 0
if (de->lcase)
printf( "lcase=%02x\n",de->lcase );
#endif
if (lfn_slot == -1)
/* no long name for this file */
return NULL;
if (lfn_slot != 0) {
/* The long name isn't finished yet. */
/* Causes: 1) LFN slot overwritten by non-VFAT aware tool */
/* Fixes: 1) delete LFN 2) move overwriting entry to somewhere else
* and let user enter missing part of LFN (hard to do :-()
* 3) renumber entries and truncate name */
char *long_name = CNV_PARTS_SO_FAR();
char *short_name = file_name(de->name);
printf( "Unfinished long file name \"%s\".\n"
" (Start may have been overwritten by %s)\n",
long_name, short_name );
free( long_name );
if (interactive) {
printf( "1: Delete LFN\n2: Leave it as it is.\n"
"3: Fix numbering (truncates long name and attaches "
"it to short name %s)\n", short_name );
}
else printf( " Not auto-correcting this.\n" );
if (interactive) {
switch( get_key( "123", "?" )) {
case '1':
clear_lfn_slots( 0, lfn_parts-1 );
lfn_reset();
return NULL;
case '2':
lfn_reset();
return NULL;
case '3':
for( i = 0; i < lfn_parts; ++i ) {
__u8 id = (lfn_parts-i) | (i==0 ? LFN_ID_START : 0);
fs_write( lfn_offsets[i]+offsetof(LFN_ENT,id),
sizeof(id), &id );
}
memmove( lfn_unicode, lfn_unicode+lfn_slot*CHARS_PER_LFN*2,
lfn_parts*CHARS_PER_LFN*2 );
break;
}
}
}
for (sum = 0, i = 0; i < 11; i++)
sum = (((sum&1) << 7) | ((sum&0xfe) >> 1)) + de->name[i];
if (sum != lfn_checksum) {
/* checksum doesn't match, long name doesn't apply to this alias */
/* Causes: 1) alias renamed */
/* Fixes: 1) Fix checksum in LFN entries */
char *long_name = CNV_PARTS_SO_FAR();
char *short_name = file_name(de->name);
printf( "Wrong checksum for long file name \"%s\".\n"
" (Short name %s may have changed without updating the long name)\n",
long_name, short_name );
free( long_name );
if (interactive) {
printf( "1: Delete LFN\n2: Leave it as it is.\n"
"3: Fix checksum (attaches to short name %s)\n",
short_name );
}
else printf( " Not auto-correcting this.\n" );
if (interactive) {
switch( get_key( "123", "?" )) {
case '1':
clear_lfn_slots( 0, lfn_parts-1 );
lfn_reset();
return NULL;
case '2':
lfn_reset();
return NULL;
case '3':
for( i = 0; i < lfn_parts; ++i ) {
fs_write( lfn_offsets[i]+offsetof(LFN_ENT,alias_checksum),
sizeof(sum), &sum );
}
break;
}
}
}
lfn = cnv_unicode( lfn_unicode, UNTIL_0, 1 );
lfn_reset();
return( lfn );
}
void lfn_check_orphaned(void)
{
char *long_name;
if (lfn_slot == -1)
return;
long_name = CNV_PARTS_SO_FAR();
printf("Orphaned long file name part \"%s\"\n", long_name);
if (interactive)
printf( "1: Delete.\n2: Leave it.\n" );
else printf( " Auto-deleting.\n" );
if (!interactive || get_key("12","?") == '1') {
clear_lfn_slots(0, lfn_parts - 1);
}
lfn_reset();
}
/* Local Variables: */
/* tab-width: 8 */
/* End: */
/* lfn.c - Functions for handling VFAT long filenames */
/* Written 1998 by Roman Hodek */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <time.h>
#include "common.h"
#include "io.h"
#include "dosfsck.h"
#include "lfn.h"
#include "file.h"
typedef struct {
__u8 id; /* sequence number for slot */
__u8 name0_4[10]; /* first 5 characters in name */
__u8 attr; /* attribute byte */
__u8 reserved; /* always 0 */
__u8 alias_checksum; /* checksum for 8.3 alias */
__u8 name5_10[12]; /* 6 more characters in name */
__u16 start; /* starting cluster number, 0 in long slots */
__u8 name11_12[4]; /* last 2 characters in name */
} LFN_ENT;
#define LFN_ID_START 0x40
#define LFN_ID_SLOTMASK 0x1f
#define CHARS_PER_LFN 13
/* These modul-global vars represent the state of the LFN parser */
unsigned char *lfn_unicode = NULL;
unsigned char lfn_checksum;
int lfn_slot = -1;
loff_t *lfn_offsets = NULL;
int lfn_parts = 0;
static unsigned char fat_uni2esc[64] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z', '+', '-'
};
/* This defines which unicode chars are directly convertable to ISO-8859-1 */
#define UNICODE_CONVERTABLE(cl,ch) (ch == 0 && (cl < 0x80 || cl >= 0xa0))
/* for maxlen param */
#define UNTIL_0 INT_MAX
static void copy_lfn_part( char *dst, LFN_ENT *lfn );
static char *cnv_unicode( const unsigned char *uni, int maxlen, int use_q );
/* Convert name part in 'lfn' from unicode to ASCII */
static __inline char* CNV_THIS_PART(LFN_ENT *lfn)
{ \
char __part_uni[CHARS_PER_LFN*2];
copy_lfn_part( __part_uni, lfn );
cnv_unicode( __part_uni, CHARS_PER_LFN, 0 );
}
/* Convert name parts collected so far (from previous slots) from unicode to
* ASCII */
#define CNV_PARTS_SO_FAR() \
(cnv_unicode( lfn_unicode+(lfn_slot*CHARS_PER_LFN*2), \
lfn_parts*CHARS_PER_LFN, 0 ))
/* This function converts an unicode string to a normal ASCII string, assuming
* ISO-8859-1 charset. Characters not in 8859-1 are converted to the same
* escape notation as used by the kernel, i.e. the uuencode-like ":xxx" */
static char *cnv_unicode( const unsigned char *uni, int maxlen, int use_q )
{
const unsigned char *up;
unsigned char *out, *cp;
int len, val;
for( len = 0, up = uni; (up-uni)/2 < maxlen && (up[0] || up[1]); up += 2 ){
if (UNICODE_CONVERTABLE(up[0],up[1]))
++len;
else
len += 4;
}
cp = out = use_q ? qalloc( &mem_queue, len+1 ) : alloc( len+1 );
for( up = uni; (up-uni)/2 < maxlen && (up[0] || up[1]); up += 2 ) {
if (UNICODE_CONVERTABLE(up[0],up[1]))
*cp++ = up[0];
else {
/* here the same escape notation is used as in the Linux kernel */
*cp++ = ':';
val = (up[1] << 8) + up[0];
cp[2] = fat_uni2esc[val & 0x3f];
val >>= 6;
cp[1] = fat_uni2esc[val & 0x3f];
val >>= 6;
cp[0] = fat_uni2esc[val & 0x3f];
cp += 3;
}
}
*cp = 0;
return( out );
}
static void copy_lfn_part( char *dst, LFN_ENT *lfn )
{
memcpy( dst, lfn->name0_4, 10 );
memcpy( dst+10, lfn->name5_10, 12 );
memcpy( dst+22, lfn->name11_12, 4 );
}
static void clear_lfn_slots( int start, int end )
{
int i;
LFN_ENT empty;
/* New dir entry is zeroed except first byte, which is set to 0xe5.
* This is to avoid that some FAT-reading OSes (not Linux! ;) stop reading
* a directory at the first zero entry...
*/
memset( &empty, 0, sizeof(empty) );
empty.id = DELETED_FLAG;
for( i = start; i <= end; ++i ) {
fs_write( lfn_offsets[i], sizeof(LFN_ENT), &empty );
}
}
void lfn_reset( void )
{
if (lfn_unicode)
free( lfn_unicode );
lfn_unicode = NULL;
if (lfn_offsets)
free( lfn_offsets );
lfn_offsets = NULL;
lfn_slot = -1;
}
/* This function is only called with de->attr == VFAT_LN_ATTR. It stores part
* of the long name. */
void lfn_add_slot( DIR_ENT *de, loff_t dir_offset )
{
LFN_ENT *lfn = (LFN_ENT *)de;
unsigned offset;
if (de->attr != VFAT_LN_ATTR)
die("lfn_add_slot called with non-LFN directory entry");
if (lfn->id & LFN_ID_START) {
if (lfn_slot != -1) {
int can_clear = 0;
/* There is already a LFN "in progess", so it is an error that a
* new start entry is here. */
/* Causes: 1) if slot# == expected: start bit set mysteriously, 2)
* old LFN overwritten by new one */
/* Fixes: 1) delete previous LFN 2) if slot# == expected and
* checksum ok: clear start bit */
/* XXX: Should delay that until next LFN known (then can better
* display the name) */
printf( "A new long file name starts within an old one.\n" );
if ((lfn->id & LFN_ID_SLOTMASK) == lfn_slot &&
lfn->alias_checksum == lfn_checksum) {
char *part1 = CNV_THIS_PART(lfn);
char *part2 = CNV_PARTS_SO_FAR();
printf( " It could be that the LFN start bit is wrong here\n"
" if \"%s\" seems to match \"%s\".\n", part1, part2 );
free( part1 );
free( part2 );
can_clear = 1;
}
if (interactive) {
printf( "1: Delete previous LFN\n2: Leave it as it is.\n" );
if (can_clear)
printf( "3: Clear start bit and concatenate LFNs\n" );
}
else printf( " Not auto-correcting this.\n" );
if (interactive) {
switch( get_key( can_clear ? "123" : "12", "?" )) {
case '1':
clear_lfn_slots( 0, lfn_parts-1 );
lfn_reset();
break;
case '2':
break;
case '3':
lfn->id &= ~LFN_ID_START;
fs_write( dir_offset+offsetof(LFN_ENT,id),
sizeof(lfn->id), &lfn->id );
break;
}
}
}
lfn_slot = lfn->id & LFN_ID_SLOTMASK;
lfn_checksum = lfn->alias_checksum;
lfn_unicode = alloc( (lfn_slot*CHARS_PER_LFN+1)*2 );
lfn_offsets = alloc( lfn_slot*sizeof(loff_t) );
lfn_parts = 0;
}
else if (lfn_slot == -1) {
/* No LFN in progress, but slot found; start bit missing */
/* Causes: 1) start bit got lost, 2) Previous slot with start bit got
* lost */
/* Fixes: 1) delete LFN, 2) set start bit */
char *part = CNV_THIS_PART(lfn);
printf( "Long filename fragment \"%s\" found outside a LFN "
"sequence.\n (Maybe the start bit is missing on the "
"last fragment)\n", part );
if (interactive) {
printf( "1: Delete fragment\n2: Leave it as it is.\n"
"3: Set start bit\n" );
}
else printf( " Not auto-correcting this.\n" );
if (interactive) {
switch( get_key( "123", "?" )) {
case '1':
if (!lfn_offsets)
lfn_offsets = alloc( sizeof(loff_t) );
lfn_offsets[0] = dir_offset;
clear_lfn_slots( 0, 0 );
lfn_reset();
return;
case '2':
lfn_reset();
return;
case '3':
lfn->id |= LFN_ID_START;
fs_write( dir_offset+offsetof(LFN_ENT,id),
sizeof(lfn->id), &lfn->id );
lfn_slot = lfn->id & LFN_ID_SLOTMASK;
lfn_checksum = lfn->alias_checksum;
lfn_unicode = alloc( (lfn_slot*CHARS_PER_LFN+1)*2 );
lfn_offsets = alloc( lfn_slot*sizeof(loff_t) );
lfn_parts = 0;
break;
}
}
}
else if ((lfn->id & LFN_ID_SLOTMASK) != lfn_slot) {
/* wrong sequence number */
/* Causes: 1) seq-no destroyed */
/* Fixes: 1) delete LFN, 2) fix number (maybe only if following parts
* are ok?, maybe only if checksum is ok?) (Attention: space
* for name was allocated before!) */
int can_fix = 0;
printf( "Unexpected long filename sequence number "
"(%d vs. expected %d).\n",
(lfn->id & LFN_ID_SLOTMASK), lfn_slot );
if (lfn->alias_checksum == lfn_checksum) {
char *part1 = CNV_THIS_PART(lfn);
char *part2 = CNV_PARTS_SO_FAR();
printf( " It could be that just the number is wrong\n"
" if \"%s\" seems to match \"%s\".\n", part1, part2 );
free( part1 );
free( part2 );
can_fix = 1;
}
if (interactive) {
printf( "1: Delete LFN\n2: Leave it as it is (and ignore LFN so far)\n" );
if (can_fix)
printf( "3: Correct sequence number\n" );
}
else printf( " Not auto-correcting this.\n" );
if (interactive) {
switch( get_key( can_fix ? "123" : "12", "?" )) {
case '1':
lfn_offsets[lfn_parts++] = dir_offset;
clear_lfn_slots( 0, lfn_parts-1 );
lfn_reset();
return;
case '2':
lfn_reset();
return;
case '3':
lfn->id = (lfn->id & ~LFN_ID_SLOTMASK) | lfn_slot;
fs_write( dir_offset+offsetof(LFN_ENT,id),
sizeof(lfn->id), &lfn->id );
break;
}
}
}
if (lfn->alias_checksum != lfn_checksum) {
/* checksum mismatch */
/* Causes: 1) checksum field here destroyed */
/* Fixes: 1) delete LFN, 2) fix checksum */
printf( "Checksum in long filename part wrong "
"(%02x vs. expected %02x).\n",
lfn->alias_checksum, lfn_checksum );
if (interactive) {
printf( "1: Delete LFN\n2: Leave it as it is.\n"
"3: Correct checksum\n" );
}
else printf( " Not auto-correcting this.\n" );
if (interactive) {
switch( get_key( "123", "?" )) {
case '1':
lfn_offsets[lfn_parts++] = dir_offset;
clear_lfn_slots( 0, lfn_parts-1 );
lfn_reset();
return;
case '2':
break;
case '3':
lfn->alias_checksum = lfn_checksum;
fs_write( dir_offset+offsetof(LFN_ENT,alias_checksum),
sizeof(lfn->alias_checksum), &lfn->alias_checksum );
break;
}
}
}
if (lfn_slot != -1) {
lfn_slot--;
offset = lfn_slot * CHARS_PER_LFN*2;
copy_lfn_part( lfn_unicode+offset, lfn );
if (lfn->id & LFN_ID_START)
lfn_unicode[offset+26] = lfn_unicode[offset+27] = 0;
lfn_offsets[lfn_parts++] = dir_offset;
}
if (lfn->reserved != 0) {
printf( "Reserved field in VFAT long filename slot is not 0 "
"(but 0x%02x).\n", lfn->reserved );
if (interactive)
printf( "1: Fix.\n2: Leave it.\n" );
else printf( "Auto-setting to 0.\n" );
if (!interactive || get_key("12","?") == '1') {
lfn->reserved = 0;
fs_write( dir_offset+offsetof(LFN_ENT,reserved),
sizeof(lfn->reserved), &lfn->reserved );
}
}
if (lfn->start != CT_LE_W(0)) {
printf( "Start cluster field in VFAT long filename slot is not 0 "
"(but 0x%04x).\n", lfn->start );
if (interactive)
printf( "1: Fix.\n2: Leave it.\n" );
else printf( "Auto-setting to 0.\n" );
if (!interactive || get_key("12","?") == '1') {
lfn->start = CT_LE_W(0);
fs_write( dir_offset+offsetof(LFN_ENT,start),
sizeof(lfn->start),&lfn->start );
}
}
}
/* This function is always called when de->attr != VFAT_LN_ATTR is found, to
* retrieve the previously constructed LFN. */
char *lfn_get( DIR_ENT *de )
{
char *lfn;
__u8 sum;
int i;
if (de->attr == VFAT_LN_ATTR)
die("lfn_get called with LFN directory entry");
#if 0
if (de->lcase)
printf( "lcase=%02x\n",de->lcase );
#endif
if (lfn_slot == -1)
/* no long name for this file */
return NULL;
if (lfn_slot != 0) {
/* The long name isn't finished yet. */
/* Causes: 1) LFN slot overwritten by non-VFAT aware tool */
/* Fixes: 1) delete LFN 2) move overwriting entry to somewhere else
* and let user enter missing part of LFN (hard to do :-()
* 3) renumber entries and truncate name */
char *long_name = CNV_PARTS_SO_FAR();
char *short_name = file_name(de->name);
printf( "Unfinished long file name \"%s\".\n"
" (Start may have been overwritten by %s)\n",
long_name, short_name );
free( long_name );
if (interactive) {
printf( "1: Delete LFN\n2: Leave it as it is.\n"
"3: Fix numbering (truncates long name and attaches "
"it to short name %s)\n", short_name );
}
else printf( " Not auto-correcting this.\n" );
if (interactive) {
switch( get_key( "123", "?" )) {
case '1':
clear_lfn_slots( 0, lfn_parts-1 );
lfn_reset();
return NULL;
case '2':
lfn_reset();
return NULL;
case '3':
for( i = 0; i < lfn_parts; ++i ) {
__u8 id = (lfn_parts-i) | (i==0 ? LFN_ID_START : 0);
fs_write( lfn_offsets[i]+offsetof(LFN_ENT,id),
sizeof(id), &id );
}
memmove( lfn_unicode, lfn_unicode+lfn_slot*CHARS_PER_LFN*2,
lfn_parts*CHARS_PER_LFN*2 );
break;
}
}
}
for (sum = 0, i = 0; i < 11; i++)
sum = (((sum&1) << 7) | ((sum&0xfe) >> 1)) + de->name[i];
if (sum != lfn_checksum) {
/* checksum doesn't match, long name doesn't apply to this alias */
/* Causes: 1) alias renamed */
/* Fixes: 1) Fix checksum in LFN entries */
char *long_name = CNV_PARTS_SO_FAR();
char *short_name = file_name(de->name);
printf( "Wrong checksum for long file name \"%s\".\n"
" (Short name %s may have changed without updating the long name)\n",
long_name, short_name );
free( long_name );
if (interactive) {
printf( "1: Delete LFN\n2: Leave it as it is.\n"
"3: Fix checksum (attaches to short name %s)\n",
short_name );
}
else printf( " Not auto-correcting this.\n" );
if (interactive) {
switch( get_key( "123", "?" )) {
case '1':
clear_lfn_slots( 0, lfn_parts-1 );
lfn_reset();
return NULL;
case '2':
lfn_reset();
return NULL;
case '3':
for( i = 0; i < lfn_parts; ++i ) {
fs_write( lfn_offsets[i]+offsetof(LFN_ENT,alias_checksum),
sizeof(sum), &sum );
}
break;
}
}
}
lfn = cnv_unicode( lfn_unicode, UNTIL_0, 1 );
lfn_reset();
return( lfn );
}
void lfn_check_orphaned(void)
{
char *long_name;
if (lfn_slot == -1)
return;
long_name = CNV_PARTS_SO_FAR();
printf("Orphaned long file name part \"%s\"\n", long_name);
if (interactive)
printf( "1: Delete.\n2: Leave it.\n" );
else printf( " Auto-deleting.\n" );
if (!interactive || get_key("12","?") == '1') {
clear_lfn_slots(0, lfn_parts - 1);
}
lfn_reset();
}
/* Local Variables: */
/* tab-width: 8 */
/* End: */

View file

@ -1,20 +1,20 @@
/* lfn.h - Functions for handling VFAT long filenames */
/* Written 1998 by Roman Hodek */
#ifndef _LFN_H
#define _LFN_H
void lfn_reset( void );
/* Reset the state of the LFN parser. */
void lfn_add_slot( DIR_ENT *de, loff_t dir_offset );
/* Process a dir slot that is a VFAT LFN entry. */
char *lfn_get( DIR_ENT *de );
/* Retrieve the long name for the proper dir entry. */
void lfn_check_orphaned(void);
#endif
/* lfn.h - Functions for handling VFAT long filenames */
/* Written 1998 by Roman Hodek */
#ifndef _LFN_H
#define _LFN_H
void lfn_reset( void );
/* Reset the state of the LFN parser. */
void lfn_add_slot( DIR_ENT *de, loff_t dir_offset );
/* Process a dir slot that is a VFAT LFN entry. */
char *lfn_get( DIR_ENT *de );
/* Retrieve the long name for the proper dir entry. */
void lfn_check_orphaned(void);
#endif

View file

@ -1,182 +1,182 @@
#ifndef _LINUX_MSDOS_FS_H
#define _LINUX_MSDOS_FS_H
/*
* The MS-DOS filesystem constants/structures
*/
#include "byteorder.h"
#define SECTOR_SIZE 512 /* sector size (bytes) */
#define SECTOR_BITS 9 /* log2(SECTOR_SIZE) */
#define MSDOS_DPB (MSDOS_DPS) /* dir entries per block */
#define MSDOS_DPB_BITS 4 /* log2(MSDOS_DPB) */
#define MSDOS_DPS (SECTOR_SIZE / sizeof(struct msdos_dir_entry))
#define MSDOS_DPS_BITS 4 /* log2(MSDOS_DPS) */
#if 0
#define CF_LE_W(v) le16_to_cpu(v)
#define CF_LE_L(v) le32_to_cpu(v)
#define CT_LE_W(v) cpu_to_le16(v)
#define CT_LE_L(v) cpu_to_le32(v)
#endif
#define MSDOS_SUPER_MAGIC 0x4d44 /* MD */
#define MSDOS_ROOT_INO 1 /* == MINIX_ROOT_INO */
#define MSDOS_DIR_BITS 5 /* log2(sizeof(struct msdos_dir_entry)) */
/* directory limit */
#define FAT_MAX_DIR_ENTRIES (65536)
#define FAT_MAX_DIR_SIZE (FAT_MAX_DIR_ENTRIES << MSDOS_DIR_BITS)
#define ATTR_NONE 0 /* no attribute bits */
#define ATTR_RO 1 /* read-only */
#define ATTR_HIDDEN 2 /* hidden */
#define ATTR_SYS 4 /* system */
#define ATTR_VOLUME 8 /* volume label */
#define ATTR_DIR 16 /* directory */
#define ATTR_ARCH 32 /* archived */
/* attribute bits that are copied "as is" */
#define ATTR_UNUSED (ATTR_VOLUME | ATTR_ARCH | ATTR_SYS | ATTR_HIDDEN)
/* bits that are used by the Windows 95/Windows NT extended FAT */
#define ATTR_EXT (ATTR_RO | ATTR_HIDDEN | ATTR_SYS | ATTR_VOLUME)
#define CASE_LOWER_BASE 8 /* base is lower case */
#define CASE_LOWER_EXT 16 /* extension is lower case */
#define DELETED_FLAG 0xe5 /* marks file as deleted when in name[0] */
#define IS_FREE(n) (!*(n) || *(n) == DELETED_FLAG)
/* valid file mode bits */
#define MSDOS_VALID_MODE (S_IFREG | S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO)
/* Convert attribute bits and a mask to the UNIX mode. */
#define MSDOS_MKMODE(a, m) (m & (a & ATTR_RO ? S_IRUGO|S_IXUGO : S_IRWXUGO))
#define MSDOS_NAME 11 /* maximum name length */
#define MSDOS_LONGNAME 256 /* maximum name length */
#define MSDOS_SLOTS 21 /* max # of slots for short and long names */
#define MSDOS_DOT ". " /* ".", padded to MSDOS_NAME chars */
#define MSDOS_DOTDOT ".. " /* "..", padded to MSDOS_NAME chars */
/* media of boot sector */
#define FAT_VALID_MEDIA(x) ((0xF8 <= (x) && (x) <= 0xFF) || (x) == 0xF0)
#define FAT_FIRST_ENT(s, x) ((MSDOS_SB(s)->fat_bits == 32 ? 0x0FFFFF00 : \
MSDOS_SB(s)->fat_bits == 16 ? 0xFF00 : 0xF00) | (x))
/* start of data cluster's entry (number of reserved clusters) */
#define FAT_START_ENT 2
/* maximum number of clusters */
#define MAX_FAT12 0xFF4
#define MAX_FAT16 0xFFF4
#define MAX_FAT32 0x0FFFFFF6
#define MAX_FAT(s) (MSDOS_SB(s)->fat_bits == 32 ? MAX_FAT32 : \
MSDOS_SB(s)->fat_bits == 16 ? MAX_FAT16 : MAX_FAT12)
/* bad cluster mark */
#define BAD_FAT12 0xFF7
#define BAD_FAT16 0xFFF7
#define BAD_FAT32 0x0FFFFFF7
/* standard EOF */
#define EOF_FAT12 0xFFF
#define EOF_FAT16 0xFFFF
#define EOF_FAT32 0x0FFFFFFF
#define FAT_ENT_FREE (0)
#define FAT_ENT_BAD (BAD_FAT32)
#define FAT_ENT_EOF (EOF_FAT32)
#define FAT_FSINFO_SIG1 0x41615252
#define FAT_FSINFO_SIG2 0x61417272
#define IS_FSINFO(x) (le32_to_cpu((x)->signature1) == FAT_FSINFO_SIG1 \
&& le32_to_cpu((x)->signature2) == FAT_FSINFO_SIG2)
/*
* ioctl commands
*/
#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2])
#define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct dirent [2])
/* <linux/videotext.h> has used 0x72 ('r') in collision, so skip a few */
#define FAT_IOCTL_GET_ATTRIBUTES _IOR('r', 0x10, __u32)
#define FAT_IOCTL_SET_ATTRIBUTES _IOW('r', 0x11, __u32)
/*
* vfat shortname flags
*/
#define VFAT_SFN_DISPLAY_LOWER 0x0001 /* convert to lowercase for display */
#define VFAT_SFN_DISPLAY_WIN95 0x0002 /* emulate win95 rule for display */
#define VFAT_SFN_DISPLAY_WINNT 0x0004 /* emulate winnt rule for display */
#define VFAT_SFN_CREATE_WIN95 0x0100 /* emulate win95 rule for create */
#define VFAT_SFN_CREATE_WINNT 0x0200 /* emulate winnt rule for create */
struct fat_boot_sector {
__u8 ignored[3]; /* Boot strap short or near jump */
__u8 system_id[8]; /* Name - can be used to special case
partition manager volumes */
__u8 sector_size[2]; /* bytes per logical sector */
__u8 sec_per_clus; /* sectors/cluster */
__le16 reserved; /* reserved sectors */
__u8 fats; /* number of FATs */
__u8 dir_entries[2]; /* root directory entries */
__u8 sectors[2]; /* number of sectors */
__u8 media; /* media code */
__le16 fat_length; /* sectors/FAT */
__le16 secs_track; /* sectors per track */
__le16 heads; /* number of heads */
__le32 hidden; /* hidden sectors (unused) */
__le32 total_sect; /* number of sectors (if sectors == 0) */
/* The following fields are only used by FAT32 */
__le32 fat32_length; /* sectors/FAT */
__le16 flags; /* bit 8: fat mirroring, low 4: active fat */
__u8 version[2]; /* major, minor filesystem version */
__le32 root_cluster; /* first cluster in root directory */
__le16 info_sector; /* filesystem info sector */
__le16 backup_boot; /* backup boot sector */
__le16 reserved2[6]; /* Unused */
};
struct fat_boot_fsinfo {
__le32 signature1; /* 0x41615252L */
__le32 reserved1[120]; /* Nothing as far as I can tell */
__le32 signature2; /* 0x61417272L */
__le32 free_clusters; /* Free cluster count. -1 if unknown */
__le32 next_cluster; /* Most recently allocated cluster */
__le32 reserved2[4];
};
struct msdos_dir_entry {
__u8 name[8],ext[3]; /* name and extension */
__u8 attr; /* attribute bits */
__u8 lcase; /* Case for base and extension */
__u8 ctime_cs; /* Creation time, centiseconds (0-199) */
__le16 ctime; /* Creation time */
__le16 cdate; /* Creation date */
__le16 adate; /* Last access date */
__le16 starthi; /* High 16 bits of cluster in FAT32 */
__le16 time,date,start;/* time, date and first cluster */
__le32 size; /* file size (in bytes) */
};
/* Up to 13 characters of the name */
struct msdos_dir_slot {
__u8 id; /* sequence number for slot */
__u8 name0_4[10]; /* first 5 characters in name */
__u8 attr; /* attribute byte */
__u8 reserved; /* always 0 */
__u8 alias_checksum; /* checksum for 8.3 alias */
__u8 name5_10[12]; /* 6 more characters in name */
__le16 start; /* starting cluster number, 0 in long slots */
__u8 name11_12[4]; /* last 2 characters in name */
};
struct fat_slot_info {
loff_t i_pos; /* on-disk position of directory entry */
loff_t slot_off; /* offset for slot or de start */
int nr_slots; /* number of slots + 1(de) in filename */
struct msdos_dir_entry *de;
struct buffer_head *bh;
};
#endif
#ifndef _LINUX_MSDOS_FS_H
#define _LINUX_MSDOS_FS_H
/*
* The MS-DOS filesystem constants/structures
*/
#include "byteorder.h"
#define SECTOR_SIZE 512 /* sector size (bytes) */
#define SECTOR_BITS 9 /* log2(SECTOR_SIZE) */
#define MSDOS_DPB (MSDOS_DPS) /* dir entries per block */
#define MSDOS_DPB_BITS 4 /* log2(MSDOS_DPB) */
#define MSDOS_DPS (SECTOR_SIZE / sizeof(struct msdos_dir_entry))
#define MSDOS_DPS_BITS 4 /* log2(MSDOS_DPS) */
#if 0
#define CF_LE_W(v) le16_to_cpu(v)
#define CF_LE_L(v) le32_to_cpu(v)
#define CT_LE_W(v) cpu_to_le16(v)
#define CT_LE_L(v) cpu_to_le32(v)
#endif
#define MSDOS_SUPER_MAGIC 0x4d44 /* MD */
#define MSDOS_ROOT_INO 1 /* == MINIX_ROOT_INO */
#define MSDOS_DIR_BITS 5 /* log2(sizeof(struct msdos_dir_entry)) */
/* directory limit */
#define FAT_MAX_DIR_ENTRIES (65536)
#define FAT_MAX_DIR_SIZE (FAT_MAX_DIR_ENTRIES << MSDOS_DIR_BITS)
#define ATTR_NONE 0 /* no attribute bits */
#define ATTR_RO 1 /* read-only */
#define ATTR_HIDDEN 2 /* hidden */
#define ATTR_SYS 4 /* system */
#define ATTR_VOLUME 8 /* volume label */
#define ATTR_DIR 16 /* directory */
#define ATTR_ARCH 32 /* archived */
/* attribute bits that are copied "as is" */
#define ATTR_UNUSED (ATTR_VOLUME | ATTR_ARCH | ATTR_SYS | ATTR_HIDDEN)
/* bits that are used by the Windows 95/Windows NT extended FAT */
#define ATTR_EXT (ATTR_RO | ATTR_HIDDEN | ATTR_SYS | ATTR_VOLUME)
#define CASE_LOWER_BASE 8 /* base is lower case */
#define CASE_LOWER_EXT 16 /* extension is lower case */
#define DELETED_FLAG 0xe5 /* marks file as deleted when in name[0] */
#define IS_FREE(n) (!*(n) || *(n) == DELETED_FLAG)
/* valid file mode bits */
#define MSDOS_VALID_MODE (S_IFREG | S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO)
/* Convert attribute bits and a mask to the UNIX mode. */
#define MSDOS_MKMODE(a, m) (m & (a & ATTR_RO ? S_IRUGO|S_IXUGO : S_IRWXUGO))
#define MSDOS_NAME 11 /* maximum name length */
#define MSDOS_LONGNAME 256 /* maximum name length */
#define MSDOS_SLOTS 21 /* max # of slots for short and long names */
#define MSDOS_DOT ". " /* ".", padded to MSDOS_NAME chars */
#define MSDOS_DOTDOT ".. " /* "..", padded to MSDOS_NAME chars */
/* media of boot sector */
#define FAT_VALID_MEDIA(x) ((0xF8 <= (x) && (x) <= 0xFF) || (x) == 0xF0)
#define FAT_FIRST_ENT(s, x) ((MSDOS_SB(s)->fat_bits == 32 ? 0x0FFFFF00 : \
MSDOS_SB(s)->fat_bits == 16 ? 0xFF00 : 0xF00) | (x))
/* start of data cluster's entry (number of reserved clusters) */
#define FAT_START_ENT 2
/* maximum number of clusters */
#define MAX_FAT12 0xFF4
#define MAX_FAT16 0xFFF4
#define MAX_FAT32 0x0FFFFFF6
#define MAX_FAT(s) (MSDOS_SB(s)->fat_bits == 32 ? MAX_FAT32 : \
MSDOS_SB(s)->fat_bits == 16 ? MAX_FAT16 : MAX_FAT12)
/* bad cluster mark */
#define BAD_FAT12 0xFF7
#define BAD_FAT16 0xFFF7
#define BAD_FAT32 0x0FFFFFF7
/* standard EOF */
#define EOF_FAT12 0xFFF
#define EOF_FAT16 0xFFFF
#define EOF_FAT32 0x0FFFFFFF
#define FAT_ENT_FREE (0)
#define FAT_ENT_BAD (BAD_FAT32)
#define FAT_ENT_EOF (EOF_FAT32)
#define FAT_FSINFO_SIG1 0x41615252
#define FAT_FSINFO_SIG2 0x61417272
#define IS_FSINFO(x) (le32_to_cpu((x)->signature1) == FAT_FSINFO_SIG1 \
&& le32_to_cpu((x)->signature2) == FAT_FSINFO_SIG2)
/*
* ioctl commands
*/
#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2])
#define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct dirent [2])
/* <linux/videotext.h> has used 0x72 ('r') in collision, so skip a few */
#define FAT_IOCTL_GET_ATTRIBUTES _IOR('r', 0x10, __u32)
#define FAT_IOCTL_SET_ATTRIBUTES _IOW('r', 0x11, __u32)
/*
* vfat shortname flags
*/
#define VFAT_SFN_DISPLAY_LOWER 0x0001 /* convert to lowercase for display */
#define VFAT_SFN_DISPLAY_WIN95 0x0002 /* emulate win95 rule for display */
#define VFAT_SFN_DISPLAY_WINNT 0x0004 /* emulate winnt rule for display */
#define VFAT_SFN_CREATE_WIN95 0x0100 /* emulate win95 rule for create */
#define VFAT_SFN_CREATE_WINNT 0x0200 /* emulate winnt rule for create */
struct fat_boot_sector {
__u8 ignored[3]; /* Boot strap short or near jump */
__u8 system_id[8]; /* Name - can be used to special case
partition manager volumes */
__u8 sector_size[2]; /* bytes per logical sector */
__u8 sec_per_clus; /* sectors/cluster */
__le16 reserved; /* reserved sectors */
__u8 fats; /* number of FATs */
__u8 dir_entries[2]; /* root directory entries */
__u8 sectors[2]; /* number of sectors */
__u8 media; /* media code */
__le16 fat_length; /* sectors/FAT */
__le16 secs_track; /* sectors per track */
__le16 heads; /* number of heads */
__le32 hidden; /* hidden sectors (unused) */
__le32 total_sect; /* number of sectors (if sectors == 0) */
/* The following fields are only used by FAT32 */
__le32 fat32_length; /* sectors/FAT */
__le16 flags; /* bit 8: fat mirroring, low 4: active fat */
__u8 version[2]; /* major, minor filesystem version */
__le32 root_cluster; /* first cluster in root directory */
__le16 info_sector; /* filesystem info sector */
__le16 backup_boot; /* backup boot sector */
__le16 reserved2[6]; /* Unused */
};
struct fat_boot_fsinfo {
__le32 signature1; /* 0x41615252L */
__le32 reserved1[120]; /* Nothing as far as I can tell */
__le32 signature2; /* 0x61417272L */
__le32 free_clusters; /* Free cluster count. -1 if unknown */
__le32 next_cluster; /* Most recently allocated cluster */
__le32 reserved2[4];
};
struct msdos_dir_entry {
__u8 name[8],ext[3]; /* name and extension */
__u8 attr; /* attribute bits */
__u8 lcase; /* Case for base and extension */
__u8 ctime_cs; /* Creation time, centiseconds (0-199) */
__le16 ctime; /* Creation time */
__le16 cdate; /* Creation date */
__le16 adate; /* Last access date */
__le16 starthi; /* High 16 bits of cluster in FAT32 */
__le16 time,date,start;/* time, date and first cluster */
__le32 size; /* file size (in bytes) */
};
/* Up to 13 characters of the name */
struct msdos_dir_slot {
__u8 id; /* sequence number for slot */
__u8 name0_4[10]; /* first 5 characters in name */
__u8 attr; /* attribute byte */
__u8 reserved; /* always 0 */
__u8 alias_checksum; /* checksum for 8.3 alias */
__u8 name5_10[12]; /* 6 more characters in name */
__le16 start; /* starting cluster number, 0 in long slots */
__u8 name11_12[4]; /* last 2 characters in name */
};
struct fat_slot_info {
loff_t i_pos; /* on-disk position of directory entry */
loff_t slot_off; /* offset for slot or de start */
int nr_slots; /* number of slots + 1(de) in filename */
struct msdos_dir_entry *de;
struct buffer_head *bh;
};
#endif

View file

@ -1,192 +1,192 @@
#ifndef _LINUX_BYTEORDER_SWAB_H
#define _LINUX_BYTEORDER_SWAB_H
/*
* linux/byteorder/swab.h
* Byte-swapping, independently from CPU endianness
* swabXX[ps]?(foo)
*
* Francois-Rene Rideau <fare@tunes.org> 19971205
* separated swab functions from cpu_to_XX,
* to clean up support for bizarre-endian architectures.
*
* See asm-i386/byteorder.h and suches for examples of how to provide
* architecture-dependent optimized versions
*
*/
#include "compiler.h"
/* casts are necessary for constants, because we never know how for sure
* how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way.
*/
#define ___swab16(x) \
({ \
__u16 __x = (x); \
((__u16)( \
(((__u16)(__x) & (__u16)0x00ffU) << 8) | \
(((__u16)(__x) & (__u16)0xff00U) >> 8) )); \
})
#define ___swab32(x) \
({ \
__u32 __x = (x); \
((__u32)( \
(((__u32)(__x) & (__u32)0x000000ffUL) << 24) | \
(((__u32)(__x) & (__u32)0x0000ff00UL) << 8) | \
(((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) | \
(((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); \
})
#define ___swab64(x) \
({ \
__u64 __x = (x); \
((__u64)( \
(__u64)(((__u64)(__x) & (__u64)0x00000000000000ffULL) << 56) | \
(__u64)(((__u64)(__x) & (__u64)0x000000000000ff00ULL) << 40) | \
(__u64)(((__u64)(__x) & (__u64)0x0000000000ff0000ULL) << 24) | \
(__u64)(((__u64)(__x) & (__u64)0x00000000ff000000ULL) << 8) | \
(__u64)(((__u64)(__x) & (__u64)0x000000ff00000000ULL) >> 8) | \
(__u64)(((__u64)(__x) & (__u64)0x0000ff0000000000ULL) >> 24) | \
(__u64)(((__u64)(__x) & (__u64)0x00ff000000000000ULL) >> 40) | \
(__u64)(((__u64)(__x) & (__u64)0xff00000000000000ULL) >> 56) )); \
})
#define ___constant_swab16(x) \
((__u16)( \
(((__u16)(x) & (__u16)0x00ffU) << 8) | \
(((__u16)(x) & (__u16)0xff00U) >> 8) ))
#define ___constant_swab32(x) \
((__u32)( \
(((__u32)(x) & (__u32)0x000000ffUL) << 24) | \
(((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \
(((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \
(((__u32)(x) & (__u32)0xff000000UL) >> 24) ))
#define ___constant_swab64(x) \
((__u64)( \
(__u64)(((__u64)(x) & (__u64)0x00000000000000ffULL) << 56) | \
(__u64)(((__u64)(x) & (__u64)0x000000000000ff00ULL) << 40) | \
(__u64)(((__u64)(x) & (__u64)0x0000000000ff0000ULL) << 24) | \
(__u64)(((__u64)(x) & (__u64)0x00000000ff000000ULL) << 8) | \
(__u64)(((__u64)(x) & (__u64)0x000000ff00000000ULL) >> 8) | \
(__u64)(((__u64)(x) & (__u64)0x0000ff0000000000ULL) >> 24) | \
(__u64)(((__u64)(x) & (__u64)0x00ff000000000000ULL) >> 40) | \
(__u64)(((__u64)(x) & (__u64)0xff00000000000000ULL) >> 56) ))
/*
* provide defaults when no architecture-specific optimization is detected
*/
#ifndef __arch__swab16
# define __arch__swab16(x) ({ __u16 __tmp = (x) ; ___swab16(__tmp); })
#endif
#ifndef __arch__swab32
# define __arch__swab32(x) ({ __u32 __tmp = (x) ; ___swab32(__tmp); })
#endif
#ifndef __arch__swab64
# define __arch__swab64(x) ({ __u64 __tmp = (x) ; ___swab64(__tmp); })
#endif
#ifndef __arch__swab16p
# define __arch__swab16p(x) __arch__swab16(*(x))
#endif
#ifndef __arch__swab32p
# define __arch__swab32p(x) __arch__swab32(*(x))
#endif
#ifndef __arch__swab64p
# define __arch__swab64p(x) __arch__swab64(*(x))
#endif
#ifndef __arch__swab16s
# define __arch__swab16s(x) do { *(x) = __arch__swab16p((x)); } while (0)
#endif
#ifndef __arch__swab32s
# define __arch__swab32s(x) do { *(x) = __arch__swab32p((x)); } while (0)
#endif
#ifndef __arch__swab64s
# define __arch__swab64s(x) do { *(x) = __arch__swab64p((x)); } while (0)
#endif
/*
* Allow constant folding
*/
#if defined(__GNUC__) && (__GNUC__ >= 2) && defined(__OPTIMIZE__)
# define __swab16(x) \
(__builtin_constant_p((__u16)(x)) ? \
___swab16((x)) : \
__fswab16((x)))
# define __swab32(x) \
(__builtin_constant_p((__u32)(x)) ? \
___swab32((x)) : \
__fswab32((x)))
# define __swab64(x) \
(__builtin_constant_p((__u64)(x)) ? \
___swab64((x)) : \
__fswab64((x)))
#else
# define __swab16(x) __fswab16(x)
# define __swab32(x) __fswab32(x)
# define __swab64(x) __fswab64(x)
#endif /* OPTIMIZE */
static __inline__ __attribute_const__ __u16 __fswab16(__u16 x)
{
return __arch__swab16(x);
}
static __inline__ __u16 __swab16p(const __u16 *x)
{
return __arch__swab16p(x);
}
static __inline__ void __swab16s(__u16 *addr)
{
__arch__swab16s(addr);
}
static __inline__ __attribute_const__ __u32 __fswab32(__u32 x)
{
return __arch__swab32(x);
}
static __inline__ __u32 __swab32p(const __u32 *x)
{
return __arch__swab32p(x);
}
static __inline__ void __swab32s(__u32 *addr)
{
__arch__swab32s(addr);
}
#ifdef __BYTEORDER_HAS_U64__
static __inline__ __attribute_const__ __u64 __fswab64(__u64 x)
{
# ifdef __SWAB_64_THRU_32__
__u32 h = x >> 32;
__u32 l = x & ((1ULL<<32)-1);
return (((__u64)__swab32(l)) << 32) | ((__u64)(__swab32(h)));
# else
return __arch__swab64(x);
# endif
}
static __inline__ __u64 __swab64p(const __u64 *x)
{
return __arch__swab64p(x);
}
static __inline__ void __swab64s(__u64 *addr)
{
__arch__swab64s(addr);
}
#endif /* __BYTEORDER_HAS_U64__ */
#if defined(__KERNEL__)
#define swab16 __swab16
#define swab32 __swab32
#define swab64 __swab64
#define swab16p __swab16p
#define swab32p __swab32p
#define swab64p __swab64p
#define swab16s __swab16s
#define swab32s __swab32s
#define swab64s __swab64s
#endif
#endif /* _LINUX_BYTEORDER_SWAB_H */
#ifndef _LINUX_BYTEORDER_SWAB_H
#define _LINUX_BYTEORDER_SWAB_H
/*
* linux/byteorder/swab.h
* Byte-swapping, independently from CPU endianness
* swabXX[ps]?(foo)
*
* Francois-Rene Rideau <fare@tunes.org> 19971205
* separated swab functions from cpu_to_XX,
* to clean up support for bizarre-endian architectures.
*
* See asm-i386/byteorder.h and suches for examples of how to provide
* architecture-dependent optimized versions
*
*/
#include "compiler.h"
/* casts are necessary for constants, because we never know how for sure
* how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way.
*/
#define ___swab16(x) \
({ \
__u16 __x = (x); \
((__u16)( \
(((__u16)(__x) & (__u16)0x00ffU) << 8) | \
(((__u16)(__x) & (__u16)0xff00U) >> 8) )); \
})
#define ___swab32(x) \
({ \
__u32 __x = (x); \
((__u32)( \
(((__u32)(__x) & (__u32)0x000000ffUL) << 24) | \
(((__u32)(__x) & (__u32)0x0000ff00UL) << 8) | \
(((__u32)(__x) & (__u32)0x00ff0000UL) >> 8) | \
(((__u32)(__x) & (__u32)0xff000000UL) >> 24) )); \
})
#define ___swab64(x) \
({ \
__u64 __x = (x); \
((__u64)( \
(__u64)(((__u64)(__x) & (__u64)0x00000000000000ffULL) << 56) | \
(__u64)(((__u64)(__x) & (__u64)0x000000000000ff00ULL) << 40) | \
(__u64)(((__u64)(__x) & (__u64)0x0000000000ff0000ULL) << 24) | \
(__u64)(((__u64)(__x) & (__u64)0x00000000ff000000ULL) << 8) | \
(__u64)(((__u64)(__x) & (__u64)0x000000ff00000000ULL) >> 8) | \
(__u64)(((__u64)(__x) & (__u64)0x0000ff0000000000ULL) >> 24) | \
(__u64)(((__u64)(__x) & (__u64)0x00ff000000000000ULL) >> 40) | \
(__u64)(((__u64)(__x) & (__u64)0xff00000000000000ULL) >> 56) )); \
})
#define ___constant_swab16(x) \
((__u16)( \
(((__u16)(x) & (__u16)0x00ffU) << 8) | \
(((__u16)(x) & (__u16)0xff00U) >> 8) ))
#define ___constant_swab32(x) \
((__u32)( \
(((__u32)(x) & (__u32)0x000000ffUL) << 24) | \
(((__u32)(x) & (__u32)0x0000ff00UL) << 8) | \
(((__u32)(x) & (__u32)0x00ff0000UL) >> 8) | \
(((__u32)(x) & (__u32)0xff000000UL) >> 24) ))
#define ___constant_swab64(x) \
((__u64)( \
(__u64)(((__u64)(x) & (__u64)0x00000000000000ffULL) << 56) | \
(__u64)(((__u64)(x) & (__u64)0x000000000000ff00ULL) << 40) | \
(__u64)(((__u64)(x) & (__u64)0x0000000000ff0000ULL) << 24) | \
(__u64)(((__u64)(x) & (__u64)0x00000000ff000000ULL) << 8) | \
(__u64)(((__u64)(x) & (__u64)0x000000ff00000000ULL) >> 8) | \
(__u64)(((__u64)(x) & (__u64)0x0000ff0000000000ULL) >> 24) | \
(__u64)(((__u64)(x) & (__u64)0x00ff000000000000ULL) >> 40) | \
(__u64)(((__u64)(x) & (__u64)0xff00000000000000ULL) >> 56) ))
/*
* provide defaults when no architecture-specific optimization is detected
*/
#ifndef __arch__swab16
# define __arch__swab16(x) ({ __u16 __tmp = (x) ; ___swab16(__tmp); })
#endif
#ifndef __arch__swab32
# define __arch__swab32(x) ({ __u32 __tmp = (x) ; ___swab32(__tmp); })
#endif
#ifndef __arch__swab64
# define __arch__swab64(x) ({ __u64 __tmp = (x) ; ___swab64(__tmp); })
#endif
#ifndef __arch__swab16p
# define __arch__swab16p(x) __arch__swab16(*(x))
#endif
#ifndef __arch__swab32p
# define __arch__swab32p(x) __arch__swab32(*(x))
#endif
#ifndef __arch__swab64p
# define __arch__swab64p(x) __arch__swab64(*(x))
#endif
#ifndef __arch__swab16s
# define __arch__swab16s(x) do { *(x) = __arch__swab16p((x)); } while (0)
#endif
#ifndef __arch__swab32s
# define __arch__swab32s(x) do { *(x) = __arch__swab32p((x)); } while (0)
#endif
#ifndef __arch__swab64s
# define __arch__swab64s(x) do { *(x) = __arch__swab64p((x)); } while (0)
#endif
/*
* Allow constant folding
*/
#if defined(__GNUC__) && (__GNUC__ >= 2) && defined(__OPTIMIZE__)
# define __swab16(x) \
(__builtin_constant_p((__u16)(x)) ? \
___swab16((x)) : \
__fswab16((x)))
# define __swab32(x) \
(__builtin_constant_p((__u32)(x)) ? \
___swab32((x)) : \
__fswab32((x)))
# define __swab64(x) \
(__builtin_constant_p((__u64)(x)) ? \
___swab64((x)) : \
__fswab64((x)))
#else
# define __swab16(x) __fswab16(x)
# define __swab32(x) __fswab32(x)
# define __swab64(x) __fswab64(x)
#endif /* OPTIMIZE */
static __inline__ __attribute_const__ __u16 __fswab16(__u16 x)
{
return __arch__swab16(x);
}
static __inline__ __u16 __swab16p(const __u16 *x)
{
return __arch__swab16p(x);
}
static __inline__ void __swab16s(__u16 *addr)
{
__arch__swab16s(addr);
}
static __inline__ __attribute_const__ __u32 __fswab32(__u32 x)
{
return __arch__swab32(x);
}
static __inline__ __u32 __swab32p(const __u32 *x)
{
return __arch__swab32p(x);
}
static __inline__ void __swab32s(__u32 *addr)
{
__arch__swab32s(addr);
}
#ifdef __BYTEORDER_HAS_U64__
static __inline__ __attribute_const__ __u64 __fswab64(__u64 x)
{
# ifdef __SWAB_64_THRU_32__
__u32 h = x >> 32;
__u32 l = x & ((1ULL<<32)-1);
return (((__u64)__swab32(l)) << 32) | ((__u64)(__swab32(h)));
# else
return __arch__swab64(x);
# endif
}
static __inline__ __u64 __swab64p(const __u64 *x)
{
return __arch__swab64p(x);
}
static __inline__ void __swab64s(__u64 *addr)
{
__arch__swab64s(addr);
}
#endif /* __BYTEORDER_HAS_U64__ */
#if defined(__KERNEL__)
#define swab16 __swab16
#define swab32 __swab32
#define swab64 __swab64
#define swab16p __swab16p
#define swab32p __swab32p
#define swab64p __swab64p
#define swab16s __swab16s
#define swab32s __swab32s
#define swab64s __swab64s
#endif
#endif /* _LINUX_BYTEORDER_SWAB_H */

View file

@ -1,8 +1,8 @@
#ifndef _version_h
#define _version_h
#define VERSION "2.8"
#define VERSION_DATE "28 Feb 2001"
#endif /* _version_h */
#ifndef _version_h
#define _version_h
#define VERSION "2.8"
#define VERSION_DATE "28 Feb 2001"
#endif /* _version_h */

File diff suppressed because it is too large Load diff

View file

@ -24,9 +24,9 @@
- New options -A, -S, -C
- Support for filesystems > 2GB
- FAT32 support
Port to work under Windows NT/2K/XP Dec 2002 by
Jens-Uwe Mager <jum@anubis.han.de>
Port to work under Windows NT/2K/XP Dec 2002 by
Jens-Uwe Mager <jum@anubis.han.de>
Copying: Copyright 1993, 1994 David Hudson (dave@humbug.demon.co.uk)
@ -51,34 +51,34 @@
/* Include the header files */
#include "../version.h"
#ifdef _WIN32
#define _WIN32_WINNT 0x0400
#include <windows.h>
#include <winioctl.h>
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#define __BYTE_ORDER __LITTLE_ENDIAN
#define inline
#define __attribute__(x)
#define BLOCK_SIZE 512
#ifdef _WIN32
#define _WIN32_WINNT 0x0400
#include <windows.h>
#include <winioctl.h>
#define __LITTLE_ENDIAN 1234
#define __BIG_ENDIAN 4321
#define __BYTE_ORDER __LITTLE_ENDIAN
#define inline
#define __attribute__(x)
#define BLOCK_SIZE 512
#else
#include <linux/hdreg.h>
#include <linux/fs.h>
#include <linux/fd.h>
#include <endian.h>
#include <mntent.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <unistd.h>
#endif
#include <fcntl.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <time.h>
#if __BYTE_ORDER == __BIG_ENDIAN
@ -106,202 +106,202 @@
#define CT_LE_L(v) (v)
#endif /* __BIG_ENDIAN */
#ifdef _WIN32
typedef unsigned char __u8;
typedef unsigned short __u16;
typedef unsigned int __u32;
typedef unsigned __int64 __u64;
typedef __int64 loff_t;
typedef __int64 ll_t;
extern char *optarg;
extern int optind;
extern int opterr;
extern int optopt;
int getopt(int argc, char *const argv[], const char * optstring);
static int is_device = 0;
#define open WIN32open
#define close WIN32close
#define read WIN32read
#define write WIN32write
#define llseek WIN32llseek
#define O_SHORT_LIVED _O_SHORT_LIVED
#define O_ACCMODE 3
#define O_NONE 3
#define O_BACKUP 0x10000
#define O_SHARED 0x20000
static int WIN32open(const char *path, int oflag, ...)
{
HANDLE fh;
DWORD desiredAccess;
DWORD shareMode;
DWORD creationDisposition;
DWORD flagsAttributes = FILE_ATTRIBUTE_NORMAL;
SECURITY_ATTRIBUTES securityAttributes;
va_list ap;
int pmode;
int trunc = FALSE;
securityAttributes.nLength = sizeof(securityAttributes);
securityAttributes.lpSecurityDescriptor = NULL;
securityAttributes.bInheritHandle = oflag & O_NOINHERIT ? FALSE : TRUE;
switch (oflag & O_ACCMODE) {
case O_RDONLY:
desiredAccess = GENERIC_READ;
shareMode = FILE_SHARE_READ;
break;
case O_WRONLY:
desiredAccess = GENERIC_WRITE;
shareMode = 0;
break;
case O_RDWR:
desiredAccess = GENERIC_READ|GENERIC_WRITE;
shareMode = 0;
break;
case O_NONE:
desiredAccess = 0;
shareMode = FILE_SHARE_READ|FILE_SHARE_WRITE;
}
if (oflag & O_APPEND) {
desiredAccess |= FILE_APPEND_DATA|SYNCHRONIZE;
shareMode = FILE_SHARE_READ|FILE_SHARE_WRITE;
}
if (oflag & O_SHARED)
shareMode |= FILE_SHARE_READ|FILE_SHARE_WRITE;
switch (oflag & (O_CREAT|O_EXCL|O_TRUNC)) {
case 0:
case O_EXCL:
creationDisposition = OPEN_EXISTING;
break;
case O_CREAT:
creationDisposition = OPEN_ALWAYS;
break;
case O_CREAT|O_EXCL:
case O_CREAT|O_TRUNC|O_EXCL:
creationDisposition = CREATE_NEW;
break;
case O_TRUNC:
case O_TRUNC|O_EXCL:
creationDisposition = TRUNCATE_EXISTING;
break;
case O_CREAT|O_TRUNC:
creationDisposition = OPEN_ALWAYS;
trunc = TRUE;
break;
}
if (oflag & O_CREAT) {
va_start(ap, oflag);
pmode = va_arg(ap, int);
va_end(ap);
if ((pmode & 0222) == 0)
flagsAttributes |= FILE_ATTRIBUTE_READONLY;
}
if (oflag & O_TEMPORARY) {
flagsAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
desiredAccess |= DELETE;
}
if (oflag & O_SHORT_LIVED)
flagsAttributes |= FILE_ATTRIBUTE_TEMPORARY;
if (oflag & O_SEQUENTIAL)
flagsAttributes |= FILE_FLAG_SEQUENTIAL_SCAN;
else if (oflag & O_RANDOM)
flagsAttributes |= FILE_FLAG_RANDOM_ACCESS;
if (oflag & O_BACKUP)
flagsAttributes |= FILE_FLAG_BACKUP_SEMANTICS;
if ((fh = CreateFile(path, desiredAccess, shareMode, &securityAttributes,
creationDisposition, flagsAttributes, NULL)) == INVALID_HANDLE_VALUE) {
errno = GetLastError();
return -1;
}
if (trunc) {
if (!SetEndOfFile(fh)) {
errno = GetLastError();
CloseHandle(fh);
DeleteFile(path);
return -1;
}
}
return (int)fh;
}
static int WIN32close(int fd)
{
if (!CloseHandle((HANDLE)fd)) {
errno = GetLastError();
return -1;
}
return 0;
}
static int WIN32read(int fd, void *buf, unsigned int len)
{
DWORD actualLen;
if (!ReadFile((HANDLE)fd, buf, (DWORD)len, &actualLen, NULL)) {
errno = GetLastError();
if (errno == ERROR_BROKEN_PIPE)
return 0;
else
return -1;
}
return (int)actualLen;
}
static int WIN32write(int fd, void *buf, unsigned int len)
{
DWORD actualLen;
if (!WriteFile((HANDLE)fd, buf, (DWORD)len, &actualLen, NULL)) {
errno = GetLastError();
return -1;
}
return (int)actualLen;
}
static loff_t WIN32llseek(int fd, loff_t offset, int whence)
{
long lo, hi;
DWORD err;
lo = offset & 0xffffffff;
hi = offset >> 32;
lo = SetFilePointer((HANDLE)fd, lo, &hi, whence);
if (lo == 0xFFFFFFFF && (err = GetLastError()) != NO_ERROR) {
errno = err;
return -1;
}
return ((loff_t)hi << 32) | (off_t)lo;
}
int fsctl(int fd, int code)
{
DWORD ret;
if (!DeviceIoControl((HANDLE)fd, code, NULL, 0, NULL, 0, &ret, NULL)) {
errno = GetLastError();
return -1;
}
return 0;
}
#else
#define O_NOINHERIT 0
#define O_TEMPORARY 0
#define O_SHORT_LIVED 0
#define O_SEQUENTIAL 0
#define O_RANDOM 0
#define O_BACKUP 0
#define O_SHARED 0
#ifndef O_NONE
# define O_NONE 0
#endif
#ifdef _WIN32
typedef unsigned char __u8;
typedef unsigned short __u16;
typedef unsigned int __u32;
typedef unsigned __int64 __u64;
typedef __int64 loff_t;
typedef __int64 ll_t;
extern char *optarg;
extern int optind;
extern int opterr;
extern int optopt;
int getopt(int argc, char *const argv[], const char * optstring);
static int is_device = 0;
#define open WIN32open
#define close WIN32close
#define read WIN32read
#define write WIN32write
#define llseek WIN32llseek
#define O_SHORT_LIVED _O_SHORT_LIVED
#define O_ACCMODE 3
#define O_NONE 3
#define O_BACKUP 0x10000
#define O_SHARED 0x20000
static int WIN32open(const char *path, int oflag, ...)
{
HANDLE fh;
DWORD desiredAccess;
DWORD shareMode;
DWORD creationDisposition;
DWORD flagsAttributes = FILE_ATTRIBUTE_NORMAL;
SECURITY_ATTRIBUTES securityAttributes;
va_list ap;
int pmode;
int trunc = FALSE;
securityAttributes.nLength = sizeof(securityAttributes);
securityAttributes.lpSecurityDescriptor = NULL;
securityAttributes.bInheritHandle = oflag & O_NOINHERIT ? FALSE : TRUE;
switch (oflag & O_ACCMODE) {
case O_RDONLY:
desiredAccess = GENERIC_READ;
shareMode = FILE_SHARE_READ;
break;
case O_WRONLY:
desiredAccess = GENERIC_WRITE;
shareMode = 0;
break;
case O_RDWR:
desiredAccess = GENERIC_READ|GENERIC_WRITE;
shareMode = 0;
break;
case O_NONE:
desiredAccess = 0;
shareMode = FILE_SHARE_READ|FILE_SHARE_WRITE;
}
if (oflag & O_APPEND) {
desiredAccess |= FILE_APPEND_DATA|SYNCHRONIZE;
shareMode = FILE_SHARE_READ|FILE_SHARE_WRITE;
}
if (oflag & O_SHARED)
shareMode |= FILE_SHARE_READ|FILE_SHARE_WRITE;
switch (oflag & (O_CREAT|O_EXCL|O_TRUNC)) {
case 0:
case O_EXCL:
creationDisposition = OPEN_EXISTING;
break;
case O_CREAT:
creationDisposition = OPEN_ALWAYS;
break;
case O_CREAT|O_EXCL:
case O_CREAT|O_TRUNC|O_EXCL:
creationDisposition = CREATE_NEW;
break;
case O_TRUNC:
case O_TRUNC|O_EXCL:
creationDisposition = TRUNCATE_EXISTING;
break;
case O_CREAT|O_TRUNC:
creationDisposition = OPEN_ALWAYS;
trunc = TRUE;
break;
}
if (oflag & O_CREAT) {
va_start(ap, oflag);
pmode = va_arg(ap, int);
va_end(ap);
if ((pmode & 0222) == 0)
flagsAttributes |= FILE_ATTRIBUTE_READONLY;
}
if (oflag & O_TEMPORARY) {
flagsAttributes |= FILE_FLAG_DELETE_ON_CLOSE;
desiredAccess |= DELETE;
}
if (oflag & O_SHORT_LIVED)
flagsAttributes |= FILE_ATTRIBUTE_TEMPORARY;
if (oflag & O_SEQUENTIAL)
flagsAttributes |= FILE_FLAG_SEQUENTIAL_SCAN;
else if (oflag & O_RANDOM)
flagsAttributes |= FILE_FLAG_RANDOM_ACCESS;
if (oflag & O_BACKUP)
flagsAttributes |= FILE_FLAG_BACKUP_SEMANTICS;
if ((fh = CreateFile(path, desiredAccess, shareMode, &securityAttributes,
creationDisposition, flagsAttributes, NULL)) == INVALID_HANDLE_VALUE) {
errno = GetLastError();
return -1;
}
if (trunc) {
if (!SetEndOfFile(fh)) {
errno = GetLastError();
CloseHandle(fh);
DeleteFile(path);
return -1;
}
}
return (int)fh;
}
static int WIN32close(int fd)
{
if (!CloseHandle((HANDLE)fd)) {
errno = GetLastError();
return -1;
}
return 0;
}
static int WIN32read(int fd, void *buf, unsigned int len)
{
DWORD actualLen;
if (!ReadFile((HANDLE)fd, buf, (DWORD)len, &actualLen, NULL)) {
errno = GetLastError();
if (errno == ERROR_BROKEN_PIPE)
return 0;
else
return -1;
}
return (int)actualLen;
}
static int WIN32write(int fd, void *buf, unsigned int len)
{
DWORD actualLen;
if (!WriteFile((HANDLE)fd, buf, (DWORD)len, &actualLen, NULL)) {
errno = GetLastError();
return -1;
}
return (int)actualLen;
}
static loff_t WIN32llseek(int fd, loff_t offset, int whence)
{
long lo, hi;
DWORD err;
lo = offset & 0xffffffff;
hi = offset >> 32;
lo = SetFilePointer((HANDLE)fd, lo, &hi, whence);
if (lo == 0xFFFFFFFF && (err = GetLastError()) != NO_ERROR) {
errno = err;
return -1;
}
return ((loff_t)hi << 32) | (off_t)lo;
}
int fsctl(int fd, int code)
{
DWORD ret;
if (!DeviceIoControl((HANDLE)fd, code, NULL, 0, NULL, 0, &ret, NULL)) {
errno = GetLastError();
return -1;
}
return 0;
}
#else
#define O_NOINHERIT 0
#define O_TEMPORARY 0
#define O_SHORT_LIVED 0
#define O_SEQUENTIAL 0
#define O_RANDOM 0
#define O_BACKUP 0
#define O_SHARED 0
#ifndef O_NONE
# define O_NONE 0
#endif
typedef long long ll_t;
/* Use the _llseek system call directly, because there (once?) was a bug in
* the glibc implementation of it. */
@ -327,8 +327,8 @@ static loff_t llseek( int fd, loff_t offset, int whence )
return actual;
}
#endif
#endif
#endif
/* Constant definitions */
@ -402,9 +402,9 @@ cdiv (int a, int b)
/* __attribute__ ((packed)) is used on all structures to make gcc ignore any
* alignments */
#ifdef _WIN32
#pragma pack(push, 1)
#ifdef _WIN32
#pragma pack(push, 1)
#endif
struct msdos_volume_info {
__u8 drive_number; /* BIOS drive number */
@ -476,10 +476,10 @@ struct msdos_dir_entry
__u16 time, date, start; /* time, date and first cluster */
__u32 size; /* file size (in bytes) */
} __attribute__ ((packed));
#ifdef _WIN32
#pragma pack(pop)
#endif
#ifdef _WIN32
#pragma pack(pop)
#endif
/* The "boot code" we put into the filesystem... it writes a message and
tells the user to try again */
@ -559,12 +559,12 @@ static void check_blocks (void);
static void get_list_blocks (char *filename);
static int valid_offset (int fd, loff_t offset);
static int count_blocks (char *filename);
static void check_mount (char *device_name);
#ifdef _WIN32
static void establish_params (void);
static void check_mount (char *device_name);
#ifdef _WIN32
static void establish_params (void);
#else
static void establish_params (int device_num, int size);
#endif
#endif
static void setup_tables (void);
static void write_tables (void);
@ -692,13 +692,13 @@ check_blocks (void)
printf ("Searching for bad blocks ");
fflush (stdout);
}
currently_testing = 0;
currently_testing = 0;
#ifndef _WIN32
if (verbose)
{
signal (SIGALRM, alarm_intr);
alarm (5);
}
}
#endif
try = TEST_BUFFER_BLOCKS;
while (currently_testing < blocks)
@ -757,7 +757,7 @@ get_list_blocks (char *filename)
(badblocks > 1) ? "s" : "");
}
#ifndef _WIN32
/* Given a file descriptor and an offset, check whether the offset is a valid offset for the file - return FALSE if it
isn't valid or TRUE if it is */
@ -773,44 +773,44 @@ valid_offset (int fd, loff_t offset)
return FALSE;
return TRUE;
}
#endif
#endif
/* Given a filename, look to see how many blocks of BLOCK_SIZE are present, returning the answer */
static int
count_blocks (char *filename)
{
#ifdef _WIN32
int fd;
DISK_GEOMETRY geom;
BY_HANDLE_FILE_INFORMATION hinfo;
DWORD ret;
loff_t len = 0;
if ((fd = open(filename, O_RDONLY)) < 0) {
perror(filename);
exit(1);
}
/*
* This should probably use IOCTL_DISK_GET_LENGTH_INFO here, but
* this ioctl is only available in XP and up.
*/
if (is_device) {
if (!DeviceIoControl((HANDLE)fd, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &geom, sizeof(geom), &ret, NULL)) {
errno = GetLastError();
die("unable to get length for '%s'");
}
len = geom.Cylinders.QuadPart*geom.TracksPerCylinder*geom.SectorsPerTrack*BLOCK_SIZE;
} else {
if (!GetFileInformationByHandle((HANDLE)fd, &hinfo)) {
errno = GetLastError();
die("unable to get length for '%s'");
}
len = ((loff_t)hinfo.nFileSizeHigh << 32) | (loff_t)hinfo.nFileSizeLow;
}
close(fd);
return len/BLOCK_SIZE;
{
#ifdef _WIN32
int fd;
DISK_GEOMETRY geom;
BY_HANDLE_FILE_INFORMATION hinfo;
DWORD ret;
loff_t len = 0;
if ((fd = open(filename, O_RDONLY)) < 0) {
perror(filename);
exit(1);
}
/*
* This should probably use IOCTL_DISK_GET_LENGTH_INFO here, but
* this ioctl is only available in XP and up.
*/
if (is_device) {
if (!DeviceIoControl((HANDLE)fd, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &geom, sizeof(geom), &ret, NULL)) {
errno = GetLastError();
die("unable to get length for '%s'");
}
len = geom.Cylinders.QuadPart*geom.TracksPerCylinder*geom.SectorsPerTrack*BLOCK_SIZE;
} else {
if (!GetFileInformationByHandle((HANDLE)fd, &hinfo)) {
errno = GetLastError();
die("unable to get length for '%s'");
}
len = ((loff_t)hinfo.nFileSizeHigh << 32) | (loff_t)hinfo.nFileSizeLow;
}
close(fd);
return len/BLOCK_SIZE;
#else
loff_t high, low;
int fd;
@ -836,7 +836,7 @@ count_blocks (char *filename)
valid_offset (fd, 0);
close (fd);
return (low + 1) / BLOCK_SIZE;
return (low + 1) / BLOCK_SIZE;
#endif
}
@ -845,7 +845,7 @@ count_blocks (char *filename)
static void
check_mount (char *device_name)
{
{
#ifndef _WIN32
FILE *f;
struct mntent *mnt;
@ -855,70 +855,70 @@ check_mount (char *device_name)
while ((mnt = getmntent (f)) != NULL)
if (strcmp (device_name, mnt->mnt_fsname) == 0)
die ("%s contains a mounted file system.");
endmntent (f);
endmntent (f);
#endif
}
/* Establish the geometry and media parameters for the device */
#ifdef _WIN32
static void
establish_params (void)
{
DISK_GEOMETRY geometry;
DWORD ret;
if (!is_device) {
bs.media = (char) 0xf8; /* Set up the media descriptor for a hard drive */
bs.dir_entries[0] = (char) 0;
bs.dir_entries[1] = (char) 2;
/* For FAT32, use 4k clusters on sufficiently large file systems,
* otherwise 1 sector per cluster. This is also what M$'s format
* command does for FAT32. */
bs.cluster_size = (char)
(size_fat == 32 ?
((ll_t)blocks*SECTORS_PER_BLOCK >= 512*1024 ? 8 : 1) :
4); /* FAT12 and FAT16: start at 4 sectors per cluster */
return;
}
if (!DeviceIoControl((HANDLE)dev, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &geometry, sizeof(geometry), &ret, NULL)) {
errno = GetLastError();
die ("unable to get geometry for '%s'");
}
bs.secs_track = geometry.SectorsPerTrack;
bs.heads = geometry.TracksPerCylinder;
switch (geometry.MediaType) {
case F3_1Pt44_512:
bs.media = (char) 0xf9;
bs.cluster_size = (char) 2;
bs.dir_entries[0] = (char) 112;
bs.dir_entries[1] = (char) 0;
break;
case F3_2Pt88_512:
bs.media = (char) 0xf0;
bs.cluster_size = (char)(atari_format ? 2 : 1);
bs.dir_entries[0] = (char) 224;
bs.dir_entries[1] = (char) 0;
break;
case F3_720_512:
bs.media = (char) 0xfd;
bs.cluster_size = (char) 2;
bs.dir_entries[0] = (char) 112;
bs.dir_entries[1] = (char) 0;
break;
default:
bs.media = (char) 0xf8; /* Set up the media descriptor for a hard drive */
bs.dir_entries[0] = (char) 0;
bs.dir_entries[1] = (char) 2;
/* For FAT32, use 4k clusters on sufficiently large file systems,
* otherwise 1 sector per cluster. This is also what M$'s format
* command does for FAT32. */
bs.cluster_size = (char)
(size_fat == 32 ?
((ll_t)blocks*SECTORS_PER_BLOCK >= 512*1024 ? 8 : 1) :
4); /* FAT12 and FAT16: start at 4 sectors per cluster */
}
}
#ifdef _WIN32
static void
establish_params (void)
{
DISK_GEOMETRY geometry;
DWORD ret;
if (!is_device) {
bs.media = (char) 0xf8; /* Set up the media descriptor for a hard drive */
bs.dir_entries[0] = (char) 0;
bs.dir_entries[1] = (char) 2;
/* For FAT32, use 4k clusters on sufficiently large file systems,
* otherwise 1 sector per cluster. This is also what M$'s format
* command does for FAT32. */
bs.cluster_size = (char)
(size_fat == 32 ?
((ll_t)blocks*SECTORS_PER_BLOCK >= 512*1024 ? 8 : 1) :
4); /* FAT12 and FAT16: start at 4 sectors per cluster */
return;
}
if (!DeviceIoControl((HANDLE)dev, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &geometry, sizeof(geometry), &ret, NULL)) {
errno = GetLastError();
die ("unable to get geometry for '%s'");
}
bs.secs_track = geometry.SectorsPerTrack;
bs.heads = geometry.TracksPerCylinder;
switch (geometry.MediaType) {
case F3_1Pt44_512:
bs.media = (char) 0xf9;
bs.cluster_size = (char) 2;
bs.dir_entries[0] = (char) 112;
bs.dir_entries[1] = (char) 0;
break;
case F3_2Pt88_512:
bs.media = (char) 0xf0;
bs.cluster_size = (char)(atari_format ? 2 : 1);
bs.dir_entries[0] = (char) 224;
bs.dir_entries[1] = (char) 0;
break;
case F3_720_512:
bs.media = (char) 0xfd;
bs.cluster_size = (char) 2;
bs.dir_entries[0] = (char) 112;
bs.dir_entries[1] = (char) 0;
break;
default:
bs.media = (char) 0xf8; /* Set up the media descriptor for a hard drive */
bs.dir_entries[0] = (char) 0;
bs.dir_entries[1] = (char) 2;
/* For FAT32, use 4k clusters on sufficiently large file systems,
* otherwise 1 sector per cluster. This is also what M$'s format
* command does for FAT32. */
bs.cluster_size = (char)
(size_fat == 32 ?
((ll_t)blocks*SECTORS_PER_BLOCK >= 512*1024 ? 8 : 1) :
4); /* FAT12 and FAT16: start at 4 sectors per cluster */
}
}
#else
static void
establish_params (int device_num,int size)
@ -1099,7 +1099,7 @@ establish_params (int device_num,int size)
4); /* FAT12 and FAT16: start at 4 sectors per cluster */
}
}
#endif
#endif
/* Create the filesystem data tables */
@ -1629,9 +1629,9 @@ static void
write_tables (void)
{
int x;
int fat_length;
#ifdef _WIN32
int blk;
int fat_length;
#ifdef _WIN32
int blk;
#endif
fat_length = (size_fat == 32) ?
@ -1658,17 +1658,17 @@ write_tables (void)
}
/* seek to start of FATS and write them all */
seekto( reserved_sectors*sector_size, "first FAT" );
for (x = 1; x <= nr_fats; x++)
#ifdef _WIN32
/*
* WIN32 appearently has problems writing very large chunks directly
* to disk devices. To not produce errors because of resource shortages
* split up the write in sector size chunks.
*/
for (blk = 0; blk < fat_length; blk++)
writebuf(fat+blk*sector_size, sector_size, "FAT");
for (x = 1; x <= nr_fats; x++)
#ifdef _WIN32
/*
* WIN32 appearently has problems writing very large chunks directly
* to disk devices. To not produce errors because of resource shortages
* split up the write in sector size chunks.
*/
for (blk = 0; blk < fat_length; blk++)
writebuf(fat+blk*sector_size, sector_size, "FAT");
#else
writebuf( fat, fat_length * sector_size, "FAT" );
writebuf( fat, fat_length * sector_size, "FAT" );
#endif
/* Write the root directory directly after the last FAT. This is the root
* dir area on FAT12/16, and the first cluster on FAT32. */
@ -1730,22 +1730,22 @@ main (int argc, char **argv)
int c;
char *tmp;
char *listfile = NULL;
FILE *msgfile;
#ifdef _WIN32
static char dev_buf[] = "\\\\.\\X:";
FILE *msgfile;
#ifdef _WIN32
static char dev_buf[] = "\\\\.\\X:";
#else
struct stat statbuf;
struct stat statbuf;
#endif
int i = 0, pos, ch;
int create = 0;
if (argc && *argv) { /* What's the program name? */
char *p;
program_name = *argv;
#ifdef _WIN32
if ((p = strrchr( program_name, '\\' )))
program_name = *argv;
#ifdef _WIN32
if ((p = strrchr( program_name, '\\' )))
#else
if ((p = strrchr( program_name, '/' )))
if ((p = strrchr( program_name, '/' )))
#endif
program_name = p+1;
}
@ -1754,9 +1754,9 @@ main (int argc, char **argv)
volume_id = (long)create_time; /* Default volume ID = creation time */
check_atari();
printf ("%s " VERSION " (" VERSION_DATE ")\n"
#ifdef _WIN32
"Win32 port by Jens-Uwe Mager <jum@anubis.han.de>\n"
printf ("%s " VERSION " (" VERSION_DATE ")\n"
#ifdef _WIN32
"Win32 port by Jens-Uwe Mager <jum@anubis.han.de>\n"
#endif
, program_name);
@ -1943,16 +1943,16 @@ main (int argc, char **argv)
printf( "Unknown option: %c\n", c );
usage ();
}
if (optind >= argc)
if (optind >= argc)
usage();
device_name = argv[optind]; /* Determine the number of blocks in the FS */
#ifdef _WIN32
if (device_name[1] == ':' && device_name[2] == '\0') {
dev_buf[4] = device_name[0];
device_name = dev_buf;
is_device = 1;
}
device_name = argv[optind]; /* Determine the number of blocks in the FS */
#ifdef _WIN32
if (device_name[1] == ':' && device_name[2] == '\0') {
dev_buf[4] = device_name[0];
device_name = dev_buf;
is_device = 1;
}
#endif
if (!create)
i = count_blocks (device_name); /* Have a look and see! */
@ -1987,12 +1987,12 @@ main (int argc, char **argv)
check_mount (device_name); /* Is the device already mounted? */
dev = open (device_name, O_RDWR|O_SHARED); /* Is it a suitable device to build the FS on? */
if (dev < 0)
die ("unable to open %s");
#ifdef _WIN32
if (is_device) {
if (fsctl(dev, FSCTL_LOCK_VOLUME) == -1)
die("unable to lock %s");
}
die ("unable to open %s");
#ifdef _WIN32
if (is_device) {
if (fsctl(dev, FSCTL_LOCK_VOLUME) == -1)
die("unable to lock %s");
}
#endif
}
else {
@ -2011,11 +2011,11 @@ main (int argc, char **argv)
if (llseek( dev, 0, SEEK_SET ) != 0)
die( "seek failed" );
}
#ifdef _WIN32
if (!is_device)
check = 0;
establish_params();
#ifdef _WIN32
if (!is_device)
check = 0;
establish_params();
#else
if (fstat (dev, &statbuf) < 0)
die ("unable to stat %s");
@ -2040,7 +2040,7 @@ main (int argc, char **argv)
die ("Will not try to make filesystem on '%s'");
establish_params (statbuf.st_rdev,statbuf.st_size);
/* Establish the media parameters */
/* Establish the media parameters */
#endif
setup_tables (); /* Establish the file system tables */
@ -2052,14 +2052,14 @@ main (int argc, char **argv)
write_tables (); /* Write the file system tables away! */
#ifdef _WIN32
if (is_device) {
if (fsctl(dev, FSCTL_DISMOUNT_VOLUME) == -1)
die("unable to dismount %s");
if (fsctl(dev, FSCTL_UNLOCK_VOLUME) == -1)
die("unable to unlock %s");
}
#endif
#ifdef _WIN32
if (is_device) {
if (fsctl(dev, FSCTL_DISMOUNT_VOLUME) == -1)
die("unable to dismount %s");
if (fsctl(dev, FSCTL_UNLOCK_VOLUME) == -1)
die("unable to unlock %s");
}
#endif
exit (0); /* Terminate with no errors! */
}