QString Util::PercentEncodeUnicodeAndFSChars(const QString& input) { //Mix of `PercentEncodeFSChars` and `PercentEncodeUnicodeChars`. QList<ushort> invalidWinFSChars = QList<ushort>() << '<' << '>' << ':' << '"' << '/' << '\\' << '|' << '?' << '*'; QString output; foreach (QChar c, input) { if (c.unicode() >= 32 && c.unicode() <= 126) { if (invalidWinFSChars.contains(c.unicode())) output += PercentEncodeQChar(c); else output += c; } else { output += PercentEncodeQChar(c); } } //Now at this point we check for valid file name. If this fails, it is because the file name is // e.g 'COM1' or '..', so we just PREPEND something to it (to avoid changing the extension). if (!IsValidFileName(output)) output = "@Name_" + output; return output; }
NamedPipe::NamedPipe(const string& name, NamedPipeIo io) : mName("\\\\.\\pipe\\" + name), mConfig(io) { if (!IsValidFileName(name)) { throw NamedPipeException("Name ist invalid. \\ and / are not allowed."); } }
/** Function for 'hexedit' command. @param[in] ImageHandle Handle to the Image (NULL if Internal). @param[in] SystemTable Pointer to the System Table (NULL if Internal). **/ SHELL_STATUS EFIAPI ShellCommandRunHexEdit ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; CHAR16 *Buffer; CHAR16 *ProblemParam; SHELL_STATUS ShellStatus; LIST_ENTRY *Package; CHAR16 *NewName; CONST CHAR16 *Name; UINTN Offset; UINTN Size; EDIT_FILE_TYPE WhatToDo; Buffer = NULL; ShellStatus = SHELL_SUCCESS; NewName = NULL; Buffer = NULL; Name = NULL; Offset = 0; Size = 0; WhatToDo = FileTypeNone; // // initialize the shell lib (we must be in non-auto-init...) // Status = ShellInitialize(); // ASSERT_EFI_ERROR(Status); Status = CommandInit(); // ASSERT_EFI_ERROR(Status); if (EFI_ERROR(Status)) { return SHELL_UNSUPPORTED; } // // parse the command line // Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE); if (EFI_ERROR(Status)) { if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellDebug1HiiHandle, L"hexedit", ProblemParam); FreePool(ProblemParam); ShellStatus = SHELL_INVALID_PARAMETER; } /* else { ASSERT(FALSE); } */ } else { // // Check for -d // if (ShellCommandLineGetFlag(Package, L"-d")){ if (ShellCommandLineGetCount(Package) < 4) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"hexedit"); ShellStatus = SHELL_INVALID_PARAMETER; } else if (ShellCommandLineGetCount(Package) > 4) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"hexedit"); ShellStatus = SHELL_INVALID_PARAMETER; } else { WhatToDo = FileTypeDiskBuffer; Name = ShellCommandLineGetRawValue(Package, 1); Offset = ShellStrToUintn(ShellCommandLineGetRawValue(Package, 2)); Size = ShellStrToUintn(ShellCommandLineGetRawValue(Package, 3)); } if (Offset == (UINTN)-1 || Size == (UINTN)-1) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_VALUE), gShellDebug1HiiHandle, L"hexedit", L"-d"); ShellStatus = SHELL_INVALID_PARAMETER; } } // // check for -f // if (ShellCommandLineGetFlag(Package, L"-f") && (WhatToDo == FileTypeNone)){ if (ShellCommandLineGetCount(Package) < 2) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"hexedit"); ShellStatus = SHELL_INVALID_PARAMETER; } else if (ShellCommandLineGetCount(Package) > 2) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"hexedit"); ShellStatus = SHELL_INVALID_PARAMETER; } else { Name = ShellCommandLineGetRawValue(Package, 1); if (Name == NULL || !IsValidFileName(Name)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"hexedit", Name); ShellStatus = SHELL_INVALID_PARAMETER; } else { WhatToDo = FileTypeFileBuffer; } } } // // check for -m // if (ShellCommandLineGetFlag(Package, L"-m") && (WhatToDo == FileTypeNone)){ if (ShellCommandLineGetCount(Package) < 3) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"hexedit"); ShellStatus = SHELL_INVALID_PARAMETER; } else if (ShellCommandLineGetCount(Package) > 3) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"hexedit"); ShellStatus = SHELL_INVALID_PARAMETER; } else { WhatToDo = FileTypeMemBuffer; Offset = ShellStrToUintn(ShellCommandLineGetRawValue(Package, 1)); Size = ShellStrToUintn(ShellCommandLineGetRawValue(Package, 2)); } } Name = ShellCommandLineGetRawValue(Package, 1); if (WhatToDo == FileTypeNone && Name != NULL) { if (ShellCommandLineGetCount(Package) > 2) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_MANY), gShellDebug1HiiHandle, L"hexedit"); ShellStatus = SHELL_INVALID_PARAMETER; } else if (!IsValidFileName(Name)) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_PARAM_INV), gShellDebug1HiiHandle, L"hexedit", Name); ShellStatus = SHELL_INVALID_PARAMETER; } else { WhatToDo = FileTypeFileBuffer; } } else if (WhatToDo == FileTypeNone) { if (gEfiShellProtocol->GetCurDir(NULL) == NULL) { ShellStatus = SHELL_NOT_FOUND; ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellDebug1HiiHandle, L"hexedit"); } else { NewName = EditGetDefaultFileName(L"bin"); Name = NewName; WhatToDo = FileTypeFileBuffer; } } if (ShellStatus == SHELL_SUCCESS && WhatToDo == FileTypeNone) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellDebug1HiiHandle, L"hexedit"); ShellStatus = SHELL_INVALID_PARAMETER; } else if (WhatToDo == FileTypeFileBuffer && ShellGetCurrentDir(NULL) == NULL) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_NO_CWD), gShellDebug1HiiHandle, L"hexedit"); ShellStatus = SHELL_INVALID_PARAMETER; } if (ShellStatus == SHELL_SUCCESS) { // // Do the editor // Status = HMainEditorInit (); if (EFI_ERROR (Status)) { gST->ConOut->ClearScreen (gST->ConOut); gST->ConOut->EnableCursor (gST->ConOut, TRUE); ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_INIT_FAILED), gShellDebug1HiiHandle); } else { HMainEditorBackup (); switch (WhatToDo) { case FileTypeFileBuffer: Status = HBufferImageRead ( Name==NULL?L"":Name, NULL, 0, 0, 0, 0, FileTypeFileBuffer, FALSE ); break; case FileTypeDiskBuffer: Status = HBufferImageRead ( NULL, Name==NULL?L"":Name, Offset, Size, 0, 0, FileTypeDiskBuffer, FALSE ); break; case FileTypeMemBuffer: Status = HBufferImageRead ( NULL, NULL, 0, 0, (UINT32) Offset, Size, FileTypeMemBuffer, FALSE ); break; default: Status = EFI_NOT_FOUND; break; } if (!EFI_ERROR (Status)) { HMainEditorRefresh (); Status = HMainEditorKeyInput (); } if (Status != EFI_OUT_OF_RESOURCES) { // // back up the status string // Buffer = CatSPrint (NULL, L"%s\r\n", StatusBarGetString()); } } // // cleanup // HMainEditorCleanup (); if (EFI_ERROR (Status)) { if (ShellStatus == SHELL_SUCCESS) { ShellStatus = SHELL_UNSUPPORTED; } } // // print editor exit code on screen // if (Status == EFI_OUT_OF_RESOURCES) { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_GEN_OUT_MEM), gShellDebug1HiiHandle, L"hexedit"); } else if (EFI_ERROR(Status)){ if (Buffer != NULL) { if (StrCmp (Buffer, L"") != 0) { // // print out the status string // ShellPrintEx(-1, -1, L"%s", Buffer); } else { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_UNKNOWN_EDITOR), gShellDebug1HiiHandle); } } else { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_HEXEDIT_UNKNOWN_EDITOR), gShellDebug1HiiHandle); } } } ShellCommandLineFreeVarList (Package); } SHELL_FREE_NON_NULL (Buffer); SHELL_FREE_NON_NULL (NewName); return ShellStatus; }
/* ファイル共有(添付)情報をデコード 注意:破壊読出し。使用が終わり次第 FreeDecodeShareMsg を呼び出すこと。 */ ShareInfo *DecodeShareMsg(char *buf, BOOL enable_clip) { ShareInfo *shareInfo = new ShareInfo; FileInfo *fileInfo = NULL; char *tok, *p, *p2, *p3; char *file = separate_token(buf, FILELIST_SEPARATOR, &p); for (int i=0; file; i++, file=separate_token(NULL, FILELIST_SEPARATOR, &p)) { ConvertShareMsgEscape(file); // "::" -> ';' if ((tok = separate_token(file, ':', &p2)) == NULL) break; fileInfo = new FileInfo(atoi(tok)); if ((tok = separate_token(NULL, ':', &p2)) == NULL || strlen(tok) >= MAX_FILENAME) break; while ((p3 = strchr(tok, '?'))) // UNICODE 対応までの暫定 *p3 = '_'; if (!IsValidFileName(tok)) break; fileInfo->SetFname(tok); if ((tok = separate_token(NULL, ':', &p2)) == NULL) break; fileInfo->SetSize(hex2ll(tok)); if ((tok = separate_token(NULL, ':', &p2)) == NULL) break; fileInfo->SetMtime(strtoul(tok, 0, 16)); if ((tok = separate_token(NULL, ':', &p2))) { fileInfo->SetAttr(strtoul(tok, 0, 16)); u_int attr_type = GET_MODE(fileInfo->Attr()); if (attr_type != IPMSG_FILE_DIR && attr_type != IPMSG_FILE_REGULAR && (!enable_clip || attr_type != IPMSG_FILE_CLIPBOARD)) { delete fileInfo; fileInfo = NULL; continue; } if (attr_type == IPMSG_FILE_CLIPBOARD) { if ((tok = separate_token(NULL, ':', &p2))) { if (strtoul(tok, 0, 16) == IPMSG_FILE_CLIPBOARDPOS) { if (separate_token(tok, '=', &p3) && (tok = separate_token(NULL, '=', &p3))) { fileInfo->SetPos(strtoul(tok, 0, 16)); } } } } } else fileInfo->SetAttr(IPMSG_FILE_REGULAR); if ((shareInfo->fileCnt % BIG_ALLOC) == 0) shareInfo->fileInfo = (FileInfo **)realloc(shareInfo->fileInfo, (shareInfo->fileCnt + BIG_ALLOC) * sizeof(FileInfo *)); shareInfo->fileInfo[shareInfo->fileCnt++] = fileInfo; fileInfo = NULL; } if (fileInfo) // デコード中に抜けた delete fileInfo; if (shareInfo->fileCnt <= 0) { delete shareInfo; return NULL; } return shareInfo; }
INT_PTR SettingsGeneral::ProcMessage(UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_INITDIALOG: { LocalizeWindow(hwnd); //---------------------------------------------- HWND hwndTemp = GetDlgItem(hwnd, IDC_LANGUAGE); OSFindData ofd; HANDLE hFind; if(hFind = OSFindFirstFile(TEXT("locale/*.txt"), ofd)) { do { if(ofd.bDirectory) continue; String langCode = GetPathFileName(ofd.fileName); LocaleNativeName *langInfo = GetLocaleNativeName(langCode); if(langInfo) { UINT id = (UINT)SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)langInfo->lpNative); SendMessage(hwndTemp, CB_SETITEMDATA, id, (LPARAM)langInfo->lpCode); if(App->strLanguage.CompareI(langCode)) SendMessage(hwndTemp, CB_SETCURSEL, id, 0); } } while(OSFindNextFile(hFind, ofd)); OSFindClose(hFind); } //---------------------------------------------- String strCurProfile = GlobalConfig->GetString(TEXT("General"), TEXT("Profile")); hwndTemp = GetDlgItem(hwnd, IDC_PROFILE); StringList profileList; App->GetProfiles(profileList); for(UINT i=0; i<profileList.Num(); i++) { UINT id = (UINT)SendMessage(hwndTemp, CB_ADDSTRING, 0, (LPARAM)profileList[i].Array()); if(profileList[i].CompareI(strCurProfile)) SendMessage(hwndTemp, CB_SETCURSEL, id, 0); } EnableWindow(hwndTemp, !App->bRunning); EnableWindow(GetDlgItem(hwnd, IDC_ADD), FALSE); EnableWindow(GetDlgItem(hwnd, IDC_RENAME), FALSE); UINT numItems = (UINT)SendMessage(hwndTemp, CB_GETCOUNT, 0, 0); EnableWindow(GetDlgItem(hwnd, IDC_REMOVE), (numItems > 1) && !App->bRunning); //---------------------------------------------- bool bShowNotificationAreaIcon = AppConfig->GetInt(TEXT("General"), TEXT("ShowNotificationAreaIcon"), 0) != 0; SendMessage(GetDlgItem(hwnd, IDC_NOTIFICATIONICON), BM_SETCHECK, bShowNotificationAreaIcon ? BST_CHECKED : BST_UNCHECKED, 0); bool bMinimizeToNotificationArea = AppConfig->GetInt(TEXT("General"), TEXT("MinimizeToNotificationArea"), 0) != 0; SendMessage(GetDlgItem(hwnd, IDC_MINIZENOTIFICATION), BM_SETCHECK, bMinimizeToNotificationArea ? BST_CHECKED : BST_UNCHECKED, 0); //---------------------------------------------- App->bEnableProjectorCursor = GlobalConfig->GetInt(L"General", L"EnableProjectorCursor", 1) != 0; SendMessage(GetDlgItem(hwnd, IDC_ENABLEPROJECTORCURSOR), BM_SETCHECK, App->bEnableProjectorCursor ? BST_CHECKED : BST_UNCHECKED, 0); //---------------------------------------------- bool showLogWindowOnLaunch = GlobalConfig->GetInt(TEXT("General"), TEXT("ShowLogWindowOnLaunch")) != 0; SendMessage(GetDlgItem(hwnd, IDC_SHOWLOGWINDOWONLAUNCH), BM_SETCHECK, showLogWindowOnLaunch ? BST_CHECKED : BST_UNCHECKED, 0); //---------------------------------------------- SetChangedSettings(false); return TRUE; } case WM_COMMAND: switch(LOWORD(wParam)) { case IDC_LANGUAGE: { if(HIWORD(wParam) != CBN_SELCHANGE) break; HWND hwndTemp = (HWND)lParam; SetWindowText(GetDlgItem(hwnd, IDC_INFO), Str("Settings.General.Restart")); ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_SHOW); SetChangedSettings(true); break; } case IDC_PROFILE: if (App->bRunning) { HWND cb = (HWND)lParam; String curProfile = GlobalConfig->GetString(TEXT("General"), TEXT("Profile")); UINT numItems = (UINT)SendMessage(cb, CB_GETCOUNT, 0, 0); for (UINT i = 0; i < numItems; i++) { if (GetCBText(cb, i).Compare(curProfile)) SendMessage(cb, CB_SETCURSEL, i, 0); } break; } if(HIWORD(wParam) == CBN_EDITCHANGE) { String strText = GetEditText((HWND)lParam).KillSpaces(); EnableWindow(GetDlgItem(hwnd, IDC_REMOVE), FALSE); if(strText.IsValid()) { if(IsValidFileName(strText)) { String strCurProfile = GlobalConfig->GetString(TEXT("General"), TEXT("Profile")); UINT id = (UINT)SendMessage((HWND)lParam, CB_FINDSTRINGEXACT, -1, (LPARAM)strText.Array()); EnableWindow(GetDlgItem(hwnd, IDC_ADD), (id == CB_ERR)); EnableWindow(GetDlgItem(hwnd, IDC_RENAME), (id == CB_ERR) || strCurProfile.CompareI(strText)); ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_HIDE); break; } SetWindowText(GetDlgItem(hwnd, IDC_INFO), Str("Settings.General.InvalidName")); ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_SHOW); } else ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_HIDE); EnableWindow(GetDlgItem(hwnd, IDC_ADD), FALSE); EnableWindow(GetDlgItem(hwnd, IDC_RENAME), FALSE); } else if(HIWORD(wParam) == CBN_SELCHANGE) { EnableWindow(GetDlgItem(hwnd, IDC_ADD), FALSE); EnableWindow(GetDlgItem(hwnd, IDC_RENAME), FALSE); String strProfile = GetCBText((HWND)lParam); String strProfilePath; strProfilePath << lpAppDataPath << TEXT("\\profiles\\") << strProfile << TEXT(".ini"); if(!AppConfig->Open(strProfilePath)) { OBSMessageBox(hwnd, TEXT("Error - unable to open ini file"), NULL, 0); break; } App->ReloadIniSettings(); SetWindowText(GetDlgItem(hwnd, IDC_INFO), Str("Settings.Info")); ShowWindow(GetDlgItem(hwnd, IDC_INFO), SW_SHOW); GlobalConfig->SetString(TEXT("General"), TEXT("Profile"), strProfile); App->ResetProfileMenu(); App->ResetApplicationName(); App->UpdateNotificationAreaIcon(); UINT numItems = (UINT)SendMessage(GetDlgItem(hwnd, IDC_PROFILE), CB_GETCOUNT, 0, 0); EnableWindow(GetDlgItem(hwnd, IDC_REMOVE), (numItems > 1)); App->ResizeWindow(false); } break; case IDC_RENAME: case IDC_ADD: if (App->bRunning) break; if(HIWORD(wParam) == BN_CLICKED) { HWND hwndProfileList = GetDlgItem(hwnd, IDC_PROFILE); String strProfile = GetEditText(hwndProfileList).KillSpaces(); SetWindowText(hwndProfileList, strProfile); if(strProfile.IsEmpty()) break; bool bRenaming = (LOWORD(wParam) == IDC_RENAME); String strCurProfile = GlobalConfig->GetString(TEXT("General"), TEXT("Profile")); String strCurProfilePath; strCurProfilePath << lpAppDataPath << TEXT("\\profiles\\") << strCurProfile << TEXT(".ini"); String strProfilePath; strProfilePath << lpAppDataPath << TEXT("\\profiles\\") << strProfile << TEXT(".ini"); if((!bRenaming || !strProfilePath.CompareI(strCurProfilePath)) && OSFileExists(strProfilePath)) OBSMessageBox(hwnd, Str("Settings.General.ProfileExists"), NULL, 0); else { if(bRenaming) { if(!MoveFile(strCurProfilePath, strProfilePath)) break; AppConfig->SetFilePath(strProfilePath); UINT curID = (UINT)SendMessage(hwndProfileList, CB_FINDSTRINGEXACT, -1, (LPARAM)strCurProfile.Array()); if(curID != CB_ERR) SendMessage(hwndProfileList, CB_DELETESTRING, curID, 0); } else { if(!AppConfig->SaveAs(strProfilePath)) { OBSMessageBox(hwnd, TEXT("Error - unable to create new profile, could not create file"), NULL, 0); break; } } UINT id = (UINT)SendMessage(hwndProfileList, CB_ADDSTRING, 0, (LPARAM)strProfile.Array()); SendMessage(hwndProfileList, CB_SETCURSEL, id, 0); GlobalConfig->SetString(TEXT("General"), TEXT("Profile"), strProfile); UINT numItems = (UINT)SendMessage(hwndProfileList, CB_GETCOUNT, 0, 0); EnableWindow(GetDlgItem(hwnd, IDC_REMOVE), (numItems > 1)); EnableWindow(GetDlgItem(hwnd, IDC_RENAME), FALSE); EnableWindow(GetDlgItem(hwnd, IDC_ADD), FALSE); App->ResetProfileMenu(); App->ResetApplicationName(); } } break; case IDC_REMOVE: if (App->bRunning) break; { HWND hwndProfileList = GetDlgItem(hwnd, IDC_PROFILE); String strCurProfile = GlobalConfig->GetString(TEXT("General"), TEXT("Profile")); UINT numItems = (UINT)SendMessage(hwndProfileList, CB_GETCOUNT, 0, 0); String strConfirm = Str("Settings.General.ConfirmDelete"); strConfirm.FindReplace(TEXT("$1"), strCurProfile); if(OBSMessageBox(hwnd, strConfirm, Str("DeleteConfirm.Title"), MB_YESNO) == IDYES) { UINT id = (UINT)SendMessage(hwndProfileList, CB_FINDSTRINGEXACT, -1, (LPARAM)strCurProfile.Array()); if(id != CB_ERR) { SendMessage(hwndProfileList, CB_DELETESTRING, id, 0); if(id == numItems-1) id--; SendMessage(hwndProfileList, CB_SETCURSEL, id, 0); DialogProc(hwnd, WM_COMMAND, MAKEWPARAM(IDC_PROFILE, CBN_SELCHANGE), (LPARAM)hwndProfileList); String strCurProfilePath; strCurProfilePath << lpAppDataPath << TEXT("\\profiles\\") << strCurProfile << TEXT(".ini"); OSDeleteFile(strCurProfilePath); App->ResetProfileMenu(); } } break; } case IDC_NOTIFICATIONICON: if (SendMessage(GetDlgItem(hwnd, IDC_NOTIFICATIONICON), BM_GETCHECK, 0, 0) == BST_UNCHECKED) { SendMessage(GetDlgItem(hwnd, IDC_MINIZENOTIFICATION), BM_SETCHECK, BST_UNCHECKED, 0); } SetChangedSettings(true); break; case IDC_MINIZENOTIFICATION: if (SendMessage(GetDlgItem(hwnd, IDC_MINIZENOTIFICATION), BM_GETCHECK, 0, 0) == BST_CHECKED) { SendMessage(GetDlgItem(hwnd, IDC_NOTIFICATIONICON), BM_SETCHECK, BST_CHECKED, 0); } SetChangedSettings(true); break; case IDC_ENABLEPROJECTORCURSOR: case IDC_SHOWLOGWINDOWONLAUNCH: SetChangedSettings(true); break; } } return FALSE; }
void GetResponseMessage(char *inmsg, char *outmsg) { char filename[FILENAME_LEN + 1]; /* requested file name */ int requested_chunk; /* requested chunk number */ char client_address[CADDRESS_LEN + 1]; /* address of client */ unsigned short client_port; /* port of client */ int total_chunks; /* total # of chunks in file */ char temp[CHUNK_LEN + 1]; /* requested chunk - string */ int i; /* loops et al */ char data[DATA_LEN + 1]; /* file chunk */ int status; /* function returns */ int datsize; /* size of data chunk */ /* extract info from request message */ GetRequestedFileName(inmsg, filename); GetRequestedChunk(inmsg, &requested_chunk); GetClientAddress(inmsg, client_address); GetClientPort(inmsg, &client_port); /* get total number of chunks in file */ total_chunks = GetTotalChunks(filename); /* check for errors - construct CTL messages */ if(!IsValidFileName(filename)) strcpy(outmsg, "CERRORUNAUTHORIZED REQUEST"); else if(inmsg[0] != 'R') strcpy(outmsg, "CERRORBAD REQUEST FORMAT"); else if(requested_chunk < 0) strcpy(outmsg, "CERRORBAD CHUNK REQUEST"); else if(requested_chunk == 0) /* number of chunks requested */ { if(total_chunks == -1) strcpy(outmsg, "CERRORCANNOT STAT FILE"); else if(total_chunks == 0) strcpy(outmsg, "CERRORFILE SIZE NULL"); else if(total_chunks > 99999) strcpy(outmsg, "CERRORTOO MANY CHUNKS"); else { sprintf(temp, "%d", total_chunks); strcpy(outmsg, "CCHNKS"); strcat(outmsg, temp); } } else /* construct data message */ { status = GetFileChunk(filename, requested_chunk, data, &datsize); if(status != 0) { if(status == -1) strcpy(outmsg, "CERRORFILE SIZE NULL"); else if (status == -2) strcpy(outmsg, "CERRORCANNOT STAT FILE"); else if(status == -3) strcpy(outmsg, "CERRORCHUNK OUT OF BOUND"); else strcpy(outmsg, "CERRORUNKNOWN ERROR"); } else { /* MSGTYPE */ strcpy(outmsg, "D"); /* CHUNK */ sprintf(temp, "%d", requested_chunk); for(i = 0; i < CHUNK_LEN - strlen(temp); i++) strcat(outmsg, " "); strcat(outmsg, temp); /* data */ strcat(outmsg, data); outmsg[datsize + MSGTYPE_LEN + CHUNK_LEN] = '\0'; } } }
void CJoinDialog::OnBnClickedJoinNow(wxCommandEvent& WXUNUSED(event)) { gpApp->LogUserAction(_T("Initiated OnBnClockedJoinNow()")); // BEW added 23Jun07 gbDoingSplitOrJoin = TRUE; // use to suppress document backups generation during the joining bool MergeIntoCurrentDoc; wxString MergeFileName; wxString MergeFilePath; wxString OldCurrentDocumentFileName; int i; wxString FileName; wxString FilePath; if (pAcceptedFiles->GetCount() == 0) { wxMessageBox(_("There are no files listed for joining to the current document."),_T(""),wxICON_EXCLAMATION | wxOK); //TellUser(IDS_NONE_FOR_JOINING); gbDoingSplitOrJoin = FALSE; // restore default return; } // Show the "Joining... Please wait." message this->pJoiningWait->Show(TRUE); this->pJoiningWait->Update(); #ifdef _DEBUG // check the reordering user does gets reflected in the AcceptedFiles list (it does) int cnt = pAcceptedFiles->GetCount(); int ii; wxString s; for (ii=0;ii<cnt;ii++) { s = pAcceptedFiles->GetString(ii); } #endif OldCurrentDocumentFileName = gpApp->GetCurrentDocFileName(); // Determine merge destination filename. MergeFileName = pNewFileName->GetValue(); MergeFileName.Trim(FALSE); // trim left end MergeFileName.Trim(TRUE); // trim right end MergeIntoCurrentDoc = MergeFileName.IsEmpty(); if (!MergeIntoCurrentDoc) { MergeFileName = CAdapt_ItApp::ApplyDefaultDocFileExtension(MergeFileName); if (MergeFileName.CmpNoCase(OldCurrentDocumentFileName) == 0) { MergeIntoCurrentDoc = true; MergeFileName = OldCurrentDocumentFileName; } } if (MergeIntoCurrentDoc) { MergeFileName = OldCurrentDocumentFileName; } MergeFilePath = ConcatenatePathBits(gpApp->GetCurrentDocFolderPath(), MergeFileName); // Ensure merge destination filename is valid. if (!MergeIntoCurrentDoc) { if (!IsValidFileName(MergeFileName)) { wxMessageBox(_("The new file name you supplied contains characters that are not permitted in a file name. Please edit the file name."),_T(""),wxICON_EXCLAMATION | wxOK); //TellUser(IDS_BAD_FNAME_FOR_JOIN); this->pJoiningWait->Show(FALSE); gbDoingSplitOrJoin = FALSE; // restore default return; } } // Ensure merge destination filename does not exist, or that if it does, // it is one of the merge source filenames. if (!MergeIntoCurrentDoc) { bool CantOverwrite = false; if (FileExists(MergeFilePath)) { CantOverwrite = true; for (i = 0; i < (int)pAcceptedFiles->GetCount(); ++i) { FileName = pAcceptedFiles->GetString(i); if (FileName.CmpNoCase(MergeFileName) == 0) { CantOverwrite = false; break; } } if (CantOverwrite) { wxMessageBox(_("The resulting document's file name must be unique or must be the same as one of the input files."),_T(""),wxICON_EXCLAMATION | wxOK); //TellUser(IDS_UNIQUE_OR_SAME_FOR_JOIN); this->pJoiningWait->Show(FALSE); gbDoingSplitOrJoin = FALSE; // restore default return; } } } // BEW 18Oct14, added failure protection. First, make a temporary copy of the open // document in case we fail when merging the files into the current open document - in // a fail scenario, we'd clobber the altered current document, and rename the temporary // copy as that document so that it is restored, and return so that none of the // original files get removed and nothing renamed. wxString tempStr = _T("temp_"); wxString tempCurrent = tempStr + OldCurrentDocumentFileName; wxString pathAndTempCurrent = ConcatenatePathBits(gpApp->GetCurrentDocFolderPath(),tempCurrent); wxString pathAndOldCurrent = ConcatenatePathBits(gpApp->GetCurrentDocFolderPath(),OldCurrentDocumentFileName); bool bSuccessful_1 = ::wxCopyFile(pathAndOldCurrent, pathAndTempCurrent); // we expect success CAdapt_ItView* pView = gpApp->GetView(); // Our needed backup is created, now proceed to the joining // In this loop we do the actual joining. bool bNoIDMismatch = TRUE; for (i = 0; i < (int)pAcceptedFiles->GetCount(); ++i) { // Algorithm: (BEW modified 07Nov05) added bookID to signature) // For each source document: // Read the source phrase list and append that list to the current source phrase list; // but abort the joining operation if the bookID code does not match the bookID // passed in for the current source phrase list. FileName = pAcceptedFiles->GetString(i); FilePath = ConcatenatePathBits(gpApp->GetCurrentDocFolderPath(), FileName); SPList* ol = gpApp->LoadSourcePhraseListFromFile(FilePath); bool bAtLastDoc = (i == (int)pAcceptedFiles->GetCount() - 1); bNoIDMismatch = gpApp->AppendSourcePhrasesToCurrentDoc(ol, bookID, bAtLastDoc); //#if defined(_DEBUG) // Test the bNoIDMismatch == TRUE recovery blocks below (I added renamed copies // of ch2 and ch3 as ch4 and ch5 for my tests, and will remove those files now) //if (i == 1) //{ // bNoIDMismatch = FALSE; //} //#endif if (!bNoIDMismatch) { // tell the user of the book ID mismatch, and then abort the joining of this and subsequent documents, // if any -- the user message should indicate which doc (using FileName) is the offending one wxString msg; msg = msg.Format(_("The book ID in the document with filename %s does not match the book ID for the currently open document."),FileName.c_str()); wxMessageBox(msg,_T(""),wxICON_EXCLAMATION | wxOK); // BEW 18Oct14, restore the pre-Join state if things went pear shape. ol->Clear(); // we don't want the concatenated list so far constructed if (::wxFileExists(pathAndOldCurrent) && bSuccessful_1) { // Remove the partially added to current doc, provided we were // able to successfully create a temporary copy of it before anything // was joined to it; if we didn't succeed in making the copy, then // keep it as-is, that's better than losing the data - and let the // user try work out what to do (making the temporary copy should // never fail, so there's not much risk of such a mess happening) ::wxRemoveFile(pathAndOldCurrent); // don't care about returned boolean } // Now restore the old current one by renaming the temporary copy bool bOkay = TRUE; if (bSuccessful_1) { // doc of first renamed to second, default bool overwrite is true bOkay = wxRenameFile(pathAndTempCurrent, pathAndOldCurrent); } // Restore the view under the open dialog window gpApp->GetDocument()->DeleteContents(); // m_pSourcePhrases is now empty, & strips & piles clobbered SPList* ol = gpApp->LoadSourcePhraseListFromFile(pathAndOldCurrent); // We can ignore the returned boolean in next call, the book ID won't // have changed, and TRUE means this is the last append (in this case // it is also the only append) gpApp->AppendSourcePhrasesToCurrentDoc(ol, bookID, TRUE); CCell* pCell = gpApp->m_pActivePile->GetCell(1); int activeSN = gpApp->m_pActivePile->GetSrcPhrase()->m_nSequNumber; pView->PlacePhraseBox(pCell,1); gpApp->m_pActivePile = pView->GetPile(activeSN); // restore active pile ptr pView->Invalidate(); gpApp->GetMainFrame()->canvas->ScrollIntoView(activeSN); // Trigger a re-layout/re-render of the current document. gpApp->CascadeSourcePhraseListChange(true); InitialiseLists(); this->pJoiningWait->Show(FALSE); gbDoingSplitOrJoin = FALSE; // restore default so document backups can happen again wxString msg1Yes = _("Joining documents exited prematurely because of a mismatched book ID code. Restoring the pre-join state succeeded."); wxString msg1No = _("Joining documents exited prematurely because of a mismatched book ID code. Restoring the pre-join state failed. Beware, the open document may have some documents appended."); if (bOkay) { // Success message wxMessageBox(msg1Yes, _T(""),wxICON_EXCLAMATION | wxOK); gpApp->LogUserAction(msg1Yes); } else { // Failure message, with a warning wxMessageBox(msg1No,_T(""),wxICON_EXCLAMATION | wxOK); gpApp->LogUserAction(msg1No); } ol->Clear(); // clear, but don't delete contents as they are now managed by m_pSourcePhrases if (ol != NULL) // whm 11Jun12 added NULL test delete ol; // Clear the typed doc name box, for a failure & restoration it should not be // left with something in it pNewFileName->Clear(); return; // to the dialog window } // end of TRUE block for test: if (!bNoIDMismatch) -- for recovery upon error ol->Clear(); // clear, but don't delete contents as they are now managed by m_pSourcePhrases if (ol != NULL) // whm 11Jun12 added NULL test delete ol; } // end of for loop for joining them // After a successful join, clobber the temporary copied document if (bSuccessful_1) { if (::wxFileExists(pathAndTempCurrent)) { ::wxRemoveFile(pathAndTempCurrent); // don't care about returned boolean } } // Refresh the document view if the parameter passed in is true, skip the update // if false is passed in gpApp->CascadeSourcePhraseListChange(false); // Change underlying filename if applicable. if (!MergeIntoCurrentDoc) { gpApp->ChangeDocUnderlyingFileDetailsInPlace(gpApp->GetCurrentDocFolderPath(), MergeFileName); } // Save. gpApp->SaveDocChanges(); // Delete source files, except current document, although even delete the old current document if // we've changed filename and thus have a new current document. // (As of 2011 (or thereabouts) we no longer have a MRU list, so we don't have to // remove anything from such a list because the document inventory may have changed.) if (bNoIDMismatch) { // no book ID mismatch occurred, so all the files in the list were processed; the // list should be empty when the user next sees the Join dialog window for (i = 0; i < (int)pAcceptedFiles->GetCount(); ++i) { FileName = pAcceptedFiles->GetString(i); if (FileName.CmpNoCase(MergeFileName) != 0) { ::wxRemoveFile(ConcatenatePathBits(gpApp->GetCurrentDocFolderPath(), FileName)); } } if (OldCurrentDocumentFileName.CmpNoCase(MergeFileName) != 0) { ::wxRemoveFile(ConcatenatePathBits(gpApp->GetCurrentDocFolderPath(), OldCurrentDocumentFileName)); } } /* // BEW 18Oct14, in the case of a mismatch of book ID, we above attempt to restore the // original pre-join state of the documents, and return from this handler early. So // this legacy code of Jonathan's is no longer needed. else { // a book ID mismatch was detected, so not all the files in the list were processed. The i index // value is was left equal to the index of the first filename in the list which was not processed, // so only delete the files which were processed. int j; for (j = 0; j < i; ++j) { FileName = pAcceptedFiles->GetString(j); if (FileName.CmpNoCase(MergeFileName) != 0) { ::wxRemoveFile(ConcatenatePathBits(gpApp->GetCurrentDocFolderPath(), FileName)); } } if (OldCurrentDocumentFileName.CmpNoCase(MergeFileName) != 0) { ::wxRemoveFile(ConcatenatePathBits(gpApp->GetCurrentDocFolderPath(), OldCurrentDocumentFileName)); } } */ // Trigger a re-layout/re-render of the current document. gpApp->CascadeSourcePhraseListChange(true); InitialiseLists(); this->pJoiningWait->Show(FALSE); // update Title bar (BEW added 14Aug09) CAdapt_ItDoc* d = gpApp->GetDocument(); wxString strUserTyped = gpApp->m_curOutputFilename; d->SetDocumentWindowTitle(strUserTyped, strUserTyped); wxMessageBox(_("Joining to the current document was successful."),_T(""),wxICON_INFORMATION | wxOK); gpApp->LogUserAction(_T("Joining to the current document was successful.")); gpApp->RefreshStatusBarInfo(); gbDoingSplitOrJoin = FALSE; // restore default so document backups can happen again }