Compare commits
10 Commits
6b366451ed
...
b0.1.0
Author | SHA1 | Date | |
---|---|---|---|
fc83b60d85 | |||
44b6792ae9 | |||
95828afcc2 | |||
92bd9a70a3 | |||
4d967d8a8e | |||
5e74a99062 | |||
5a0f92deec | |||
67b8e302be | |||
5f593682e2 | |||
47043afb83 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -41,3 +41,4 @@
|
|||||||
|
|
||||||
reHDD
|
reHDD
|
||||||
|
|
||||||
|
reHDD.log
|
||||||
|
77
README.md
77
README.md
@ -3,12 +3,77 @@
|
|||||||
## Useful for:
|
## Useful for:
|
||||||
* checking new drives for the first time
|
* checking new drives for the first time
|
||||||
* checking used drives for their next live
|
* checking used drives for their next live
|
||||||
* deleting a drive securely
|
* deleting a drive securely via overwriting
|
||||||
|
|
||||||
## planned Features:
|
## Screenshot
|
||||||
|

|
||||||
|
|
||||||
* search for new attached Hard Drives via USB
|
## Debian Build Notes
|
||||||
* display Hard Drive Manufacturer, Model, Rotation Rate and Capacity
|
|
||||||
* Check S.M.A.R.T. values and make an 'passed' or 'not passed' decision
|
* apt-get install ncurses-dev git make g++
|
||||||
* If passed, wipe the data securely
|
* clone repo
|
||||||
|
* make release
|
||||||
|
|
||||||
|
## Create Standalone with Debian
|
||||||
|
|
||||||
|
Instructions how to create a standalone machine that boots directly to reHDD. This is aimed for production use, like several drives a day shredding.
|
||||||
|
|
||||||
|
### Software requirements
|
||||||
|
|
||||||
|
* apt-get install hwinfo
|
||||||
|
* wget http://ftp.de.debian.org/debian/pool/main/s/smartmontools/smartmontools_7.1-1_amd64.deb
|
||||||
|
* dpkg --install smartmontools_7.1-1_amd64.deb
|
||||||
|
|
||||||
|
### Start reHDD after boot without login (as a tty shell)
|
||||||
|
|
||||||
|
nano /etc/systemd/system/reHDD.service
|
||||||
|
```
|
||||||
|
[Unit]
|
||||||
|
Description=Custom user interface on tty1
|
||||||
|
Conflicts=getty@tty1.service
|
||||||
|
Before=getty.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
WorkingDirectory=/root/reHDD
|
||||||
|
ExecStart=/root/reHDD/reHDD
|
||||||
|
StandardInput=tty
|
||||||
|
StandardOutput=tty
|
||||||
|
Restart=always
|
||||||
|
RestartSec=1
|
||||||
|
UtmpIdentifier=tty1
|
||||||
|
TTYPath=/dev/tty1
|
||||||
|
TTYReset=yes
|
||||||
|
TTYVHangup=yes
|
||||||
|
TTYVTDisallocate=yes
|
||||||
|
SendSIGHUP=yes
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
```
|
||||||
|
|
||||||
|
nano /etc/systemd/system/reHDDSettings.service
|
||||||
|
```
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
RemainAfterExit=yes
|
||||||
|
ExecStart=/usr/bin/bash /root/reHDDSettings.sh
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
```
|
||||||
|
|
||||||
|
nano /root/reHDDSettings.sh
|
||||||
|
```
|
||||||
|
#!/bin/bash
|
||||||
|
dmesg -n 1 #disable overlay if a drive is attached/detached
|
||||||
|
rm -f /root/reHDD/reHDD.log
|
||||||
|
```
|
||||||
|
Make sure the binary reHDD is in /root/reHDD/
|
||||||
|
Add your system drive in /root/reHDD/ignoreDrives.conf like:
|
||||||
|
``` /dev/sdX:e102f49d-5ed5-462b-94c5-ef66a4345671```
|
||||||
|
Get your UUID via blkid /dev/sdX
|
||||||
|
|
||||||
|
systemctl enable reHDD.service
|
||||||
|
|
||||||
|
systemctl enable reHDDSettings.service
|
||||||
|
|
||||||
|
BIN
doc/screenshot.png
Normal file
BIN
doc/screenshot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 54 KiB |
@ -1,3 +1 @@
|
|||||||
/dev/sdc:4673974d-1af2-44fd-996b-a2d8e4c43d9a
|
|
||||||
/dev/sda:508ef27d-5039-4e8b-9e2c-22d7528b7149
|
|
||||||
/dev/sdb:32b66944-ffa0-40e9-817c-3f0c52eefaf4
|
|
||||||
|
@ -18,7 +18,8 @@ public:
|
|||||||
SHRED_SELECTED,
|
SHRED_SELECTED,
|
||||||
SHRED_ACTIVE,
|
SHRED_ACTIVE,
|
||||||
DELETE_SELECTED,
|
DELETE_SELECTED,
|
||||||
DELETE_ACTIVE
|
DELETE_ACTIVE,
|
||||||
|
FROZEN
|
||||||
} state;
|
} state;
|
||||||
|
|
||||||
bool bWasShredded = false;
|
bool bWasShredded = false;
|
||||||
@ -34,9 +35,11 @@ private:
|
|||||||
uint32_t u32ErrorCount = 0U;
|
uint32_t u32ErrorCount = 0U;
|
||||||
uint32_t u32PowerOnHours = 0U; //in hours
|
uint32_t u32PowerOnHours = 0U; //in hours
|
||||||
uint32_t u32PowerCycles = 0U;
|
uint32_t u32PowerCycles = 0U;
|
||||||
|
time_t u32Timestamp = 0U; //unix timestamp for detecting a frozen drive
|
||||||
double d32TaskPercentage = 0U; //in percent for Shred (1 to 100)
|
double d32TaskPercentage = 0U; //in percent for Shred (1 to 100)
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setTimestamp();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@ -54,6 +57,7 @@ public:
|
|||||||
uint32_t getErrorCount(void);
|
uint32_t getErrorCount(void);
|
||||||
uint32_t getPowerOnHours(void); //in hours
|
uint32_t getPowerOnHours(void); //in hours
|
||||||
uint32_t getPowerCycles(void);
|
uint32_t getPowerCycles(void);
|
||||||
|
void checkFrozenDrive(void);
|
||||||
|
|
||||||
void setDriveSMARTData( string modelFamily,
|
void setDriveSMARTData( string modelFamily,
|
||||||
string modelName,
|
string modelName,
|
||||||
|
@ -8,15 +8,15 @@
|
|||||||
#ifndef REHDD_H_
|
#ifndef REHDD_H_
|
||||||
#define REHDD_H_
|
#define REHDD_H_
|
||||||
|
|
||||||
|
#define REHDD_VERSION "bV0.1.0"
|
||||||
|
|
||||||
//#define DRYRUN
|
//#define DRYRUN
|
||||||
|
|
||||||
|
// Drive handling Settings
|
||||||
#define WORSE_HOURS 19200 //mark drive if at this limit or beyond
|
#define WORSE_HOURS 19200 //mark drive if at this limit or beyond
|
||||||
#define WORSE_POWERUP 10000 //mark drive if at this limit or beyond
|
#define WORSE_POWERUP 10000 //mark drive if at this limit or beyond
|
||||||
|
#define SHRED_ITERATIONS 3
|
||||||
#define SHRED_ITERATIONS 1
|
#define FROZEN_TIMEOUT 5 //After this timeout (minutes) the drive will be marked as frozen
|
||||||
|
|
||||||
#define READ 0
|
|
||||||
#define WRITE 1
|
|
||||||
|
|
||||||
// Logger Settings
|
// Logger Settings
|
||||||
#define LOG_PATH "./reHDD.log"
|
#define LOG_PATH "./reHDD.log"
|
||||||
@ -30,6 +30,10 @@
|
|||||||
#define LOG_LEVEL_LOW //log only user actions and tasks
|
#define LOG_LEVEL_LOW //log only user actions and tasks
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//IPC pipes
|
||||||
|
#define READ 0
|
||||||
|
#define WRITE 1
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@ -82,6 +86,7 @@ private:
|
|||||||
static void ThreadScannDevices();
|
static void ThreadScannDevices();
|
||||||
static void ThreadUserInput();
|
static void ThreadUserInput();
|
||||||
static void ThreadShred();
|
static void ThreadShred();
|
||||||
|
static void ThreadCheckFrozenDrives();
|
||||||
static void handleArrowKey(TUI::UserInput userInput);
|
static void handleArrowKey(TUI::UserInput userInput);
|
||||||
static void handleEnter();
|
static void handleEnter();
|
||||||
static void handleESC();
|
static void handleESC();
|
||||||
|
@ -60,6 +60,7 @@ private:
|
|||||||
static WINDOW *createSystemStats(int iXSize, int iYSize, int iYStart);
|
static WINDOW *createSystemStats(int iXSize, int iYSize, int iYStart);
|
||||||
static WINDOW *createMenuView(int iXSize, int iYSize, int iXStart, int iYStart, struct MenuState menustate);
|
static WINDOW *createMenuView(int iXSize, int iYSize, int iXStart, int iYStart, struct MenuState menustate);
|
||||||
static WINDOW *createDialog(int iXSize, int iYSize, int iXStart, int iYStart, string selectedTask, string optionA, string optionB);
|
static WINDOW *createDialog(int iXSize, int iYSize, int iXStart, int iYStart, string selectedTask, string optionA, string optionB);
|
||||||
|
static WINDOW* createFrozenWarning(int iXSize, int iYSize, int iXStart, int iYStart, string sPath, string sModelFamily, string sModelName, string sSerial);
|
||||||
|
|
||||||
void displaySelectedDrive(Drive drive, int stdscrX, int stdscrY);
|
void displaySelectedDrive(Drive drive, int stdscrX, int stdscrY);
|
||||||
|
|
||||||
|
@ -91,6 +91,7 @@ void Drive::setTaskPercentage(double d32TaskPercentage)
|
|||||||
if(d32TaskPercentage <= 100)
|
if(d32TaskPercentage <= 100)
|
||||||
{
|
{
|
||||||
this->d32TaskPercentage = d32TaskPercentage;
|
this->d32TaskPercentage = d32TaskPercentage;
|
||||||
|
this->setTimestamp(); //set timestamp for this progress for detecting a frozen drive
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
double Drive::getTaskPercentage(void)
|
double Drive::getTaskPercentage(void)
|
||||||
@ -126,3 +127,23 @@ void Drive::setDriveSMARTData( string modelFamily,
|
|||||||
u32PowerOnHours = powerOnHours;
|
u32PowerOnHours = powerOnHours;
|
||||||
u32PowerCycles = powerCycle;
|
u32PowerCycles = powerCycle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Drive::setTimestamp()
|
||||||
|
{
|
||||||
|
time(&this->u32Timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Drive::checkFrozenDrive(void)
|
||||||
|
{
|
||||||
|
time_t u32localtime;
|
||||||
|
time(&u32localtime);
|
||||||
|
|
||||||
|
if((u32localtime - this->u32Timestamp) >= (FROZEN_TIMEOUT*60) && (this->u32Timestamp > 0))
|
||||||
|
{
|
||||||
|
Logger::logThis()->warning("Drive Frozen: " + this->getModelName() + " " + this->getSerial());
|
||||||
|
this->bWasDeleteted = false;
|
||||||
|
this->bWasShredded = false;
|
||||||
|
this->state = Drive::FROZEN;
|
||||||
|
}
|
||||||
|
}
|
@ -52,6 +52,7 @@ void reHDD::app_logic(void)
|
|||||||
|
|
||||||
thread thDevices(ThreadScannDevices); //start thread that scanns for drives
|
thread thDevices(ThreadScannDevices); //start thread that scanns for drives
|
||||||
thread thUserInput(ThreadUserInput); //start thread that reads user input
|
thread thUserInput(ThreadUserInput); //start thread that reads user input
|
||||||
|
thread thCheckFrozenDrives(ThreadCheckFrozenDrives); //start thread that checks timeout for drives
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
@ -60,15 +61,14 @@ void reHDD::app_logic(void)
|
|||||||
FD_SET(fdShredInformPipe[0], &selectSet);
|
FD_SET(fdShredInformPipe[0], &selectSet);
|
||||||
|
|
||||||
select(FD_SETSIZE, &selectSet, NULL, NULL, NULL);
|
select(FD_SETSIZE, &selectSet, NULL, NULL, NULL);
|
||||||
|
mxScannDrives.lock();
|
||||||
if( FD_ISSET(fdNewDrivesInformPipe[0], &selectSet))
|
if( FD_ISSET(fdNewDrivesInformPipe[0], &selectSet))
|
||||||
{
|
{
|
||||||
char dummy;
|
char dummy;
|
||||||
read (fdNewDrivesInformPipe[0],&dummy,1);
|
read (fdNewDrivesInformPipe[0],&dummy,1);
|
||||||
mxScannDrives.lock();
|
|
||||||
filterNewDrives(&vecDrives, &vecNewDrives); //filter and copy to app logic vector
|
filterNewDrives(&vecDrives, &vecNewDrives); //filter and copy to app logic vector
|
||||||
printDrives(&vecDrives);
|
printDrives(&vecDrives);
|
||||||
mxScannDrives.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FD_ISSET(fdShredInformPipe[0], &selectSet))
|
if (FD_ISSET(fdShredInformPipe[0], &selectSet))
|
||||||
@ -77,9 +77,11 @@ void reHDD::app_logic(void)
|
|||||||
read (fdShredInformPipe[0],&dummy,1);
|
read (fdShredInformPipe[0],&dummy,1);
|
||||||
}
|
}
|
||||||
ui->updateTUI(&vecDrives, u8SelectedEntry);
|
ui->updateTUI(&vecDrives, u8SelectedEntry);
|
||||||
|
mxScannDrives.unlock();
|
||||||
} //endless loop
|
} //endless loop
|
||||||
thDevices.join();
|
thDevices.join();
|
||||||
thUserInput.join();
|
thUserInput.join();
|
||||||
|
thCheckFrozenDrives.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
Drive* reHDD::getSelectedDrive()
|
Drive* reHDD::getSelectedDrive()
|
||||||
@ -110,6 +112,25 @@ void reHDD::ThreadScannDevices()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void reHDD::ThreadCheckFrozenDrives()
|
||||||
|
{
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
mxScannDrives.lock();
|
||||||
|
for(auto it = begin(vecDrives); it != end(vecDrives); ++it)
|
||||||
|
{
|
||||||
|
if(it->state == Drive::SHRED_ACTIVE)
|
||||||
|
{
|
||||||
|
it->checkFrozenDrive();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mxScannDrives.unlock();
|
||||||
|
sleep(5); //sleep 5 sec
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void reHDD::ThreadUserInput()
|
void reHDD::ThreadUserInput()
|
||||||
{
|
{
|
||||||
while(true)
|
while(true)
|
||||||
@ -216,7 +237,7 @@ void reHDD::filterNewDrives(vector <Drive>* pvecOldDrives, vector <Drive>* pvecN
|
|||||||
itOld->bIsOffline = true; //set offline befor seachring in the new list
|
itOld->bIsOffline = true; //set offline befor seachring in the new list
|
||||||
for (itNew = pvecNewDrives->begin(); itNew != pvecNewDrives->end();)
|
for (itNew = pvecNewDrives->begin(); itNew != pvecNewDrives->end();)
|
||||||
{
|
{
|
||||||
if(itOld->getSerial() == itNew->getSerial())
|
if((itOld->getSerial() == itNew->getSerial()) || (itOld->getPath() == itNew->getPath()))
|
||||||
{
|
{
|
||||||
itOld->bIsOffline = false; //drive is still attached
|
itOld->bIsOffline = false; //drive is still attached
|
||||||
#ifdef LOG_LEVEL_HIGH
|
#ifdef LOG_LEVEL_HIGH
|
||||||
|
@ -21,6 +21,7 @@ struct tfnge_stream
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct tfnge_stream tfnge;
|
static struct tfnge_stream tfnge;
|
||||||
|
#endif
|
||||||
|
|
||||||
Shred::Shred()
|
Shred::Shred()
|
||||||
{
|
{
|
||||||
@ -34,7 +35,7 @@ Shred::~Shred()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
/**
|
/**
|
||||||
* \brief shred drive with shred
|
* \brief shred drive with shred
|
||||||
* \param pointer of Drive instance
|
* \param pointer of Drive instance
|
||||||
@ -51,7 +52,6 @@ void Shred::shredDrive(Drive* drive, int* ipSignalFd)
|
|||||||
}
|
}
|
||||||
drive->setTaskPercentage(i+0.05);
|
drive->setTaskPercentage(i+0.05);
|
||||||
write(*ipSignalFd, "A",1);
|
write(*ipSignalFd, "A",1);
|
||||||
|
|
||||||
usleep(20000);
|
usleep(20000);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
54
src/tui.cpp
54
src/tui.cpp
@ -111,6 +111,10 @@ void TUI::updateTUI(vector <Drive>* pvecDrives, uint8_t u8SelectedEntry)
|
|||||||
sState = "SHREDDED"; //mark drive as shreded previously, overwrite if deleted
|
sState = "SHREDDED"; //mark drive as shreded previously, overwrite if deleted
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case Drive::FROZEN:
|
||||||
|
dialog=createFrozenWarning(70, 16, ((stdscrX)-(int)(stdscrX/2)-35),(int)(stdscrY/2)-8, it->getPath(), it->getModelFamily(), it->getModelName(), it->getSerial());
|
||||||
|
wrefresh(dialog);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -274,23 +278,23 @@ WINDOW* TUI::overwriteDetailViewWindow( int iXSize, int iYSize, int iXStart)
|
|||||||
string title = "About this tool";
|
string title = "About this tool";
|
||||||
centerTitle(newWindow, title.c_str());
|
centerTitle(newWindow, title.c_str());
|
||||||
|
|
||||||
string sLine01 = "Path: NextLine ";
|
string sLine01 = "reHDD - hard drive refurbishing tool";
|
||||||
string sLine02 = "Path: NextLine ";
|
string sLine02 = "Version: " + string(REHDD_VERSION);
|
||||||
string sLine03 = "Path: NextLine ";
|
string sLine03 = "Available under GPL 3.0";
|
||||||
string sLine04 = "Path: NextLine ";
|
string sLine04 = "https://git.mosad.xyz/localhorst/reHDD";
|
||||||
string sLine05 = "Path: NextLine ";
|
string sLine05 = "Delete: Wipe format table - this is NOT secure";
|
||||||
string sLine06 = "Path: NextLine ";
|
string sLine06 = "Shred: Overwite drive " + to_string(SHRED_ITERATIONS) + " iterations - this is secure";
|
||||||
string sLine07 = "Path: NextLine ";
|
|
||||||
|
|
||||||
uint16_t u16Line = 5;
|
uint16_t u16Line = 5;
|
||||||
|
|
||||||
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), sLine01.c_str());
|
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine01.size()/2), sLine01.c_str());
|
||||||
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine02.size()/2), sLine02.c_str());
|
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine02.size()/2), sLine02.c_str());
|
||||||
|
u16Line++;
|
||||||
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine03.size()/2), sLine03.c_str());
|
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine03.size()/2), sLine03.c_str());
|
||||||
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine04.size()/2), sLine04.c_str());
|
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine04.size()/2), sLine04.c_str());
|
||||||
|
u16Line++;
|
||||||
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine05.size()/2), sLine05.c_str());
|
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine05.size()/2), sLine05.c_str());
|
||||||
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine06.size()/2), sLine06.c_str());
|
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine06.size()/2), sLine06.c_str());
|
||||||
mvwaddstr(newWindow,u16Line++, (iXSize/2)-(sLine07.size()/2), sLine07.c_str());
|
|
||||||
|
|
||||||
attroff(COLOR_PAIR(COLOR_AREA_DETAIL));
|
attroff(COLOR_PAIR(COLOR_AREA_DETAIL));
|
||||||
|
|
||||||
@ -395,6 +399,40 @@ WINDOW* TUI::createDialog(int iXSize, int iYSize, int iXStart, int iYStart, stri
|
|||||||
return newWindow;
|
return newWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WINDOW* TUI::createFrozenWarning(int iXSize, int iYSize, int iXStart, int iYStart, string sPath, string sModelFamily, string sModelName, string sSerial)
|
||||||
|
{
|
||||||
|
WINDOW *newWindow;
|
||||||
|
newWindow = newwin(iYSize, iXSize, iYStart, iXStart);
|
||||||
|
|
||||||
|
wbkgd(newWindow, COLOR_PAIR(COLOR_AREA_ENTRY_SELECTED));
|
||||||
|
box(newWindow, ACS_VLINE, ACS_HLINE);
|
||||||
|
|
||||||
|
string sHeader = "Drive " + sPath + " is frozen";
|
||||||
|
string sLine01 = "Please detach this drive and check it manually:";
|
||||||
|
string sLinePath = "Path: " +sPath;
|
||||||
|
string sLineModelFamlily = "ModelFamily: " + sModelFamily;
|
||||||
|
string sLineModelName = "ModelName: " + sModelName;
|
||||||
|
string sLineSerial = "Serial: " + sSerial;
|
||||||
|
|
||||||
|
string sLine02 = "reHDD was not able to write data to the drive.";
|
||||||
|
string sLine03 = "This can be caused by an malfunctioning drive.";
|
||||||
|
|
||||||
|
centerTitle(newWindow, sHeader.c_str());
|
||||||
|
|
||||||
|
uint16_t u16Line = 2;
|
||||||
|
mvwaddstr(newWindow,u16Line++, 3, sLine01.c_str());
|
||||||
|
u16Line++;
|
||||||
|
mvwaddstr(newWindow,u16Line++, 3, sLinePath.c_str());
|
||||||
|
mvwaddstr(newWindow,u16Line++, 3, sLineModelFamlily.c_str());
|
||||||
|
mvwaddstr(newWindow,u16Line++, 3, sLineModelName.c_str());
|
||||||
|
mvwaddstr(newWindow,u16Line++, 3, sLineSerial.c_str());
|
||||||
|
u16Line++;
|
||||||
|
mvwaddstr(newWindow,u16Line++, 3, sLine02.c_str());
|
||||||
|
mvwaddstr(newWindow,u16Line++, 3, sLine03.c_str());
|
||||||
|
|
||||||
|
return newWindow;
|
||||||
|
}
|
||||||
|
|
||||||
void TUI::displaySelectedDrive(Drive drive, int stdscrX, int stdscrY)
|
void TUI::displaySelectedDrive(Drive drive, int stdscrX, int stdscrY)
|
||||||
{
|
{
|
||||||
struct MenuState menustate;
|
struct MenuState menustate;
|
||||||
|
Reference in New Issue
Block a user