From be04afc10347202377f01991658f25a3b99e806a Mon Sep 17 00:00:00 2001 From: Klemens Friedl Date: Sun, 3 Apr 2005 19:06:49 +0000 Subject: [PATCH] ReactOS Package Manager More information: http://reactos.com/wiki/index.php/ReactOS_Package_Manager * Maarten Bosma (Dr. Fred) * Klemens Friedl (frik85) svn path=/trunk/; revision=14481 --- rosapps/packmgr/gui/en.rc | 43 + rosapps/packmgr/gui/generic.rc | 24 + rosapps/packmgr/gui/main.cpp | 401 +++++++ rosapps/packmgr/gui/main.h | 62 + rosapps/packmgr/gui/makefile | 24 + rosapps/packmgr/gui/packmgr.rc | 18 + rosapps/packmgr/gui/res/blank.ico | Bin 0 -> 11502 bytes rosapps/packmgr/gui/res/development.ico | Bin 0 -> 4710 bytes rosapps/packmgr/gui/res/games.ico | Bin 0 -> 11502 bytes rosapps/packmgr/gui/res/graphics.ico | Bin 0 -> 9062 bytes rosapps/packmgr/gui/res/inet.ico | Bin 0 -> 18902 bytes rosapps/packmgr/gui/res/install.ico | Bin 0 -> 18902 bytes rosapps/packmgr/gui/res/installed.ico | Bin 0 -> 21630 bytes rosapps/packmgr/gui/res/installsource.ico | Bin 0 -> 18902 bytes rosapps/packmgr/gui/res/multimedia.ico | Bin 0 -> 7782 bytes rosapps/packmgr/gui/res/office.ico | Bin 0 -> 7782 bytes rosapps/packmgr/gui/res/others.ico | Bin 0 -> 21630 bytes rosapps/packmgr/gui/res/packetmanager.ico | Bin 0 -> 22486 bytes rosapps/packmgr/gui/res/toolbar.bmp | Bin 0 -> 9270 bytes rosapps/packmgr/gui/res/tools.ico | Bin 0 -> 18902 bytes rosapps/packmgr/gui/res/uninstall.ico | Bin 0 -> 21630 bytes rosapps/packmgr/gui/res/update.ico | Bin 0 -> 21630 bytes rosapps/packmgr/gui/resource.h | 14 + rosapps/packmgr/help.txt | 9 + rosapps/packmgr/lib/download.cpp | 117 ++ rosapps/packmgr/lib/en.rc | 19 + rosapps/packmgr/lib/error.h | 16 + rosapps/packmgr/lib/expat.h | 1081 ++++++++++++++++++ rosapps/packmgr/lib/functions.cpp | 101 ++ rosapps/packmgr/lib/log.cpp | 98 ++ rosapps/packmgr/lib/log.h | 21 + rosapps/packmgr/lib/main.cpp | 185 +++ rosapps/packmgr/lib/makefile | 27 + rosapps/packmgr/lib/package.cpp | 191 ++++ rosapps/packmgr/lib/package.def | 13 + rosapps/packmgr/lib/package.hpp | 86 ++ rosapps/packmgr/lib/package.rc | 15 + rosapps/packmgr/lib/script.cpp | 278 +++++ rosapps/packmgr/lib/script.h | 65 ++ rosapps/packmgr/lib/tree.cpp | 112 ++ rosapps/packmgr/makefile | 14 + rosapps/packmgr/tree/abiword.inst.rps | 9 + rosapps/packmgr/tree/abiword.xml | 7 + rosapps/packmgr/tree/mozcontrol.xml | 7 + rosapps/packmgr/tree/mozillacontrol.inst.rps | 9 + rosapps/packmgr/tree/tree.xml | 69 ++ 46 files changed, 3135 insertions(+) create mode 100644 rosapps/packmgr/gui/en.rc create mode 100644 rosapps/packmgr/gui/generic.rc create mode 100644 rosapps/packmgr/gui/main.cpp create mode 100644 rosapps/packmgr/gui/main.h create mode 100644 rosapps/packmgr/gui/makefile create mode 100644 rosapps/packmgr/gui/packmgr.rc create mode 100644 rosapps/packmgr/gui/res/blank.ico create mode 100644 rosapps/packmgr/gui/res/development.ico create mode 100644 rosapps/packmgr/gui/res/games.ico create mode 100644 rosapps/packmgr/gui/res/graphics.ico create mode 100644 rosapps/packmgr/gui/res/inet.ico create mode 100644 rosapps/packmgr/gui/res/install.ico create mode 100644 rosapps/packmgr/gui/res/installed.ico create mode 100644 rosapps/packmgr/gui/res/installsource.ico create mode 100644 rosapps/packmgr/gui/res/multimedia.ico create mode 100644 rosapps/packmgr/gui/res/office.ico create mode 100644 rosapps/packmgr/gui/res/others.ico create mode 100644 rosapps/packmgr/gui/res/packetmanager.ico create mode 100644 rosapps/packmgr/gui/res/toolbar.bmp create mode 100644 rosapps/packmgr/gui/res/tools.ico create mode 100644 rosapps/packmgr/gui/res/uninstall.ico create mode 100644 rosapps/packmgr/gui/res/update.ico create mode 100644 rosapps/packmgr/gui/resource.h create mode 100644 rosapps/packmgr/help.txt create mode 100644 rosapps/packmgr/lib/download.cpp create mode 100644 rosapps/packmgr/lib/en.rc create mode 100644 rosapps/packmgr/lib/error.h create mode 100644 rosapps/packmgr/lib/expat.h create mode 100644 rosapps/packmgr/lib/functions.cpp create mode 100644 rosapps/packmgr/lib/log.cpp create mode 100644 rosapps/packmgr/lib/log.h create mode 100644 rosapps/packmgr/lib/main.cpp create mode 100644 rosapps/packmgr/lib/makefile create mode 100644 rosapps/packmgr/lib/package.cpp create mode 100644 rosapps/packmgr/lib/package.def create mode 100644 rosapps/packmgr/lib/package.hpp create mode 100644 rosapps/packmgr/lib/package.rc create mode 100644 rosapps/packmgr/lib/script.cpp create mode 100644 rosapps/packmgr/lib/script.h create mode 100644 rosapps/packmgr/lib/tree.cpp create mode 100644 rosapps/packmgr/makefile create mode 100644 rosapps/packmgr/tree/abiword.inst.rps create mode 100644 rosapps/packmgr/tree/abiword.xml create mode 100644 rosapps/packmgr/tree/mozcontrol.xml create mode 100644 rosapps/packmgr/tree/mozillacontrol.inst.rps create mode 100644 rosapps/packmgr/tree/tree.xml diff --git a/rosapps/packmgr/gui/en.rc b/rosapps/packmgr/gui/en.rc new file mode 100644 index 00000000000..d82f2a9b818 --- /dev/null +++ b/rosapps/packmgr/gui/en.rc @@ -0,0 +1,43 @@ + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +/* Dialogs */ +IDD_OPTIONS DIALOG DISCARDABLE 0, 0, 180, 200 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Options" +FONT 8, "MS Sans Serif" +BEGIN + LTEXT "There are no options yet.", 0, 50, 95, 80, 8 +END + +IDD_DOIT DIALOG DISCARDABLE 0, 0, 180, 100 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Performing Operations" +FONT 8, "MS Sans Serif" +BEGIN + + CTEXT "{Status}", IDC_TSTATUS, 0, 10, 180, 8 + + CONTROL "", IDC_STATUS1, "msctls_progress32", PBS_SMOOTH, 20, 25, 140, 15 + + CONTROL "", IDC_STATUS2, "msctls_progress32", PBS_SMOOTH, 20, 45, 140, 15 + + PUSHBUTTON "Abort", IDC_CANCEL, 65, 70, 50, 14, WS_DISABLED +END + +IDR_POPUP MENU DISCARDABLE +BEGIN + POPUP "PopUp", MENUBARBREAK + BEGIN + MENUITEM "No Action", 1, GRAYED + MENUITEM "Install (recommended)", 2, GRAYED + MENUITEM "Install from Source", 3, GRAYED + MENUITEM "Update", 4, GRAYED + MENUITEM "Unnstall", 5, GRAYED + MENUITEM SEPARATOR + MENUITEM "Options", 8 + MENUITEM SEPARATOR + MENUITEM "DoIt", 6 + END +END + diff --git a/rosapps/packmgr/gui/generic.rc b/rosapps/packmgr/gui/generic.rc new file mode 100644 index 00000000000..25486492e49 --- /dev/null +++ b/rosapps/packmgr/gui/generic.rc @@ -0,0 +1,24 @@ + +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL + +IDI_MAIN ICON DISCARDABLE "res/packetmanager.ico" +IDB_TOOLBAR BITMAP DISCARDABLE "res/toolbar.bmp" + +/* TreeIcons - Categories */ +1 ICON DISCARDABLE "res/blank.ico" +2 ICON DISCARDABLE "res/inet.ico" +3 ICON DISCARDABLE "res/office.ico" +4 ICON DISCARDABLE "res/graphics.ico" +5 ICON DISCARDABLE "res/multimedia.ico" +6 ICON DISCARDABLE "res/development.ico" +7 ICON DISCARDABLE "res/games.ico" +8 ICON DISCARDABLE "res/tools.ico" +9 ICON DISCARDABLE "res/others.ico" +10 ICON DISCARDABLE "res/installed.ico" + +/* TreeIcons - Actions */ +11 ICON DISCARDABLE "res/install.ico" +12 ICON DISCARDABLE "res/installsource.ico" +13 ICON DISCARDABLE "res/update.ico" +14 ICON DISCARDABLE "res/uninstall.ico" + diff --git a/rosapps/packmgr/gui/main.cpp b/rosapps/packmgr/gui/main.cpp new file mode 100644 index 00000000000..893cb7a026a --- /dev/null +++ b/rosapps/packmgr/gui/main.cpp @@ -0,0 +1,401 @@ +//////////////////////////////////////////////////////// +// +// main.cpp +// +// Implementation of the Package Manager GUI +// +// +// Maarten Bosma, 09.01.2004 +// maarten.paul@bosma.de +// +//////////////////////////////////////////////////////////////////// + +#include "main.h" + + +// 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)) + { + 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) +{ + string source; + + ifstream file("help.txt", ios_base::in); + getline(file, source, '\0'); + + SetText(source.c_str()); +} + +// 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 + RegisterHotKey(hwnd, 1, MOD_CONTROL, VK_1); + RegisterHotKey(hwnd, 2, MOD_CONTROL, VK_2); + RegisterHotKey(hwnd, 3, MOD_CONTROL, VK_3); + RegisterHotKey(hwnd, 4, MOD_CONTROL, VK_4); + RegisterHotKey(hwnd, 0, MOD_CONTROL, VK_0); +} + +// 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; +} + +// 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 1; +} + +// Set the text of the text box +int SetText (const char* text) +{ + int i = 0; + string source = text; + + // the windows does not need "\n" + // for new lines but "\r\n" + for(i=0; source[i]; i++) + if(source[i]=='\n' && source[i]!='\r') + source.insert (i++, "\r"); + + SetWindowTextA(hEdit, source.c_str()); + + 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); + } + + else if ((int)(((LPNMHDR)lParam)->code) == NM_RCLICK) // <= ahhh 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) == ERR_OK) + break; + + MessageBeep(MB_ICONHAND); + } + + // DoIt + else if(LOWORD(wParam)==6) + { + if(PML_DoIt(tree, SetStatus) == 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); + + else + MessageBox(0,0,0,0); + } + break; + + // prozess hotkeys + case WM_HOTKEY: + { + if(PML_SetAction(tree, selected, wParam, SetIcon) != 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; +} diff --git a/rosapps/packmgr/gui/main.h b/rosapps/packmgr/gui/main.h new file mode 100644 index 00000000000..63cd4cc50f9 --- /dev/null +++ b/rosapps/packmgr/gui/main.h @@ -0,0 +1,62 @@ +/////////////////////////////////////////////////// +// +// main.h +// main.cpp's lumber room :) +/////////////////////////////////////////////////// + +#include +#include +#include +#include +#include + +#include +#include "resource.h" + +/* Some Variables */ + +int selected, splitter_pos = 50; + +pTree tree; +HMENU hPopup; +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); + +/* Toolbar Releated */ + +#define TBSTYLE_FLAT 2048 + +// This is the struct where the toolbar is defined +TBBUTTON Buttons [] = +{ + {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0}, + + {0, 1, TBSTATE_INDETERMINATE, TBSTYLE_BUTTON, 0L, 0}, // No Action + {1, 2, TBSTATE_INDETERMINATE, TBSTYLE_BUTTON, 0L, 0}, // Install + {2, 3, TBSTATE_INDETERMINATE, TBSTYLE_BUTTON, 0L, 0}, // Install from source + {3, 4, TBSTATE_INDETERMINATE, TBSTYLE_BUTTON, 0L, 0}, // Update + {4, 5, TBSTATE_INDETERMINATE, TBSTYLE_BUTTON, 0L, 0}, // Unistall + + {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0}, + {5, 6, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0}, // DoIt (tm) + {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0}, + + {6, 7, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0}, // Help + {7, 8, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0}, // Options + + {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, 0}, +}; diff --git a/rosapps/packmgr/gui/makefile b/rosapps/packmgr/gui/makefile new file mode 100644 index 00000000000..8bd3eb14bd3 --- /dev/null +++ b/rosapps/packmgr/gui/makefile @@ -0,0 +1,24 @@ + +TARGET_NAME = packmgr +TARGET_TYPE = program +TARGET_APPTYPE = windows +PATH_TO_TOP = ../../../reactos + +TARGET_SDKLIBS = kernel32.a user32.a package.a gdi32.a comctl32.a shell32.a + +TARGET_GCCLIBS = stdc++ uuid + +TARGET_OBJECTS = main.o + + +TARGET_CFLAGS = \ + -D__USE_W32API -DWIN32 -D_ROS_ \ + -D_WIN32_IE=0x0501 -D_WIN32_WINNT=0x0501 \ + -DUNICODE -Wall -I../lib + +TARGET_CPPFLAGS = $(TARGET_CFLAGS) +TARGET_RCFLAGS = -D__USE_W32API -DNDEBUG -DWIN32 -D_ROS_ -D__WINDRES__ -DUNICODE + +include $(PATH_TO_TOP)/rules.mak +include $(TOOLS_PATH)/helper.mk +include $(TOOLS_PATH)/depend.mk diff --git a/rosapps/packmgr/gui/packmgr.rc b/rosapps/packmgr/gui/packmgr.rc new file mode 100644 index 00000000000..9b38cf6a771 --- /dev/null +++ b/rosapps/packmgr/gui/packmgr.rc @@ -0,0 +1,18 @@ + +#include +#include "resource.h" + +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Package Manager\0" +#define REACTOS_STR_INTERNAL_NAME "packmgr\0" +#define REACTOS_STR_ORIGINAL_FILENAME "packmgr.exe\0" + +#include + +/* For all langs */ +#include "generic.rc" + +/* Language specific */ + +#include "en.rc" + +/* EOF */ diff --git a/rosapps/packmgr/gui/res/blank.ico b/rosapps/packmgr/gui/res/blank.ico new file mode 100644 index 0000000000000000000000000000000000000000..96c1bdd7ddc14117a37281700931847d017640b8 GIT binary patch literal 11502 zcmeI&Ee?b*5QgE8U=hd_h{}~HG-}U*$A;0 zS;no2`FR8oKmY**5I_I{1Q4hy5c8B+B3PXNd5YHx%BcELybJ*Z5I_I{1Q0*~0R#|0 e009ILKmY**5I_I{1Q0*~fhq#AA25P*ZHEK;7MN-| zE4U9*7;Z#Tl*q~VhLkP;6$Um*k$u!ha^9Qw!B1iIGPERMI^5+jCzi^#QhW6(p zk)PiQcD0K9aV(O&SNqWZ?MIRRCy~!IPvHw_Je7i2FH3Vf@uOVmNXuf95pJmgMLA;#aD{{@BmG!>Ew3!_F z%X@P+*t2{*vZ?lO%4RQfCS@3}aaL-Pe10Hb<>`3qd>+VKXY*12rO3NNm)k!i8hc5O z!=$>-b?KkNew{D5e_09^H5S%&xNzq7P3s)*AW@l@B@6V#dq#g=d>rPin1;m^-JR%~ zh$7mo714H=Yv0}BS|DBht52Nn$AEZ(9A2NnzvP`p784lEcTNqDEMI6JUl zAiQb(iZm-iu5e$`b%mOqEA-&Nf&moNgB~1MFhD2jK@Scr7{HNw(1QaD1_(xW^c)T> z7$5;dfd(8{FhEl3K@Scr7@!bL=)r*n12m`yJvgvnfDY7y9voOOfD`qg2R$qpAQ1IX z9XPOHfZ)`F9voOOKtk$44-PCCpa@*hg98f&xS<~O;J|_bjMRfZRDzzv01ni{NPzz zUAwAUivGF*JL0`nq;Fr`*?VYwX9XDb)^zlaU53(_TBy= z4?2u}>bMW~s@)(7(&#BkXtnKz2!p-uyKb>q>~`Dm|uO{Vcb>gkbf=Bc2h~c-Oe};PDA~{zy4G;vsRCX(`+qc{mE?I=!A{G@w!`!KEL{R zZNl{4|MV`Ibu!pl7jalKk56$m*n6(8iLNids99~g;0{i@{HnMiy{>OYGt9`-6DA^S zjMwC~#NSSTn0fi1f6ooyDPLarqNGmV>+Fi~{X6CRcgpwg6y5><=kJum7Z>jYuiJHv zG<+@8Gtb+dPXXQN!>2&Mkan@#23d5QxbLLx!=}xKhOgS$|8#rnI^R~xW#PeoP53-86J{hqefM}7YWQ?;=Y literal 0 HcmV?d00001 diff --git a/rosapps/packmgr/gui/res/games.ico b/rosapps/packmgr/gui/res/games.ico new file mode 100644 index 0000000000000000000000000000000000000000..92469e7a83b1c564462a729e43a03d7d4e7f3ef9 GIT binary patch literal 11502 zcmeHNJ#W-N5S=Im4br8gK)Nd_uS)Awh>o8CCI2Ev1OEbA{>CXkfQpLdPzu_Bf^ta4 zX6&(FCi^kFcjrV#*kW&I-_E@EJhsmy3egcA)5!_7$D3oKQ;rr3S$}#=^ntPEvRgkT zdd|7ec-fRJcpT9a{vttP$%KwEzxOGYt z-i2J^94K*cW634PZvIw24@^qnNH}(!WT(V$8nZbi;776qz;%fRTU;*awTE{i4lX4= zn2oTt8=~)Dh%Qz{Z=10u`g$pNb8a_0)||6qY|VR@JYVv<*=wG&1&=cx{d2bBXVN{g z?M#Ue*Ma5|?sDLw<`glx{L4v34oe_50+44)h;t?sek_9$4tY{S*n*!ve~{dk2r|b` zVTAnBcK|mcE9XDvRlzdn zAt|n_E8hG0u_`v4yP0ig&A5KGoo$P9zAc1X*ET<=EP1@VWz|?_< z?11s!+{uRXRPR))lSkzTZ?~b|LEI&MviY%gqT_r9$;4&C5`k=G5^4`R&MZgTAbzv~ zKZaH^fEhb5czpF3Vvu0Vwt-#b`$0_I$NgF#fubGwg+P4W7=jWbux()1WVrnwY|M$^ z28rH+Xe`jler$WtyMApDiP-=itOBSNbsu6l3he;uI`(6Agw>pht1~$)K-D%vw4a z+x1BsNU(XZ8}y(-WEugB$}ZG3VifvYS~?i}B|$_x(Qz<22_E7^$h8L@C#8c4WAno% z9ZNymN$~K_I1=pYkYj9q4mp>p_P^>tf9Ge+pX++vJiqa@6>OR7tn z6J1den=9gc-j{h<)GOvGm%`uA&1Go#<#HS_v(NT>hkdtv-CVv9J@(P+tNE_K&gY+Z Wb&K=)w)uK)`_lEJ?&sEc-1lElhUy3a literal 0 HcmV?d00001 diff --git a/rosapps/packmgr/gui/res/graphics.ico b/rosapps/packmgr/gui/res/graphics.ico new file mode 100644 index 0000000000000000000000000000000000000000..02327802f36750e780f42fddc21ae0ca9cf5f651 GIT binary patch literal 9062 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�-OyqU%|WrW9N*QGnUSr19KU0Sk=7wL?zW*SXkKF z>aSETUAxx7#l=h`nVFf3gF{&5>&9m_s=s!vsYY{Lr^_!Wc=F^)VNp?WY^=uA^jTfR zXfzidKFoad=&@G&2uoHL(5>9OJWWiD@i3(Gn$>r4iA_tpedkX4-MdX%w@z)1H8t7E zDfs^V2ab*|Va9{Hk(hWhFfcSBA=v=Y;fCad(9lb_ZpGfXVKluptMB5Hn3NP46_t?8 zmY|q?61sP9N^GpD>Nm&4#>U0RhdMbWI5|aCHm8IHr_j(n*RDCLW~rw2HCL|eb90Ld zRZQwaISCDoiVEDiHCm&om?KNe3l}f`86JLV@7`cTrHZ5Az`%$jMj2@GbFn?3@>ch8<9d-u*?vc&D&xx?qrYow<(>iF^Be*E#ou3a0} zuitaz$PwulY&;Gf+IRA#^R{hE)~(xh;>0hfPT4p(U_>>o?{e_q#vgt-w0rlDhY$Px z^iyD9AUZh`7#P2A-@ZeK4j(wMCKTLPOqckZ-lpDMO^&6+R2`s%B3|ze9PXeFy}#ox;tYt z2*YF>GQ{29-d1iOBkI$qud{Q%_uhL~GH3-d>}g8Fd#WC6*eEO|4qB>(qgM%(`B^`ZhKiTk%vYSC!6c zS|2xsnVO3D!LrI{w3-zYCeQY zcht1I=hv^)^nZ5p{EnV~wc4IRCkjSUO)AQ~qM#O^#V(3ApWk)0SH->Rga487s0V;! znF|$ksDTkxNKwIy3Tjlaqtz0mqWx;;!KhGF#sL^Y!JP{FR4}N5L=`-$fl5`_R6(d# z&Q|nTby`p& zu3{uuWTM!>6&vVcg)y!~8iPH)$BRrI3-%b?vP2*Y4%vuCmOFj%$0H_3X1N8?ZQ!~q z(cK`u!Fa1kZ`MnL_ZHN*!hQ<^T;ae44X$Rw(Yu%;F%o>HvB<2rff!eF;}!I{V93=Z zxy+Lbs$5~q6~bI_=7Kg?Gw1&+#sf-Uu=;}77ul>48NM>$An?#q+``bOBgom6l4VRiV`qaxJ0Q5~3}k+cHSEgnFy8 zfJ;_#$ucgrl1qM47|aVe9x*E57+7SLnGl*8v}TIj%%C_^L}yiWXKMACL4YP}(1Z+4 ztwdALj~I{q1Z7p45T+TlX^K3}pimPcwdd*7BwbsDa*Z`>LbmpNiIzMVY+sP^sQ*Y1 z+6ZA?b=o>vPX~FOyi}FfRV{%!uR?QYB)gO6L4HQnZpB2&LOh|xGsy9TA`fyrS(I0u zE>9@+WPzU0=&5CT=&RZ>s0&}T@nCFXNDvYVEuoMT8We>>R45-nSExt}p*NJ(g+gFx zq%oAcP|w3(9*a@IbweU184ytYQKPmiY!w`484<y^3E|ey8&LmAx`Q#`C5>Q!$^){3?6>8A-_d-*OcNZ2$lO literal 0 HcmV?d00001 diff --git a/rosapps/packmgr/gui/res/install.ico b/rosapps/packmgr/gui/res/install.ico new file mode 100644 index 0000000000000000000000000000000000000000..3a44f717abee08af34c104d8e58e781a42bb4103 GIT binary patch literal 18902 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 T(f)g!65Yh(lkwlr6Q}%dG!|mK literal 0 HcmV?d00001 diff --git a/rosapps/packmgr/gui/res/installed.ico b/rosapps/packmgr/gui/res/installed.ico new file mode 100644 index 0000000000000000000000000000000000000000..a50f549659aa85fb22d5ea9c3102385c4fb36d79 GIT binary patch literal 21630 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 literal 0 HcmV?d00001 diff --git a/rosapps/packmgr/gui/res/others.ico b/rosapps/packmgr/gui/res/others.ico new file mode 100644 index 0000000000000000000000000000000000000000..82eba8bb678ad51f3cf8c1be1577a8e860d021a7 GIT binary patch literal 21630 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 literal 0 HcmV?d00001 diff --git a/rosapps/packmgr/gui/res/uninstall.ico b/rosapps/packmgr/gui/res/uninstall.ico new file mode 100644 index 0000000000000000000000000000000000000000..962bc6de28115332b8248e5f2434e06c6295f715 GIT binary patch literal 21630 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 Kr~SWNr~Dt(I@h%T literal 0 HcmV?d00001 diff --git a/rosapps/packmgr/gui/resource.h b/rosapps/packmgr/gui/resource.h new file mode 100644 index 00000000000..90aa5f713cf --- /dev/null +++ b/rosapps/packmgr/gui/resource.h @@ -0,0 +1,14 @@ +#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 diff --git a/rosapps/packmgr/help.txt b/rosapps/packmgr/help.txt new file mode 100644 index 00000000000..c6de41b6997 --- /dev/null +++ b/rosapps/packmgr/help.txt @@ -0,0 +1,9 @@ +Welcome to ReactOS's Package Manager ! + +WARNING: This is still pre-alfa software you can't do much with it yet. + +This is the online help. You can show it at any time by clicking on the the Questionmark Icon above. + +You can use this package manager like this: click on the +You can also use the Buttons [ctrl] + [0] to [4] to set the action. + diff --git a/rosapps/packmgr/lib/download.cpp b/rosapps/packmgr/lib/download.cpp new file mode 100644 index 00000000000..6528ae5da0a --- /dev/null +++ b/rosapps/packmgr/lib/download.cpp @@ -0,0 +1,117 @@ +//////////////////////////////////////////////////////// +// +// 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 + +// Server there all the files lie +const char* tree_server = "http://svn.reactos.com/viewcvs/*checkout*/trunk/rosapps/packmgr/tree/"; + +HRESULT WINAPI URLDownloadToFileA( + LPUNKNOWN pCaller, + LPCSTR szURL, + LPCSTR szFileName, + DWORD dwReserved, + LPBINDSTATUSCALLBACK lpfnCB +); + + +// Download a file +char* PML_Download (const char* name, const char* local_name = "packmgr.txt", const char* server = tree_server, BOOL totemp = TRUE) +{ + char url [MAX_PATH]; + static char path [MAX_PATH]; + + // get temp dir + if(totemp) + GetTempPathA (200, path); + + // create the local file name + if(local_name) + strcat(path, local_name); + else + strcat(path, "tmp.tmp"); + + // get the url + if(server) strcpy(url, server); + strcat(url, name); + + // make sure there is no old file + DeleteFileA (path); + + // download the file + if(URLDownloadToFileA (NULL, url, path, 0, NULL) != S_OK) + { + Log("! ERROR: Unable to download "); + LogAdd(url); + + return NULL; + } + + return path; +} + +// Download and prozess a xml file +int PML_XmlDownload (const char* url, void* usrdata, XML_StartElementHandler start, + XML_EndElementHandler end, XML_CharacterDataHandler text) +{ + char buffer[255]; + int done = 0; + + // logging + Log("* prozess the xml file: "); + LogAdd(url); + + // download the file + char* filename = PML_Download(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"); + 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; +} + diff --git a/rosapps/packmgr/lib/en.rc b/rosapps/packmgr/lib/en.rc new file mode 100644 index 00000000000..386b5bbbaa3 --- /dev/null +++ b/rosapps/packmgr/lib/en.rc @@ -0,0 +1,19 @@ + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +/* String Tables */ +STRINGTABLE DISCARDABLE +BEGIN + IDS_LOAD "Loading ..." + ERR_OK "Operation done." + ERR_PACK "Not all packages could be installed\n\nPlease have a look at the log file for details." + ERR_GENERIC "An error occured. \nFor more information please have a look at the log file." + ERR_DOWNL "A needed file could not be downloaded!\nFor more information please have a look at the log file." + ERR_FILE "Error while Script Execution.\nFile could not be opened." + + ERR_SYNATX "Error while Script Execution.\nWrong Synatx." + ERR_CALL "Error while Script Execution.\nCould not find function." + ERR_PARAMETER "Error while Script Execution.\nWrong Parameter(s)." +END + +/* EOF */ diff --git a/rosapps/packmgr/lib/error.h b/rosapps/packmgr/lib/error.h new file mode 100644 index 00000000000..847c6999a9d --- /dev/null +++ b/rosapps/packmgr/lib/error.h @@ -0,0 +1,16 @@ +// 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 + +// Script +#define ERR_SYNATX 0x011 +#define ERR_CALL 0x012 +#define ERR_PARAMETER 0x013 +#define ERR_FILE 0x014 + +#define IDS_LOAD 0x254 +#define NOTFOUND -1 diff --git a/rosapps/packmgr/lib/expat.h b/rosapps/packmgr/lib/expat.h new file mode 100644 index 00000000000..c6d86a21d20 --- /dev/null +++ b/rosapps/packmgr/lib/expat.h @@ -0,0 +1,1081 @@ +/* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd + See the file COPYING for copying permission. +*/ + +#ifndef XmlParse_INCLUDED +#define XmlParse_INCLUDED 1 + +#ifdef __VMS +/* 0 1 2 3 0 1 2 3 + 1234567890123456789012345678901 1234567890123456789012345678901 */ +#define XML_SetProcessingInstructionHandler XML_SetProcessingInstrHandler +#define XML_SetUnparsedEntityDeclHandler XML_SetUnparsedEntDeclHandler +#define XML_SetStartNamespaceDeclHandler XML_SetStartNamespcDeclHandler +#define XML_SetExternalEntityRefHandlerArg XML_SetExternalEntRefHandlerArg +#endif + +#include + +#if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__) +#define XML_USE_MSC_EXTENSIONS 1 +#endif + +/* Expat tries very hard to make the API boundary very specifically + defined. There are two macros defined to control this boundary; + each of these can be defined before including this header to + achieve some different behavior, but doing so it not recommended or + tested frequently. + + XMLCALL - The calling convention to use for all calls across the + "library boundary." This will default to cdecl, and + try really hard to tell the compiler that's what we + want. + + XMLIMPORT - Whatever magic is needed to note that a function is + to be imported from a dynamically loaded library + (.dll, .so, or .sl, depending on your platform). + + The XMLCALL macro was added in Expat 1.95.7. The only one which is + expected to be directly useful in client code is XMLCALL. + + Note that on at least some Unix versions, the Expat library must be + compiled with the cdecl calling convention as the default since + system headers may assume the cdecl convention. +*/ +#ifndef XMLCALL +#if defined(XML_USE_MSC_EXTENSIONS) +#define XMLCALL __cdecl +#elif defined(__GNUC__) && defined(__i386) +//MF#define XMLCALL __attribute__((cdecl)) +#define XMLCALL//MF +#else +/* For any platform which uses this definition and supports more than + one calling convention, we need to extend this definition to + declare the convention used on that platform, if it's possible to + do so. + + If this is the case for your platform, please file a bug report + with information on how to identify your platform via the C + pre-processor and how to specify the same calling convention as the + platform's malloc() implementation. +*/ +#define XMLCALL +#endif +#endif /* not defined XMLCALL */ + + +#if !defined(XML_STATIC) && !defined(XMLIMPORT) +#ifndef XML_BUILDING_EXPAT +/* using Expat from an application */ + +#ifdef XML_USE_MSC_EXTENSIONS +#define XMLIMPORT __declspec(dllimport) +#endif + +#endif +#endif /* not defined XML_STATIC */ + +/* If we didn't define it above, define it away: */ +#ifndef XMLIMPORT +#define XMLIMPORT +#endif + + +#define XMLPARSEAPI(type) XMLIMPORT type XMLCALL + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef XML_UNICODE_WCHAR_T +#define XML_UNICODE +#endif + +struct XML_ParserStruct; +typedef struct XML_ParserStruct *XML_Parser; + +#ifdef XML_UNICODE /* Information is UTF-16 encoded. */ +#ifdef XML_UNICODE_WCHAR_T +typedef wchar_t XML_Char; +typedef wchar_t XML_LChar; +#else +typedef unsigned short XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE_WCHAR_T */ +#else /* Information is UTF-8 encoded. */ +typedef char XML_Char; +typedef char XML_LChar; +#endif /* XML_UNICODE */ + +/* Should this be defined using stdbool.h when C99 is available? */ +typedef unsigned char XML_Bool; +#define XML_TRUE ((XML_Bool) 1) +#define XML_FALSE ((XML_Bool) 0) + +/* The XML_Status enum gives the possible return values for several + API functions. The preprocessor #defines are included so this + stanza can be added to code that still needs to support older + versions of Expat 1.95.x: + + #ifndef XML_STATUS_OK + #define XML_STATUS_OK 1 + #define XML_STATUS_ERROR 0 + #endif + + Otherwise, the #define hackery is quite ugly and would have been + dropped. +*/ +enum XML_Status { + XML_STATUS_ERROR = 0, +#define XML_STATUS_ERROR XML_STATUS_ERROR + XML_STATUS_OK = 1, +#define XML_STATUS_OK XML_STATUS_OK + XML_STATUS_SUSPENDED = 2, +#define XML_STATUS_SUSPENDED XML_STATUS_SUSPENDED +}; + +enum XML_Error { + XML_ERROR_NONE, + XML_ERROR_NO_MEMORY, + XML_ERROR_SYNTAX, + XML_ERROR_NO_ELEMENTS, + XML_ERROR_INVALID_TOKEN, + XML_ERROR_UNCLOSED_TOKEN, + XML_ERROR_PARTIAL_CHAR, + XML_ERROR_TAG_MISMATCH, + XML_ERROR_DUPLICATE_ATTRIBUTE, + XML_ERROR_JUNK_AFTER_DOC_ELEMENT, + XML_ERROR_PARAM_ENTITY_REF, + XML_ERROR_UNDEFINED_ENTITY, + XML_ERROR_RECURSIVE_ENTITY_REF, + XML_ERROR_ASYNC_ENTITY, + XML_ERROR_BAD_CHAR_REF, + XML_ERROR_BINARY_ENTITY_REF, + XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF, + XML_ERROR_MISPLACED_XML_PI, + XML_ERROR_UNKNOWN_ENCODING, + XML_ERROR_INCORRECT_ENCODING, + XML_ERROR_UNCLOSED_CDATA_SECTION, + XML_ERROR_EXTERNAL_ENTITY_HANDLING, + XML_ERROR_NOT_STANDALONE, + XML_ERROR_UNEXPECTED_STATE, + XML_ERROR_ENTITY_DECLARED_IN_PE, + XML_ERROR_FEATURE_REQUIRES_XML_DTD, + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING, + XML_ERROR_UNBOUND_PREFIX, + XML_ERROR_SUSPENDED, + XML_ERROR_NOT_SUSPENDED, + XML_ERROR_ABORTED, + XML_ERROR_FINISHED, + XML_ERROR_SUSPEND_PE +}; + +enum XML_Content_Type { + XML_CTYPE_EMPTY = 1, + XML_CTYPE_ANY, + XML_CTYPE_MIXED, + XML_CTYPE_NAME, + XML_CTYPE_CHOICE, + XML_CTYPE_SEQ +}; + +enum XML_Content_Quant { + XML_CQUANT_NONE, + XML_CQUANT_OPT, + XML_CQUANT_REP, + XML_CQUANT_PLUS +}; + +/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be + XML_CQUANT_NONE, and the other fields will be zero or NULL. + If type == XML_CTYPE_MIXED, then quant will be NONE or REP and + numchildren will contain number of elements that may be mixed in + and children point to an array of XML_Content cells that will be + all of XML_CTYPE_NAME type with no quantification. + + If type == XML_CTYPE_NAME, then the name points to the name, and + the numchildren field will be zero and children will be NULL. The + quant fields indicates any quantifiers placed on the name. + + CHOICE and SEQ will have name NULL, the number of children in + numchildren and children will point, recursively, to an array + of XML_Content cells. + + The EMPTY, ANY, and MIXED types will only occur at top level. +*/ + +typedef struct XML_cp XML_Content; + +struct XML_cp { + enum XML_Content_Type type; + enum XML_Content_Quant quant; + XML_Char * name; + unsigned int numchildren; + XML_Content * children; +}; + + +/* This is called for an element declaration. See above for + description of the model argument. It's the caller's responsibility + to free model when finished with it. +*/ +typedef void (XMLCALL *XML_ElementDeclHandler) (void *userData, + const XML_Char *name, + XML_Content *model); + +XMLPARSEAPI(void) +XML_SetElementDeclHandler(XML_Parser parser, + XML_ElementDeclHandler eldecl); + +/* The Attlist declaration handler is called for *each* attribute. So + a single Attlist declaration with multiple attributes declared will + generate multiple calls to this handler. The "default" parameter + may be NULL in the case of the "#IMPLIED" or "#REQUIRED" + keyword. The "isrequired" parameter will be true and the default + value will be NULL in the case of "#REQUIRED". If "isrequired" is + true and default is non-NULL, then this is a "#FIXED" default. +*/ +typedef void (XMLCALL *XML_AttlistDeclHandler) ( + void *userData, + const XML_Char *elname, + const XML_Char *attname, + const XML_Char *att_type, + const XML_Char *dflt, + int isrequired); + +XMLPARSEAPI(void) +XML_SetAttlistDeclHandler(XML_Parser parser, + XML_AttlistDeclHandler attdecl); + +/* The XML declaration handler is called for *both* XML declarations + and text declarations. The way to distinguish is that the version + parameter will be NULL for text declarations. The encoding + parameter may be NULL for XML declarations. The standalone + parameter will be -1, 0, or 1 indicating respectively that there + was no standalone parameter in the declaration, that it was given + as no, or that it was given as yes. +*/ +typedef void (XMLCALL *XML_XmlDeclHandler) (void *userData, + const XML_Char *version, + const XML_Char *encoding, + int standalone); + +XMLPARSEAPI(void) +XML_SetXmlDeclHandler(XML_Parser parser, + XML_XmlDeclHandler xmldecl); + + +typedef struct { + void *(XMLCALL *malloc_fcn)(size_t size); + void *(XMLCALL *realloc_fcn)(void *ptr, size_t size); + void (XMLCALL *free_fcn)(void *ptr); +} XML_Memory_Handling_Suite; + +/* Constructs a new parser; encoding is the encoding specified by the + external protocol or NULL if there is none specified. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate(const XML_Char *encoding); + +/* Constructs a new parser and namespace processor. Element type + names and attribute names that belong to a namespace will be + expanded; unprefixed attribute names are never expanded; unprefixed + element type names are expanded only if there is a default + namespace. The expanded name is the concatenation of the namespace + URI, the namespace separator character, and the local part of the + name. If the namespace separator is '\0' then the namespace URI + and the local part will be concatenated without any separator. + When a namespace is not declared, the name and prefix will be + passed through without expansion. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator); + + +/* Constructs a new parser using the memory management suite referred to + by memsuite. If memsuite is NULL, then use the standard library memory + suite. If namespaceSeparator is non-NULL it creates a parser with + namespace processing as described above. The character pointed at + will serve as the namespace separator. + + All further memory operations used for the created parser will come from + the given suite. +*/ +XMLPARSEAPI(XML_Parser) +XML_ParserCreate_MM(const XML_Char *encoding, + const XML_Memory_Handling_Suite *memsuite, + const XML_Char *namespaceSeparator); + +/* Prepare a parser object to be re-used. This is particularly + valuable when memory allocation overhead is disproportionatly high, + such as when a large number of small documnents need to be parsed. + All handlers are cleared from the parser, except for the + unknownEncodingHandler. The parser's external state is re-initialized + except for the values of ns and ns_triplets. + + Added in Expat 1.95.3. +*/ +XMLPARSEAPI(XML_Bool) +XML_ParserReset(XML_Parser parser, const XML_Char *encoding); + +/* atts is array of name/value pairs, terminated by 0; + names and values are 0 terminated. +*/ +typedef void (XMLCALL *XML_StartElementHandler) (void *userData, + const XML_Char *name, + const XML_Char **atts); + +typedef void (XMLCALL *XML_EndElementHandler) (void *userData, + const XML_Char *name); + + +/* s is not 0 terminated. */ +typedef void (XMLCALL *XML_CharacterDataHandler) (void *userData, + const XML_Char *s, + int len); + +/* target and data are 0 terminated */ +typedef void (XMLCALL *XML_ProcessingInstructionHandler) ( + void *userData, + const XML_Char *target, + const XML_Char *data); + +/* data is 0 terminated */ +typedef void (XMLCALL *XML_CommentHandler) (void *userData, + const XML_Char *data); + +typedef void (XMLCALL *XML_StartCdataSectionHandler) (void *userData); +typedef void (XMLCALL *XML_EndCdataSectionHandler) (void *userData); + +/* This is called for any characters in the XML document for which + there is no applicable handler. This includes both characters that + are part of markup which is of a kind that is not reported + (comments, markup declarations), or characters that are part of a + construct which could be reported but for which no handler has been + supplied. The characters are passed exactly as they were in the XML + document except that they will be encoded in UTF-8 or UTF-16. + Line boundaries are not normalized. Note that a byte order mark + character is not passed to the default handler. There are no + guarantees about how characters are divided between calls to the + default handler: for example, a comment might be split between + multiple calls. +*/ +typedef void (XMLCALL *XML_DefaultHandler) (void *userData, + const XML_Char *s, + int len); + +/* This is called for the start of the DOCTYPE declaration, before + any DTD or internal subset is parsed. +*/ +typedef void (XMLCALL *XML_StartDoctypeDeclHandler) ( + void *userData, + const XML_Char *doctypeName, + const XML_Char *sysid, + const XML_Char *pubid, + int has_internal_subset); + +/* This is called for the start of the DOCTYPE declaration when the + closing > is encountered, but after processing any external + subset. +*/ +typedef void (XMLCALL *XML_EndDoctypeDeclHandler)(void *userData); + +/* This is called for entity declarations. The is_parameter_entity + argument will be non-zero if the entity is a parameter entity, zero + otherwise. + + For internal entities (), value will + be non-NULL and systemId, publicID, and notationName will be NULL. + The value string is NOT nul-terminated; the length is provided in + the value_length argument. Since it is legal to have zero-length + values, do not use this argument to test for internal entities. + + For external entities, value will be NULL and systemId will be + non-NULL. The publicId argument will be NULL unless a public + identifier was provided. The notationName argument will have a + non-NULL value only for unparsed entity declarations. + + Note that is_parameter_entity can't be changed to XML_Bool, since + that would break binary compatibility. +*/ +typedef void (XMLCALL *XML_EntityDeclHandler) ( + void *userData, + const XML_Char *entityName, + int is_parameter_entity, + const XML_Char *value, + int value_length, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + +XMLPARSEAPI(void) +XML_SetEntityDeclHandler(XML_Parser parser, + XML_EntityDeclHandler handler); + +/* OBSOLETE -- OBSOLETE -- OBSOLETE + This handler has been superceded by the EntityDeclHandler above. + It is provided here for backward compatibility. + + This is called for a declaration of an unparsed (NDATA) entity. + The base argument is whatever was set by XML_SetBase. The + entityName, systemId and notationName arguments will never be + NULL. The other arguments may be. +*/ +typedef void (XMLCALL *XML_UnparsedEntityDeclHandler) ( + void *userData, + const XML_Char *entityName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId, + const XML_Char *notationName); + +/* This is called for a declaration of notation. The base argument is + whatever was set by XML_SetBase. The notationName will never be + NULL. The other arguments can be. +*/ +typedef void (XMLCALL *XML_NotationDeclHandler) ( + void *userData, + const XML_Char *notationName, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* When namespace processing is enabled, these are called once for + each namespace declaration. The call to the start and end element + handlers occur between the calls to the start and end namespace + declaration handlers. For an xmlns attribute, prefix will be + NULL. For an xmlns="" attribute, uri will be NULL. +*/ +typedef void (XMLCALL *XML_StartNamespaceDeclHandler) ( + void *userData, + const XML_Char *prefix, + const XML_Char *uri); + +typedef void (XMLCALL *XML_EndNamespaceDeclHandler) ( + void *userData, + const XML_Char *prefix); + +/* This is called if the document is not standalone, that is, it has an + external subset or a reference to a parameter entity, but does not + have standalone="yes". If this handler returns XML_STATUS_ERROR, + then processing will not continue, and the parser will return a + XML_ERROR_NOT_STANDALONE error. + If parameter entity parsing is enabled, then in addition to the + conditions above this handler will only be called if the referenced + entity was actually read. +*/ +typedef int (XMLCALL *XML_NotStandaloneHandler) (void *userData); + +/* This is called for a reference to an external parsed general + entity. The referenced entity is not automatically parsed. The + application can parse it immediately or later using + XML_ExternalEntityParserCreate. + + The parser argument is the parser parsing the entity containing the + reference; it can be passed as the parser argument to + XML_ExternalEntityParserCreate. The systemId argument is the + system identifier as specified in the entity declaration; it will + not be NULL. + + The base argument is the system identifier that should be used as + the base for resolving systemId if systemId was relative; this is + set by XML_SetBase; it may be NULL. + + The publicId argument is the public identifier as specified in the + entity declaration, or NULL if none was specified; the whitespace + in the public identifier will have been normalized as required by + the XML spec. + + The context argument specifies the parsing context in the format + expected by the context argument to XML_ExternalEntityParserCreate; + context is valid only until the handler returns, so if the + referenced entity is to be parsed later, it must be copied. + context is NULL only when the entity is a parameter entity. + + The handler should return XML_STATUS_ERROR if processing should not + continue because of a fatal error in the handling of the external + entity. In this case the calling parser will return an + XML_ERROR_EXTERNAL_ENTITY_HANDLING error. + + Note that unlike other handlers the first argument is the parser, + not userData. +*/ +typedef int (XMLCALL *XML_ExternalEntityRefHandler) ( + XML_Parser parser, + const XML_Char *context, + const XML_Char *base, + const XML_Char *systemId, + const XML_Char *publicId); + +/* This is called in two situations: + 1) An entity reference is encountered for which no declaration + has been read *and* this is not an error. + 2) An internal entity reference is read, but not expanded, because + XML_SetDefaultHandler has been called. + Note: skipped parameter entities in declarations and skipped general + entities in attribute values cannot be reported, because + the event would be out of sync with the reporting of the + declarations or attribute values +*/ +typedef void (XMLCALL *XML_SkippedEntityHandler) ( + void *userData, + const XML_Char *entityName, + int is_parameter_entity); + +/* This structure is filled in by the XML_UnknownEncodingHandler to + provide information to the parser about encodings that are unknown + to the parser. + + The map[b] member gives information about byte sequences whose + first byte is b. + + If map[b] is c where c is >= 0, then b by itself encodes the + Unicode scalar value c. + + If map[b] is -1, then the byte sequence is malformed. + + If map[b] is -n, where n >= 2, then b is the first byte of an + n-byte sequence that encodes a single Unicode scalar value. + + The data member will be passed as the first argument to the convert + function. + + The convert function is used to convert multibyte sequences; s will + point to a n-byte sequence where map[(unsigned char)*s] == -n. The + convert function must return the Unicode scalar value represented + by this byte sequence or -1 if the byte sequence is malformed. + + The convert function may be NULL if the encoding is a single-byte + encoding, that is if map[b] >= -1 for all bytes b. + + When the parser is finished with the encoding, then if release is + not NULL, it will call release passing it the data member; once + release has been called, the convert function will not be called + again. + + Expat places certain restrictions on the encodings that are supported + using this mechanism. + + 1. Every ASCII character that can appear in a well-formed XML document, + other than the characters + + $@\^`{}~ + + must be represented by a single byte, and that byte must be the + same byte that represents that character in ASCII. + + 2. No character may require more than 4 bytes to encode. + + 3. All characters encoded must have Unicode scalar values <= + 0xFFFF, (i.e., characters that would be encoded by surrogates in + UTF-16 are not allowed). Note that this restriction doesn't + apply to the built-in support for UTF-8 and UTF-16. + + 4. No Unicode character may be encoded by more than one distinct + sequence of bytes. +*/ +typedef struct { + int map[256]; + void *data; + int (XMLCALL *convert)(void *data, const char *s); + void (XMLCALL *release)(void *data); +} XML_Encoding; + +/* This is called for an encoding that is unknown to the parser. + + The encodingHandlerData argument is that which was passed as the + second argument to XML_SetUnknownEncodingHandler. + + The name argument gives the name of the encoding as specified in + the encoding declaration. + + If the callback can provide information about the encoding, it must + fill in the XML_Encoding structure, and return XML_STATUS_OK. + Otherwise it must return XML_STATUS_ERROR. + + If info does not describe a suitable encoding, then the parser will + return an XML_UNKNOWN_ENCODING error. +*/ +typedef int (XMLCALL *XML_UnknownEncodingHandler) ( + void *encodingHandlerData, + const XML_Char *name, + XML_Encoding *info); + +XMLPARSEAPI(void) +XML_SetElementHandler(XML_Parser parser, + XML_StartElementHandler start, + XML_EndElementHandler end); + +XMLPARSEAPI(void) +XML_SetStartElementHandler(XML_Parser parser, + XML_StartElementHandler handler); + +XMLPARSEAPI(void) +XML_SetEndElementHandler(XML_Parser parser, + XML_EndElementHandler handler); + +XMLPARSEAPI(void) +XML_SetCharacterDataHandler(XML_Parser parser, + XML_CharacterDataHandler handler); + +XMLPARSEAPI(void) +XML_SetProcessingInstructionHandler(XML_Parser parser, + XML_ProcessingInstructionHandler handler); +XMLPARSEAPI(void) +XML_SetCommentHandler(XML_Parser parser, + XML_CommentHandler handler); + +XMLPARSEAPI(void) +XML_SetCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start, + XML_EndCdataSectionHandler end); + +XMLPARSEAPI(void) +XML_SetStartCdataSectionHandler(XML_Parser parser, + XML_StartCdataSectionHandler start); + +XMLPARSEAPI(void) +XML_SetEndCdataSectionHandler(XML_Parser parser, + XML_EndCdataSectionHandler end); + +/* This sets the default handler and also inhibits expansion of + internal entities. These entity references will be passed to the + default handler, or to the skipped entity handler, if one is set. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandler(XML_Parser parser, + XML_DefaultHandler handler); + +/* This sets the default handler but does not inhibit expansion of + internal entities. The entity reference will not be passed to the + default handler. +*/ +XMLPARSEAPI(void) +XML_SetDefaultHandlerExpand(XML_Parser parser, + XML_DefaultHandler handler); + +XMLPARSEAPI(void) +XML_SetDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start, + XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartDoctypeDeclHandler(XML_Parser parser, + XML_StartDoctypeDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndDoctypeDeclHandler(XML_Parser parser, + XML_EndDoctypeDeclHandler end); + +XMLPARSEAPI(void) +XML_SetUnparsedEntityDeclHandler(XML_Parser parser, + XML_UnparsedEntityDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNotationDeclHandler(XML_Parser parser, + XML_NotationDeclHandler handler); + +XMLPARSEAPI(void) +XML_SetNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetStartNamespaceDeclHandler(XML_Parser parser, + XML_StartNamespaceDeclHandler start); + +XMLPARSEAPI(void) +XML_SetEndNamespaceDeclHandler(XML_Parser parser, + XML_EndNamespaceDeclHandler end); + +XMLPARSEAPI(void) +XML_SetNotStandaloneHandler(XML_Parser parser, + XML_NotStandaloneHandler handler); + +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandler(XML_Parser parser, + XML_ExternalEntityRefHandler handler); + +/* If a non-NULL value for arg is specified here, then it will be + passed as the first argument to the external entity ref handler + instead of the parser object. +*/ +XMLPARSEAPI(void) +XML_SetExternalEntityRefHandlerArg(XML_Parser parser, + void *arg); + +XMLPARSEAPI(void) +XML_SetSkippedEntityHandler(XML_Parser parser, + XML_SkippedEntityHandler handler); + +XMLPARSEAPI(void) +XML_SetUnknownEncodingHandler(XML_Parser parser, + XML_UnknownEncodingHandler handler, + void *encodingHandlerData); + +/* This can be called within a handler for a start element, end + element, processing instruction or character data. It causes the + corresponding markup to be passed to the default handler. +*/ +XMLPARSEAPI(void) +XML_DefaultCurrent(XML_Parser parser); + +/* If do_nst is non-zero, and namespace processing is in effect, and + a name has a prefix (i.e. an explicit namespace qualifier) then + that name is returned as a triplet in a single string separated by + the separator character specified when the parser was created: URI + + sep + local_name + sep + prefix. + + If do_nst is zero, then namespace information is returned in the + default manner (URI + sep + local_name) whether or not the name + has a prefix. + + Note: Calling XML_SetReturnNSTriplet after XML_Parse or + XML_ParseBuffer has no effect. +*/ + +XMLPARSEAPI(void) +XML_SetReturnNSTriplet(XML_Parser parser, int do_nst); + +/* This value is passed as the userData argument to callbacks. */ +XMLPARSEAPI(void) +XML_SetUserData(XML_Parser parser, void *userData); + +/* Returns the last value set by XML_SetUserData or NULL. */ +#define XML_GetUserData(parser) (*(void **)(parser)) + +/* This is equivalent to supplying an encoding argument to + XML_ParserCreate. On success XML_SetEncoding returns non-zero, + zero otherwise. + Note: Calling XML_SetEncoding after XML_Parse or XML_ParseBuffer + has no effect and returns XML_STATUS_ERROR. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetEncoding(XML_Parser parser, const XML_Char *encoding); + +/* If this function is called, then the parser will be passed as the + first argument to callbacks instead of userData. The userData will + still be accessible using XML_GetUserData. +*/ +XMLPARSEAPI(void) +XML_UseParserAsHandlerArg(XML_Parser parser); + +/* If useDTD == XML_TRUE is passed to this function, then the parser + will assume that there is an external subset, even if none is + specified in the document. In such a case the parser will call the + externalEntityRefHandler with a value of NULL for the systemId + argument (the publicId and context arguments will be NULL as well). + Note: If this function is called, then this must be done before + the first call to XML_Parse or XML_ParseBuffer, since it will + have no effect after that. Returns + XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING. + Note: If the document does not have a DOCTYPE declaration at all, + then startDoctypeDeclHandler and endDoctypeDeclHandler will not + be called, despite an external subset being parsed. + Note: If XML_DTD is not defined when Expat is compiled, returns + XML_ERROR_FEATURE_REQUIRES_XML_DTD. +*/ +XMLPARSEAPI(enum XML_Error) +XML_UseForeignDTD(XML_Parser parser, XML_Bool useDTD); + + +/* Sets the base to be used for resolving relative URIs in system + identifiers in declarations. Resolving relative identifiers is + left to the application: this value will be passed through as the + base argument to the XML_ExternalEntityRefHandler, + XML_NotationDeclHandler and XML_UnparsedEntityDeclHandler. The base + argument will be copied. Returns XML_STATUS_ERROR if out of memory, + XML_STATUS_OK otherwise. +*/ +XMLPARSEAPI(enum XML_Status) +XML_SetBase(XML_Parser parser, const XML_Char *base); + +XMLPARSEAPI(const XML_Char *) +XML_GetBase(XML_Parser parser); + +/* Returns the number of the attribute/value pairs passed in last call + to the XML_StartElementHandler that were specified in the start-tag + rather than defaulted. Each attribute/value pair counts as 2; thus + this correspondds to an index into the atts array passed to the + XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetSpecifiedAttributeCount(XML_Parser parser); + +/* Returns the index of the ID attribute passed in the last call to + XML_StartElementHandler, or -1 if there is no ID attribute. Each + attribute/value pair counts as 2; thus this correspondds to an + index into the atts array passed to the XML_StartElementHandler. +*/ +XMLPARSEAPI(int) +XML_GetIdAttributeIndex(XML_Parser parser); + +/* Parses some input. Returns XML_STATUS_ERROR if a fatal error is + detected. The last call to XML_Parse must have isFinal true; len + may be zero for this call (or any other). + + Though the return values for these functions has always been + described as a Boolean value, the implementation, at least for the + 1.95.x series, has always returned exactly one of the XML_Status + values. +*/ +XMLPARSEAPI(enum XML_Status) +XML_Parse(XML_Parser parser, const char *s, int len, int isFinal); + +XMLPARSEAPI(void *) +XML_GetBuffer(XML_Parser parser, int len); + +XMLPARSEAPI(enum XML_Status) +XML_ParseBuffer(XML_Parser parser, int len, int isFinal); + +/* Stops parsing, causing XML_Parse() or XML_ParseBuffer() to return. + Must be called from within a call-back handler, except when aborting + (resumable = 0) an already suspended parser. Some call-backs may + still follow because they would otherwise get lost. Examples: + - endElementHandler() for empty elements when stopped in + startElementHandler(), + - endNameSpaceDeclHandler() when stopped in endElementHandler(), + and possibly others. + + Can be called from most handlers, including DTD related call-backs, + except when parsing an external parameter entity and resumable != 0. + Returns XML_STATUS_OK when successful, XML_STATUS_ERROR otherwise. + Possible error codes: + - XML_ERROR_SUSPENDED: when suspending an already suspended parser. + - XML_ERROR_FINISHED: when the parser has already finished. + - XML_ERROR_SUSPEND_PE: when suspending while parsing an external PE. + + When resumable != 0 (true) then parsing is suspended, that is, + XML_Parse() and XML_ParseBuffer() return XML_STATUS_SUSPENDED. + Otherwise, parsing is aborted, that is, XML_Parse() and XML_ParseBuffer() + return XML_STATUS_ERROR with error code XML_ERROR_ABORTED. + + *Note*: + This will be applied to the current parser instance only, that is, if + there is a parent parser then it will continue parsing when the + externalEntityRefHandler() returns. It is up to the implementation of + the externalEntityRefHandler() to call XML_StopParser() on the parent + parser (recursively), if one wants to stop parsing altogether. + + When suspended, parsing can be resumed by calling XML_ResumeParser(). +*/ +XMLPARSEAPI(enum XML_Status) +XML_StopParser(XML_Parser parser, XML_Bool resumable); + +/* Resumes parsing after it has been suspended with XML_StopParser(). + Must not be called from within a handler call-back. Returns same + status codes as XML_Parse() or XML_ParseBuffer(). + Additional error code XML_ERROR_NOT_SUSPENDED possible. + + *Note*: + This must be called on the most deeply nested child parser instance + first, and on its parent parser only after the child parser has finished, + to be applied recursively until the document entity's parser is restarted. + That is, the parent parser will not resume by itself and it is up to the + application to call XML_ResumeParser() on it at the appropriate moment. +*/ +XMLPARSEAPI(enum XML_Status) +XML_ResumeParser(XML_Parser parser); + +enum XML_Parsing { + XML_INITIALIZED, + XML_PARSING, + XML_FINISHED, + XML_SUSPENDED +}; + +typedef struct { + enum XML_Parsing parsing; + XML_Bool finalBuffer; +} XML_ParsingStatus; + +/* Returns status of parser with respect to being initialized, parsing, + finished, or suspended and processing the final buffer. + XXX XML_Parse() and XML_ParseBuffer() should return XML_ParsingStatus, + XXX with XML_FINISHED_OK or XML_FINISHED_ERROR replacing XML_FINISHED +*/ +XMLPARSEAPI(void) +XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status); + +/* Creates an XML_Parser object that can parse an external general + entity; context is a '\0'-terminated string specifying the parse + context; encoding is a '\0'-terminated string giving the name of + the externally specified encoding, or NULL if there is no + externally specified encoding. The context string consists of a + sequence of tokens separated by formfeeds (\f); a token consisting + of a name specifies that the general entity of the name is open; a + token of the form prefix=uri specifies the namespace for a + particular prefix; a token of the form =uri specifies the default + namespace. This can be called at any point after the first call to + an ExternalEntityRefHandler so longer as the parser has not yet + been freed. The new parser is completely independent and may + safely be used in a separate thread. The handlers and userData are + initialized from the parser argument. Returns NULL if out of memory. + Otherwise returns a new XML_Parser object. +*/ +XMLPARSEAPI(XML_Parser) +XML_ExternalEntityParserCreate(XML_Parser parser, + const XML_Char *context, + const XML_Char *encoding); + +enum XML_ParamEntityParsing { + XML_PARAM_ENTITY_PARSING_NEVER, + XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE, + XML_PARAM_ENTITY_PARSING_ALWAYS +}; + +/* Controls parsing of parameter entities (including the external DTD + subset). If parsing of parameter entities is enabled, then + references to external parameter entities (including the external + DTD subset) will be passed to the handler set with + XML_SetExternalEntityRefHandler. The context passed will be 0. + + Unlike external general entities, external parameter entities can + only be parsed synchronously. If the external parameter entity is + to be parsed, it must be parsed during the call to the external + entity ref handler: the complete sequence of + XML_ExternalEntityParserCreate, XML_Parse/XML_ParseBuffer and + XML_ParserFree calls must be made during this call. After + XML_ExternalEntityParserCreate has been called to create the parser + for the external parameter entity (context must be 0 for this + call), it is illegal to make any calls on the old parser until + XML_ParserFree has been called on the newly created parser. + If the library has been compiled without support for parameter + entity parsing (ie without XML_DTD being defined), then + XML_SetParamEntityParsing will return 0 if parsing of parameter + entities is requested; otherwise it will return non-zero. + Note: If XML_SetParamEntityParsing is called after XML_Parse or + XML_ParseBuffer, then it has no effect and will always return 0. +*/ +XMLPARSEAPI(int) +XML_SetParamEntityParsing(XML_Parser parser, + enum XML_ParamEntityParsing parsing); + +/* If XML_Parse or XML_ParseBuffer have returned XML_STATUS_ERROR, then + XML_GetErrorCode returns information about the error. +*/ +XMLPARSEAPI(enum XML_Error) +XML_GetErrorCode(XML_Parser parser); + +/* These functions return information about the current parse + location. They may be called from any callback called to report + some parse event; in this case the location is the location of the + first of the sequence of characters that generated the event. When + called from callbacks generated by declarations in the document + prologue, the location identified isn't as neatly defined, but will + be within the relevant markup. When called outside of the callback + functions, the position indicated will be just past the last parse + event (regardless of whether there was an associated callback). + + They may also be called after returning from a call to XML_Parse + or XML_ParseBuffer. If the return value is XML_STATUS_ERROR then + the location is the location of the character at which the error + was detected; otherwise the location is the location of the last + parse event, as described above. +*/ +XMLPARSEAPI(int) XML_GetCurrentLineNumber(XML_Parser parser); +XMLPARSEAPI(int) XML_GetCurrentColumnNumber(XML_Parser parser); +XMLPARSEAPI(long) XML_GetCurrentByteIndex(XML_Parser parser); + +/* Return the number of bytes in the current event. + Returns 0 if the event is in an internal entity. +*/ +XMLPARSEAPI(int) +XML_GetCurrentByteCount(XML_Parser parser); + +/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets + the integer pointed to by offset to the offset within this buffer + of the current parse position, and sets the integer pointed to by size + to the size of this buffer (the number of input bytes). Otherwise + returns a NULL pointer. Also returns a NULL pointer if a parse isn't + active. + + NOTE: The character pointer returned should not be used outside + the handler that makes the call. +*/ +XMLPARSEAPI(const char *) +XML_GetInputContext(XML_Parser parser, + int *offset, + int *size); + +/* For backwards compatibility with previous versions. */ +#define XML_GetErrorLineNumber XML_GetCurrentLineNumber +#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber +#define XML_GetErrorByteIndex XML_GetCurrentByteIndex + +/* Frees the content model passed to the element declaration handler */ +XMLPARSEAPI(void) +XML_FreeContentModel(XML_Parser parser, XML_Content *model); + +/* Exposing the memory handling functions used in Expat */ +XMLPARSEAPI(void *) +XML_MemMalloc(XML_Parser parser, size_t size); + +XMLPARSEAPI(void *) +XML_MemRealloc(XML_Parser parser, void *ptr, size_t size); + +XMLPARSEAPI(void) +XML_MemFree(XML_Parser parser, void *ptr); + +/* Frees memory used by the parser. */ +XMLPARSEAPI(void) +XML_ParserFree(XML_Parser parser); + +/* Returns a string describing the error. */ +XMLPARSEAPI(const XML_LChar *) +XML_ErrorString(enum XML_Error code); + +/* Return a string containing the version number of this expat */ +XMLPARSEAPI(const XML_LChar *) +XML_ExpatVersion(void); + +typedef struct { + int major; + int minor; + int micro; +} XML_Expat_Version; + +/* Return an XML_Expat_Version structure containing numeric version + number information for this version of expat. +*/ +XMLPARSEAPI(XML_Expat_Version) +XML_ExpatVersionInfo(void); + +/* Added in Expat 1.95.5. */ +enum XML_FeatureEnum { + XML_FEATURE_END = 0, + XML_FEATURE_UNICODE, + XML_FEATURE_UNICODE_WCHAR_T, + XML_FEATURE_DTD, + XML_FEATURE_CONTEXT_BYTES, + XML_FEATURE_MIN_SIZE, + XML_FEATURE_SIZEOF_XML_CHAR, + XML_FEATURE_SIZEOF_XML_LCHAR + /* Additional features must be added to the end of this enum. */ +}; + +typedef struct { + enum XML_FeatureEnum feature; + const XML_LChar *name; + long int value; +} XML_Feature; + +XMLPARSEAPI(const XML_Feature *) +XML_GetFeatureList(void); + + +/* Expat follows the GNU/Linux convention of odd number minor version for + beta/development releases and even number minor version for stable + releases. Micro is bumped with each release, and set to 0 with each + change to major or minor version. +*/ +#define XML_MAJOR_VERSION 1 +#define XML_MINOR_VERSION 95 +#define XML_MICRO_VERSION 8 + +#ifdef __cplusplus +} +#endif + +#endif /* not XmlParse_INCLUDED */ diff --git a/rosapps/packmgr/lib/functions.cpp b/rosapps/packmgr/lib/functions.cpp new file mode 100644 index 00000000000..d7524d6ae31 --- /dev/null +++ b/rosapps/packmgr/lib/functions.cpp @@ -0,0 +1,101 @@ +//////////////////////////////////////////////////////// +// +// script.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 (const char* name, const char* local_name, const char* server, BOOL totemp = TRUE); + + +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(argv[1], argv[2], argv[3]); + + else if (argc==2) + result = PML_Download(argv[1], argv[2], NULL); + + 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} +}; diff --git a/rosapps/packmgr/lib/log.cpp b/rosapps/packmgr/lib/log.cpp new file mode 100644 index 00000000000..94b583f8c69 --- /dev/null +++ b/rosapps/packmgr/lib/log.cpp @@ -0,0 +1,98 @@ +//////////////////////////////////////////////////////// +// +// log.cpp +// +// Script Functions +// +// +// Klemens Friedl, 19.03.2005 +// frik85@hotmail.com +// +//////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include + +#include "log.h" +#include "package.hpp" // for Package Manager version +#include // 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; + + // 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); + + fputs("# ReactOS Package Manager - Log File\n#\n# WARNING: This is still pre-alpha software.\n# Date: ", file); + fputs(GTime, file); + fputs("\n#\n#", file); + fputs(version, file); + fputs("\n#", file); + fputs(versionos, file); + fputs("\n#\n", file); + } + else + file = fopen(LOGFILE, "a"); + + if (file == NULL) { + + if (LogCreated) + LogCreated = false; + + return; + } + else + { + // Save log entry (+ add time) + fputs("\n", file); + time_t now; + now = time(NULL); + strftime(GTime,sizeof GTime,"%I:%M:%S %p ",localtime(&now)); + fputs(GTime, 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); +} diff --git a/rosapps/packmgr/lib/log.h b/rosapps/packmgr/lib/log.h new file mode 100644 index 00000000000..d04e29e9872 --- /dev/null +++ b/rosapps/packmgr/lib/log.h @@ -0,0 +1,21 @@ +//////////////////////////////////////////////////////// +// +// log.h +// +// Script Functions +// +// +// Klemens Friedl, 19.03.2005 +// frik85@hotmail.com +// +//////////////////////////////////////////////////////////////////// + +#include +#include + +#define LOGFILE "packmgr.log" + +extern bool LogCreated; + +void Log (const char *message); +void LogAdd (const char *message); diff --git a/rosapps/packmgr/lib/main.cpp b/rosapps/packmgr/lib/main.cpp new file mode 100644 index 00000000000..f5812fe6176 --- /dev/null +++ b/rosapps/packmgr/lib/main.cpp @@ -0,0 +1,185 @@ +//////////////////////////////////////////////////////// +// +// main.cpp +// +// Doit stuff and +// everything that fits nowhere else. +// +// +// Maarten Bosma, 09.01.2004 +// maarten.paul@bosma.de +// +//////////////////////////////////////////////////////////////////// + +#include +#include "package.hpp" +#include "log.h" +#include "script.h" + +HANDLE hThread = NULL; +BOOL thread_abort = FALSE; + +extern const char* tree_server; +char* PML_Download (const char* name, const char* local_name = "packmgr.txt", const char* server = tree_server, BOOL totemp = TRUE); + + +// 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 scripts; + + /* Load the scripts */ + + tree->setStatus(0, 0, L"Downloading Install instructions ..."); + + for(i=0; itodo.size(); i++) + { + SCRIPT* script; + + char* path = PML_Download(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; isetStatus(500, 0, L"Install"); + + for(i=0; isetStatus(750, 0, L"Postinstall"); + + for(i=0; itodo.size(); i++) + RPS_Clear(scripts[i]); + + // clear the todo list + tree->todo.clear(); + + // set all actions to none + for(i=0; ipackages.size(); i++) + PML_SetAction (tree, i, 0, tree->setIcon); + + 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) +{ + DWORD dummy; + tree->setStatus = SetStatus; + + if(!tree->todo.size()) + return ERR_NOTODO; + + 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; ipackages.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; +} + diff --git a/rosapps/packmgr/lib/makefile b/rosapps/packmgr/lib/makefile new file mode 100644 index 00000000000..943b78f42b6 --- /dev/null +++ b/rosapps/packmgr/lib/makefile @@ -0,0 +1,27 @@ + +TARGET_TYPE = dynlink +TARGET_NAME = package +PATH_TO_TOP = ../../../reactos + +TARGET_SDKLIBS = kernel32.a shell32.a user32.a package.a expat.a urlmon.a + +TARGET_OBJECTS = main.o tree.o package.o download.o script.o functions.o log.o + +TARGET_GCCLIBS = stdc++ uuid + + +TARGET_CFLAGS = \ + -DUNICODE \ + -Wall \ + -Wno-error \ + -D__USE_W32API \ + -DWINVER=0x0600 \ + -D_WIN32_WINNT=0x0501 + +TARGET_CPPFLAGS = $(TARGET_CFLAGS) + +include $(PATH_TO_TOP)/rules.mak +include $(TOOLS_PATH)/helper.mk +include $(TOOLS_PATH)/depend.mk + +# EOF diff --git a/rosapps/packmgr/lib/package.cpp b/rosapps/packmgr/lib/package.cpp new file mode 100644 index 00000000000..469cb4d95af --- /dev/null +++ b/rosapps/packmgr/lib/package.cpp @@ -0,0 +1,191 @@ +//////////////////////////////////////////////////////// +// +// 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 (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; + } +} + +// 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, PML_SetText SetText) +{ + PACKAGE* pack = &tree->packages[id]; + tree->setButton = 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 (pack->path, (void*)pack, pack_start, pack_end, pack_text); + pack->loaded = TRUE; + } + + if(pack->description) + SetText(pack->description); + + return ERR_OK; +} + +// The user chooses a actions like Install +extern "C" int PML_SetAction (TREE* tree, int id, int action, PML_SetIcon SetIcon) +{ + 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; ichildren.size(); i++) + ret = ret || PML_SetAction(tree, pack->children[i], action, SetIcon); + + // is the action possible ? + if(!pack->actions[action]) + return ERR_GENERIC; + + // is it already set + if(pack->action == action) + return ERR_OK; + + // set the icon + if(!pack->icon) + SetIcon(id, 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 + tree->setButton(1, 1); + //tree->setButton(action+1, 0); + pack->action = action; + + // root notes (like network) return here + if(!pack->path) + return ret; + + // load it if it's not loaded yet + if(!pack->loaded) + { + PML_XmlDownload (pack->path, (void*)pack, pack_start, pack_end, pack_text); + pack->loaded = TRUE; + } + + // save the name of the corresponding script in a vector + tree->todo.push_back(pack->files[action-1]); + } + + // undoing + else + {+ + // set other things back + tree->setButton(1, 0); + //tree->setButton(pack->action+1, 1); + pack->action = 0; + + // root notes (like network) return here + if(!pack->path || pack->action==0) + return ret; + + // erase from todo list + for(i=0; itodo.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 + + return ERR_OK; + } + + return ret; +} + diff --git a/rosapps/packmgr/lib/package.def b/rosapps/packmgr/lib/package.def new file mode 100644 index 00000000000..9154be9287e --- /dev/null +++ b/rosapps/packmgr/lib/package.def @@ -0,0 +1,13 @@ +LIBRARY package.dll + +EXPORTS + + PML_Abort + PML_TransError + PML_LoadTree + PML_LoadPackage + PML_SetAction + PML_DoIt + PML_CloseTree + +; EOF diff --git a/rosapps/packmgr/lib/package.hpp b/rosapps/packmgr/lib/package.hpp new file mode 100644 index 00000000000..ce6ee469579 --- /dev/null +++ b/rosapps/packmgr/lib/package.hpp @@ -0,0 +1,86 @@ +//////////////////////////////////////////////// +// +// package.hpp +// Package C++ Header +//////////////////////////////////////////////// + +#include +#include +#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); + + +/* Structs */ + +typedef struct +{ + char* path; + BOOL icon; + BOOL loaded; + vector children; + + char** field; + char* name; + char* description; + + 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* xmltree; + + vector descriptionPath; + vector todo; + vector 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_LoadPackage (pTree, int id, PML_SetButton, PML_SetText); + int PML_SetAction (pTree, int package, int action, PML_SetIcon); + int PML_DoIt (pTree, PML_SetStatus); + + void PML_CloseTree (pTree); +} + + +/* Version */ + +#define PACKMGR_VERSION_MAJOR 0 +#define PACKMGR_VERSION_MINOR 3 +#define PACKMGR_VERSION_PATCH_LEVEL 1 diff --git a/rosapps/packmgr/lib/package.rc b/rosapps/packmgr/lib/package.rc new file mode 100644 index 00000000000..c5bc60ff9c1 --- /dev/null +++ b/rosapps/packmgr/lib/package.rc @@ -0,0 +1,15 @@ + +#include +#include "error.h" + +#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Package Manager\0" +#define REACTOS_STR_INTERNAL_NAME "package\0" +#define REACTOS_STR_ORIGINAL_FILENAME "package.dll\0" + +#include + +/* Language specific */ + +#include "en.rc" + +/* EOF */ diff --git a/rosapps/packmgr/lib/script.cpp b/rosapps/packmgr/lib/script.cpp new file mode 100644 index 00000000000..6c52ef8116a --- /dev/null +++ b/rosapps/packmgr/lib/script.cpp @@ -0,0 +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 + +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)asubs.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; asubs[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; bend)) + 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); + } +} diff --git a/rosapps/packmgr/lib/script.h b/rosapps/packmgr/lib/script.h new file mode 100644 index 00000000000..76778742793 --- /dev/null +++ b/rosapps/packmgr/lib/script.h @@ -0,0 +1,65 @@ +//////////////////////////////////////////////// +// +// package.hpp +// Header for the script stuff +//////////////////////////////////////////////// + +#include +#include + +using namespace std; + + +/* Structs */ + +typedef struct +{ + string name; + int start, end; + +} SUB; + +typedef struct +{ + vector code; + vector 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 diff --git a/rosapps/packmgr/lib/tree.cpp b/rosapps/packmgr/lib/tree.cpp new file mode 100644 index 00000000000..030e6333ef3 --- /dev/null +++ b/rosapps/packmgr/lib/tree.cpp @@ -0,0 +1,112 @@ +//////////////////////////////////////////////////////// +// +// tree.cpp +// +// Loading of the package tree +// +// +// Maarten Bosma, 09.01.2004 +// maarten.paul@bosma.de +// +//////////////////////////////////////////////////////////////////// + +#include "package.hpp" +#include "expat.h" + +vector parents; + +void tree_end (void* tree, const char* tag); +void tree_start (void* usrdata, const char* tag, const char** arg); + +int PML_XmlDownload (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; + + return PML_XmlDownload (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; + static int id = 1; + const char* name = "\0"; + + 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; + + // read the arguments + for (i=0; arg[i]; i+=2) + { + if(!strcmp(arg[i], "name")) + 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])]; + 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(name[0]=='\0') return; + + // add it + if(!parents.size()) + tree->addItem(id, name, 0, icon); + else + { + tree->addItem(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(); +} diff --git a/rosapps/packmgr/makefile b/rosapps/packmgr/makefile new file mode 100644 index 00000000000..439f9f149a4 --- /dev/null +++ b/rosapps/packmgr/makefile @@ -0,0 +1,14 @@ + +all: lib gui + +lib: dummy + $(MAKE) -C lib + +gui: dummy + $(MAKE) -C gui + +dummy: + +clean: + $(MAKE) -C gui clean + $(MAKE) -C lib clean diff --git a/rosapps/packmgr/tree/abiword.inst.rps b/rosapps/packmgr/tree/abiword.inst.rps new file mode 100644 index 00000000000..40cd3b96b55 --- /dev/null +++ b/rosapps/packmgr/tree/abiword.inst.rps @@ -0,0 +1,9 @@ +'Install rutine for abiword + +Sub Main + download ("http://www.abisource.com/downloads/abiword/2.2.5/Windows/abiword-setup-2.2.5.exe", "abisetup.exe") +End Sub + +Sub After + shell abisetup.exe +End Sub \ No newline at end of file diff --git a/rosapps/packmgr/tree/abiword.xml b/rosapps/packmgr/tree/abiword.xml new file mode 100644 index 00000000000..07f07ee44ac --- /dev/null +++ b/rosapps/packmgr/tree/abiword.xml @@ -0,0 +1,7 @@ + +AbiWord +Currently it's definitely the best word processor running under ReactOS. + + + + diff --git a/rosapps/packmgr/tree/mozcontrol.xml b/rosapps/packmgr/tree/mozcontrol.xml new file mode 100644 index 00000000000..01e953692b8 --- /dev/null +++ b/rosapps/packmgr/tree/mozcontrol.xml @@ -0,0 +1,7 @@ + +MozillaControl +Provide the Gekko Engine for ReactOS. + + + + diff --git a/rosapps/packmgr/tree/mozillacontrol.inst.rps b/rosapps/packmgr/tree/mozillacontrol.inst.rps new file mode 100644 index 00000000000..096e2a4a632 --- /dev/null +++ b/rosapps/packmgr/tree/mozillacontrol.inst.rps @@ -0,0 +1,9 @@ +'Install rutine for Mozilla Control 1.6 + +Sub Main + download ("http://www.iol.ie/~locka/mozilla/MozillaControl16.exe", "mozillacontrol16.exe") +End Sub + +Sub After + shell mozillacontrol16.exe +End Sub \ No newline at end of file diff --git a/rosapps/packmgr/tree/tree.xml b/rosapps/packmgr/tree/tree.xml new file mode 100644 index 00000000000..0ebd1859521 --- /dev/null +++ b/rosapps/packmgr/tree/tree.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +