You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by sk...@apache.org on 2022/12/08 13:14:40 UTC

[netbeans-native-installers] 10/19: Cleaner: Removed commented-out code and added explanatory comments.

This is an automated email from the ASF dual-hosted git repository.

skygo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans-native-installers.git

commit 215bdda1e9c46378e21dd2b11589b0e32847f03c
Author: Lars Bruun-Hansen <lb...@apache.org>
AuthorDate: Sat Sep 14 22:16:53 2019 +0200

    Cleaner: Removed commented-out code and added explanatory comments.
---
 cleaner/windows/src/main.c | 207 ++++++++++++++++++++++-----------------------
 1 file changed, 100 insertions(+), 107 deletions(-)

diff --git a/cleaner/windows/src/main.c b/cleaner/windows/src/main.c
index fb3d93c..74f0850 100644
--- a/cleaner/windows/src/main.c
+++ b/cleaner/windows/src/main.c
@@ -21,14 +21,82 @@
 #include <wchar.h>
 
 
+/*
+ * cleaner.exe
+ * 
+ * Deletes a list of files/folders.
+ * 
+ * The command line syntax is:
+ * 
+ *    arg1:   File name containing a list of files/folders to delete.
+ * 
+ * Requirements for arg1:
+ *  - The arg1 file name MUST be fully qualified. (or be in the same directory
+ *       as the cleaner.exe executable)
+ *  - The file MUST use Windows line ending (CRLF)
+ *  - The file MUST be encoded in UTF-16. The NBI Engine will produce
+ *    this file in Java charset "UNICODE" which effectively means
+ *    UCS-2 BigEndian BOM. Such file will work just fine.
+ *  - Each line in the file is expected to contain a fully qualified file
+ *    or folder name. The entry can be 
+ *        - a local file/folder name, e.g. "C:\foo\bar", up to a maximum of 32767 
+ *          chars and thus not subject to the original Windows limitation 
+ *          of 260 chars for a path name.
+ *        - a UNC, e.g. "\\servername\sharename\foo\bar", subject to a
+ *          restriction of 260 chars.
+ *  - The list MUST be ordered so that the files in a folder are listed before 
+ *    the folder itself. (it is not possible to delete a non-empty folder)
+ * 
+ * Method of working:
+ * 
+ * 1. After launch the content of command line arg1 is read into memory 
+ *    as one big string.
+ * 2. The string is chopped into a list by separating at the LINE_SEPARATOR.
+ * 3. Sleep for 2 seconds to allow the launching process (the JVM) to exit.
+ * 4. Loop over the list of files/folder to delete. Each file-delete operation 
+ *    is spawned into a thread of its own up to a maximum of 64 threads. 
+ *    Therefore the delete operations happens in parallel rather than in sequence. 
+ *    If 64 threads have been spawned then wait for a thread to exit before
+ *    spawning a new one. (therefore never more than 64 threads)
+ *    For each file delete operation do the following:
+ *       - Check to see if the file exists (by getting its attributes)
+ *       - If file: delete file, if directory: delete directory (these are two 
+ *            different calls in the Win32 API).
+ *       - Attempt to delete each file/dir up to 15 times sleeping for 200 ms 
+ *            between each attempt.
+ * 5. Wait for all file-delete threads to exit.
+ * 6. Delete self, i.e. the "cleaner.exe" executable.
+ * 7. End
+ *
+ * The arg1 file is not deleted. However it can be part of the list itself 
+ * if need be.
+ * 
+ * Author:  Dmitry Lipin, 2007
+ * 
+ *
+ *  
+ * Changes after transition to Apache:
+ * 
+ *   14-SEP-2019 Lars Bruun-Hansen (lbruun@apache.org) :   
+ *         Function comment headers added. 
+ *         Main comment header added.
+ *  
+ */
+
 
+// Retry functionality: 
+//   SLEEP_DELAY : millis between each attempt at a file delete
+//   MAX_ATTEMPTS : how many times to attempt to delete a file
 const DWORD SLEEP_DELAY   = 200;
 const DWORD MAX_ATTEMPTS   = 15;
 const DWORD THREAD_FINISHED = 100;
-const DWORD INITIAL_DELAY = 2000; // 2 seconds is seems to be enough to finish java process
+
+// Number of milliseconds to sleep at launch of the application.
+const DWORD INITIAL_DELAY = 2000; // 2 seconds seems to be enough to finish java process
+
 const WCHAR * LINE_SEPARATOR = L"\r\n";
-const WCHAR * UNC_PREFIX     = L"\\\\?\\";
-const WCHAR * UNC_STD_PREFIX = L"\\\\";
+const WCHAR * UNC_PREFIX     = L"\\\\?\\"; // Prefix for extended-length path in Win32 API
+const WCHAR * UNC_STD_PREFIX = L"\\\\";  // Prefix for UNC paths, for example: \\servername\share\foo\bar
 const DWORD UNC_PREFIX_LENGTH = 4;
 
 #ifdef _MSC_VER
@@ -37,25 +105,11 @@ const DWORD UNC_PREFIX_LENGTH = 4;
 #define ZERO(x,y) ZeroMemory((x),(y));
 #endif
 
+
 /*
- * typedef UINT  (WINAPI * WAIT_PROC)(HANDLE, DWORD);
- * typedef BOOL  (WINAPI * CLOSE_PROC)(HANDLE);
- * typedef BOOL  (WINAPI * DELETE_PROC)(LPCWSTR);
- * typedef VOID  (WINAPI * EXIT_PROC)(DWORD);
- * typedef VOID  (WINAPI * SLEEP_PROC)(DWORD);
- *
- *
- * typedef struct {
- * WAIT_PROC	waitObject;
- * CLOSE_PROC	closeHandle;
- * DELETE_PROC	deleteFile;
- * EXIT_PROC	exitProcess;
- * SLEEP_PROC  sleep;
- *
- * HANDLE		hProcess;
- * WCHAR		szFileName[MAX_PATH];
- *
- * } INJECT;
+ * Search for the first occurrence of wcs2 within wcs1.
+ * Returns a pointer to the first occurrence if found.
+ * If not found, NULL is returned.
  */
 WCHAR * search( const WCHAR * wcs1, const WCHAR * wcs2) {
     WCHAR *cp = (WCHAR *) wcs1;
@@ -80,91 +134,6 @@ WCHAR * search( const WCHAR * wcs1, const WCHAR * wcs2) {
     return(NULL);
 }
 
-/*
- * DWORD WINAPI RemoteThread(INJECT *remote) {
- * DWORD count = 0 ;
- *
- * remote->waitObject(remote->hProcess, INFINITE);
- * remote->closeHandle(remote->hProcess);
- * while(!remote->deleteFile(remote->szFileName) && (count++) < MAX_ATTEPTS) {
- * remote->sleep(SLEEP_DELAY);
- * }
- * remote->exitProcess(0);
- * return 0;
- * }
- *
- * HANDLE GetRemoteProcess() {
- * STARTUPINFO si;
- *
- * PROCESS_INFORMATION pi;
- * ZERO( &si, sizeof(si) );
- * ZERO( &pi, sizeof(pi) );
- * si.cb = sizeof(si);
- * if(CreateProcess(0, "explorer.exe", 0, 0, FALSE, CREATE_SUSPENDED|CREATE_NO_WINDOW|IDLE_PRIORITY_CLASS, 0, 0, &si, &pi)) {
- * CloseHandle(pi.hThread);
- * return pi.hProcess;
- * }
- * else {
- * return 0;
- * }
- * }
- *
- * BOOL removeItself() {
- *
- * INJECT local, *remote;
- * BYTE   *code;
- * HMODULE hKernel32;
- * HANDLE  hRemoteProcess;
- * HANDLE  hCurProc;
- *
- * DWORD	dwThreadId;
- * HANDLE	hThread = 0;
- * DWORD sizeOfCode = 200;
- *
- * hRemoteProcess = GetRemoteProcess();
- *
- * if(hRemoteProcess == 0) {
- * return FALSE;
- * }
- *
- * code = VirtualAllocEx(hRemoteProcess, 0, sizeof(INJECT) + sizeOfCode, MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE);
- *
- * if(code == 0) {
- * CloseHandle(hRemoteProcess);
- * return FALSE;
- * }
- *
- * hKernel32 = GetModuleHandleW(L"kernel32.dll");
- * remote = (INJECT *)(code + sizeOfCode);
- *
- * local.waitObject      = (WAIT_PROC)  GetProcAddress(hKernel32, "WaitForSingleObject");
- * local.closeHandle	  = (CLOSE_PROC) GetProcAddress(hKernel32, "CloseHandle");
- * local.exitProcess	  = (EXIT_PROC)  GetProcAddress(hKernel32, "ExitProcess");
- * local.deleteFile      = (DELETE_PROC)GetProcAddress(hKernel32, "DeleteFileW");
- * local.sleep           = (SLEEP_PROC) GetProcAddress(hKernel32, "Sleep");
- *
- * // duplicate our own process handle for remote process to wait on
- * hCurProc = GetCurrentProcess();
- *
- * DuplicateHandle(hCurProc, hCurProc, hRemoteProcess, &local.hProcess, 0, FALSE, DUPLICATE_SAME_ACCESS);
- *
- * // find name of current executable
- *
- * GetModuleFileNameW(NULL, local.szFileName, MAX_PATH);
- *
- * // write in code to execute, and the remote structure
- * WriteProcessMemory(hRemoteProcess, (LPVOID) code,   RemoteThread, sizeOfCode, 0);
- * WriteProcessMemory(hRemoteProcess, (LPVOID) remote, &local, sizeof(local), 0);
- *
- * // execute the code in remote process
- * hThread = CreateRemoteThread(hRemoteProcess, 0, 0, (LPTHREAD_START_ROUTINE) code, remote, 0, &dwThreadId);
- *
- * if(hThread != 0) {
- * CloseHandle(hThread);
- * }
- * return TRUE;
- * }
- */
 
 typedef struct _list {
     WCHAR * item;
@@ -203,6 +172,10 @@ WCHAR * toWCHAR(char * charBuffer, DWORD size) {
     return buffer;
 }
 
+/*
+ * Gets the number of lines in the input. 
+ * (lines are expected to be separated by LINE_SEPARATOR) 
+ */
 DWORD getLinesNumber(WCHAR *str) {
     DWORD result = 0;
     WCHAR *ptr = str;
@@ -222,6 +195,15 @@ DWORD getLinesNumber(WCHAR *str) {
     return result;
 }
 
+/*
+ * Produces a string array, 'list', from 'str' by splitting the string
+ * at each occurrence of LINE_SEPARATOR.
+ * 
+ * [IN] str:      the input
+ * [OUT] list:    string array
+ * [OUT] number:  number of elements in 'list' 
+ *
+ */
 void getLines(WCHAR *str, WCHAR *** list, DWORD * number) {
     WCHAR *ptr = str;
     WCHAR *ptr2 = NULL;
@@ -257,7 +239,9 @@ void getLines(WCHAR *str, WCHAR *** list, DWORD * number) {
     }
 }
 
-
+/*
+ *  Read file into memory. 
+ */
 void readStringList(HANDLE fileHandle, WCHAR *** list, DWORD *number) {
     DWORD size = GetFileSize(fileHandle, NULL); // hope it much less than 2GB
     DWORD read = 0;
@@ -329,6 +313,11 @@ void getFreeIndexForNextThread(HANDLE * list, DWORD max, DWORD * counter) {
     }
 }
 
+/*
+ * Deletes the the current executable. This is done by spawning a small
+ * .bat file which does the job. The .bat file even deletes itself when 
+ * finished.
+ */
 #define BUFSIZE 512
 void removeItselfUsingCmd() {
     char * currentFile = LocalAlloc(LPTR, sizeof(char) * BUFSIZE);    
@@ -391,6 +380,10 @@ void removeItselfUsingCmd() {
     
 }
 
+/*
+ * Changes directory to the directory where the currently executing
+ * executable is located.
+ */ 
 void changeCurrentDirectory() {
     WCHAR * currentFile = LocalAlloc(LPTR, sizeof(WCHAR) * MAX_PATH);    
     if (GetModuleFileNameW(0, currentFile, MAX_PATH)) {


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists