I am trying to create a program that functions similar to a task manager along with many other capabilities. Currently, I am having trouble finding all the top-level windows with my current enumeration function. For some reason, it enumerates and fills out the HWND for some applications properly ( e.g. Google Chrome, Command Prompt, Code::Blocks ), but not for some games( e.g. Roblox ( only one I tested ) ). I tried to see if maybe FindWindow() would fail too, but it worked fine in that context. Which means that EnumWindows() should obviously find it, but apparently I either did something wrong or I read something wrong in the documentation. I really don't want to have to use FindWindow( ) when I probably won't know the title of most windows anyways.
Enumeration function :
BOOL CALLBACK FindWindows( HWND handle, LPARAM option )
{
DWORD window_process_id = 0;
GetWindowThreadProcessId( handle, &window_process_id );
process_list * p1 = NULL;
switch ( option )
{
case FIND_WINDOW_HANDLE :
if ( IsWindowEnabled( handle ) )
for ( p1 = head_copy; p1; p1 = p1->next )
if ( p1->pid == window_process_id )
p1->window_handle = handle;
break;
default :
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
break;
}
return TRUE;
}
Full source :
/* Preprocessor directives */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <windows.h>
#include <tlhelp32.h>
#include <tchar.h>
#define TARGET_PROCESS "chrome.exe"
/* Structures */
typedef struct process_list
{
char * process_name;
DWORD pid;
HANDLE process_handle;
HWND window_handle;
int process_name_sz;
struct process_list * next;
} process_list;
typedef struct drawing_data
{
RECT window_pos;
} drawing_data;
/* Enums ( Global integer constants ) */
enum
{
FIND_WINDOW_HANDLE
};
enum
{
TIMER_START,
TIMER_STOP,
TIMER_GETDIFF
};
typedef struct t_timer
{
clock_t start_time;
clock_t end_time;
} t_timer;
/* Global variables */
process_list * head_copy = NULL;
/* ***************************************************************** */
/* Time functions */
clock_t timer( int command, t_timer * timer1 )
{
switch ( command )
{
case TIMER_START :
timer1->start_time = clock( );
break;
case TIMER_STOP :
timer1->end_time = clock( );
break;
case TIMER_GETDIFF :
return ( ( timer1->end_time - timer1->start_time ) / ( CLOCKS_PER_SEC / 1000 ));
break;
default : break;
}
return -1;
}
/* ***************************************************************** */
/* Windows error functions */
void show_error( char * user_string, BOOL exit )
{
char buffer[BUFSIZ] = { 0 };
DWORD error_code = GetLastError( );
FormatMessage
(
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
error_code,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) buffer,
BUFSIZ,
NULL
);
printf( "%s : %s", user_string, buffer );
if ( exit ) ExitProcess( error_code );
return;
}
/* ***************************************************************** */
void win_error( char * message, BOOL exit )
{
char buffer[BUFSIZ] = { 0 };
DWORD error_code = GetLastError( );
FormatMessage
(
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
error_code,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) buffer,
BUFSIZ,
NULL
);
MessageBox(NULL, buffer, "Error from System :", MB_ICONWARNING | MB_OK );
if ( exit ) ExitProcess( error_code );
return;
}
/* ***************************************************************** */
/* Linked list functions */
process_list * create( )
{
process_list * temp = NULL;
if ( !( temp = malloc( sizeof( process_list ) ) ) )
{
perror("Malloc");
exit( 1 );
}
return temp;
}
/* ***************************************************************** */
process_list * add( process_list * head, HANDLE process_handle, PROCESSENTRY32 * process_structure )
{
process_list * temp = NULL;
if ( !head )
{
head = create( );
head->pid = process_structure->th32ParentProcessID;
head->process_handle = process_handle;
head->process_name_sz = strlen( process_structure->szExeFile ) + 1;
head->process_name = malloc( head->process_name_sz );
if ( !head->process_name )
{
perror( "Malloc" );
exit( 1 );
}
strcpy( head->process_name, process_structure->szExeFile );
head->next = NULL;
} else
{
temp = create( );
temp->next = head;
head = temp;
head->pid = process_structure->th32ParentProcessID;
head->process_handle = process_handle;
head->process_name_sz = strlen( process_structure->szExeFile ) + 1;
head->process_name = malloc( head->process_name_sz );
if ( !head->process_name )
{
perror( "Malloc" );
exit( 1 );
}
strcpy( head->process_name, process_structure->szExeFile );
}
return head;
}
/* ***************************************************************** */
void print_list( process_list * head )
{
process_list * p1 = NULL;
for ( p1 = head; p1; p1 = p1->next )
{
printf(
"-------------------------------------------------\n"
"node.process_name\t=\t%s\n"
"node.process_id\t\t=\t%d\n"
"\nCan terminate process : %s\n\n"
"node.window_handle\t=\t0x%p\n"
"node.next\t\t=\t%s\n",
p1->process_name,
( int )p1->pid,
p1->process_handle == INVALID_HANDLE_VALUE ? "NO" : "YES",
( void * )p1->window_handle,
p1->next ? "(node address)\n" : "NULL"
);
}
}
/* ***************************************************************** */
void print_node( process_list * node )
{
printf(
"node.process_name\t=\t%s\n"
"node.process_id\t\t=\t%d\n"
"\nCan terminate process : %s\n\n"
"node.window_handle\t=\t0x%p\n"
"node.next\t\t=\t%s\n",
node->process_name,
( int )node->pid,
node->process_handle == INVALID_HANDLE_VALUE ? "NO" : "YES",
( void * )node->window_handle,
node->next ? "(node address)\n" : "NULL"
);
return;
}
/* ***************************************************************** */
process_list * delete( process_list * head, process_list * node )
{
process_list * p1 = head;
process_list * p2 = NULL;
if ( !p1 )
return NULL;
else if ( p1 == node )
{
if ( !p1->next )
{
free( p1->process_name );
if ( p1->process_handle != INVALID_HANDLE_VALUE )
CloseHandle( p1->process_handle );
if ( p1->window_handle )
CloseHandle( p1->window_handle );
free( p1 );
}
else
{
free( p1->process_name );
if ( p1->process_handle != INVALID_HANDLE_VALUE )
CloseHandle( p1->process_handle );
if ( p1->window_handle )
CloseHandle( p1->window_handle );
p2 = head->next;
free( p1 );
return p2;
}
return NULL;
}
for ( ; p1 && p1 != node; p2 = p1, p1 = p1->next );
if ( !p1 )
return NULL;
else
{
free( p1->process_name );
if ( p1->process_handle != INVALID_HANDLE_VALUE )
CloseHandle( p1->process_handle );
if ( p1->window_handle )
CloseHandle( p1->window_handle );
p2->next = p1->next;
free( p1 );
}
return head;
}
/* ***************************************************************** */
void free_list( process_list * head )
{
process_list * p1 = head;
process_list * p2 = NULL;
while ( p1 )
{
free( p1->process_name );
if ( p1->process_handle != INVALID_HANDLE_VALUE )
CloseHandle( p1->process_handle );
if ( p1->window_handle )
CloseHandle( p1->window_handle );
p2 = p1;
p1 = p1->next;
free( p2 );
}
return;
}
/* ***************************************************************** */
process_list * find_process_and_copy_node( process_list * head, const char * process_name )
{
BOOL is_match = FALSE;
process_list * p1 = NULL;
process_list * new_node = NULL;
for ( p1 = head; p1; p1 = p1->next )
{
if ( !strcmp( p1->process_name, process_name ) )
{
is_match = TRUE;
break;
}
}
if ( is_match )
{
new_node = create( );
new_node->pid = p1->pid;
new_node->process_handle = p1->process_handle;
if ( !( new_node->process_name = malloc( p1->process_name_sz ) ) )
{
perror( "Malloc" );
free( new_node );
free_list( head );
exit( 1 );
}
new_node->process_name = strcpy( new_node->process_name, p1->process_name );
new_node->process_name_sz = p1->process_name_sz;
new_node->window_handle = p1->window_handle;
new_node->next = NULL;
return new_node;
}
else return NULL;
}
/* ***************************************************************** */
/* WinAPI functions */
BOOL CALLBACK FindWindows( HWND handle, LPARAM option )
{
DWORD window_process_id = 0;
GetWindowThreadProcessId( handle, &window_process_id );
process_list * p1 = NULL;
switch ( option )
{
case FIND_WINDOW_HANDLE :
if ( IsWindowEnabled( handle ) )
for ( p1 = head_copy; p1; p1 = p1->next )
if ( p1->pid == window_process_id )
p1->window_handle = handle;
break;
default :
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
break;
}
return TRUE;
}
/* ***************************************************************** */
process_list * get_process_list( process_list * head )
{
HANDLE h_process_snap;
HANDLE h_process;
PROCESSENTRY32 process_structure;
h_process_snap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
if( h_process_snap == INVALID_HANDLE_VALUE )
{
show_error( "CreateToolhelp32Snapshot", FALSE );
return NULL;
}
process_structure.dwSize = sizeof( PROCESSENTRY32 );
if( !Process32First( h_process_snap, &process_structure ) )
{
show_error( "Process32First", FALSE );
CloseHandle( h_process_snap );
return NULL;
}
do
{
h_process = OpenProcess( PROCESS_TERMINATE, FALSE, process_structure.th32ProcessID );
if ( h_process )
head = add( head, h_process, &process_structure );
else
head = add( head, INVALID_HANDLE_VALUE, &process_structure );
} while( Process32Next( h_process_snap, &process_structure ) );
CloseHandle( h_process_snap );
return head;
}
/* ***************************************************************** */
process_list * find_process( const char * process_name )
{
process_list * head = NULL;
process_list * target_process = NULL;
if ( !( head = get_process_list( head ) ) )
exit( 1 );
head_copy = head;
if ( !EnumWindows( FindWindows, FIND_WINDOW_HANDLE ) )
win_error( "EnumWindows", FALSE );
target_process = find_process_and_copy_node( head, TARGET_PROCESS );
free_list( head );
return target_process;
}
/* ***************************************************************** */
int main( )
{
t_timer program_run_time;
memset( &program_run_time, 0, sizeof( t_timer ) );
timer( TIMER_START, &program_run_time );
process_list * target_process = NULL;
printf("Searching for target process...\n");
while ( !( target_process = find_process( TARGET_PROCESS ) ) )
Sleep( 100 );
printf("Found!\n\n");
print_node( target_process );
timer( TIMER_STOP, &program_run_time );
printf( "\n\n\t--\tProgram run time : %d milliseconds\t--\t\n\n", ( int )timer( TIMER_GETDIFF, &program_run_time ) );
free( target_process->process_name );
free( target_process );
return 0;
}
If you can see it in Spy++, you should be able to get at it with EnumWindows.
But if your query is ROBLOX-specific and all you want is the window handle, you can do
foreach (Process p in Process.GetProcesses())
{
if (p.MainWindowTitle == "Roblox - [Place1]")
{
rbxProc = p;
Console.WriteLine("FOUND ROBLOX Process");
}
}
and then you can get the main handle like this:
rbxProc.MainWindowHandle
Related
I am trying to communicate via SPI in Linux user space using the spidev driver. Physically, this SPI interface is a 4 bus (SCLK, CS, MOSI, MISO).
For this purpose I have attached to my dts the relevant node in the corresponding chip select. Once Linux boots I have the device available.
Using c++ and according to the spi-test example I have treated it as a character device, so I open it, require a full duplex transfer and close it (with the relevant calls to open, ioctl/spi_ioc_transfer and close primitives). The set bus configuration is 8 bits per word, at a maximum frequency of 1.29 MHz and in mode 0 (in other words, CPHA=CPOL=0).
Then, using the oscilloscope I see how my request is present in the MOSI, but I don't see any type of response in the MISO. What am I missing?
In case it helps, I see that the clock signal drops the level immediately after sending the data through the MOSI, so it makes sense that I am not getting any data in the MISO.
In addition, I have checked that the maximum frequency as well as all settings have been set correctly. I also have a baremetal application using the bus correctly, so any HW failure is ruled out.
Spi.hpp
#pragma once
#include <string>
#include <sys/ioctl.h>
#include <cstring>
#include <fcntl.h>
#include <unistd.h>
#include <linux/spi/spidev.h>
#include <drivers/common/literals.hpp>
#include <drivers/common/Utils.hpp>
namespace interfaces
{
namespace spi
{
namespace lnx
{
enum class Mode
{
ZERO = SPI_MODE_0,
ONE = SPI_MODE_1,
TWO = SPI_MODE_2,
THREE = SPI_MODE_3
};
enum class Bpw
{
BITS_8 = 8,
BITS_16 = 16
};
enum class State
{
CLOSED,
OPEN
};
class Spi
{
public:
explicit Spi( const std::string& aDevice )
{
memset( &theFrame, 0, sizeof( struct spi_ioc_transfer ) );
theFileDescriptor = -1;
theState = State::CLOSED;
theFrame[0].delay_usecs = 0;
// Do keep CS activated
theFrame[0].cs_change = 0;
if( setDevice( aDevice ) != ErrorCode::OPERATION_SUCESS )
{
trace( DEBUG_GENERAL, "error setting device\r\n" );
}
if( setMode( Mode::ZERO ) != ErrorCode::OPERATION_SUCESS )
{
trace( DEBUG_GENERAL, "error setting mode\r\n" );
}
if( setBitsPerWord( Bpw::BITS_8 ) != ErrorCode::OPERATION_SUCESS )
{
trace( DEBUG_GENERAL, "error setting bpw\r\n" );
}
// Set the SPI device pre-scaler to divide by 128
// (SPI_CLK_FREQ_HZ = 166 MHz) to transfer below 2MHz clock rate.
if( setMaxSpeedHz( ( 166 / 128.0 ) * 1000000 ) != ErrorCode::OPERATION_SUCESS )
{
trace( DEBUG_GENERAL, "error setting maximum speed\r\n" );
}
}
virtual ~Spi( void )
{
if( theState != State::CLOSED && theFileDescriptor != -1 )
{
if( close() != ErrorCode::OPERATION_SUCESS )
{
trace(
DEBUG_GENERAL,
"error closing device %s\r\n",
theDevice.c_str() );
}
}
}
Spi( const Spi& ) = delete;
Spi& operator=( const Spi& ) = delete;
inline std::string getDevice( void )
{
return this->theDevice;
}
inline ErrorCode setDevice( const std::string& aDevice )
{
ErrorCode anErrorCode = ErrorCode::CANT_CONFIGURE_INTERFACE;
if( theState != State::CLOSED && theFileDescriptor != -1 )
{
if ( close() != ErrorCode::OPERATION_SUCESS )
{
goto exit;
}
}
this->theDevice = aDevice;
anErrorCode = open();
exit:
return std::move( anErrorCode );
}
inline ErrorCode setMode( const Mode& aMode )
{
ErrorCode anErrorCode = ErrorCode::CANT_CONFIGURE_INTERFACE;
if( theState != State::CLOSED && theFileDescriptor != -1 )
{
if( ::ioctl(
theFileDescriptor,
SPI_IOC_WR_MODE32,
&aMode ) != -1 )
{
auto aResult = getMode();
if( aResult.first == ErrorCode::OPERATION_SUCESS &&
aResult.second == aMode )
{
anErrorCode = ErrorCode::OPERATION_SUCESS;
trace(
DEBUG_INFO,
"mode set to %d\r\n",
aMode );
}
else
{
close();
trace(
DEBUG_GENERAL,
"mode incongruence\r\n" );
}
}
else
{
close();
trace(
DEBUG_GENERAL,
"failed setting mode\r\n" );
}
}
return std::move( anErrorCode );
}
inline std::pair<ErrorCode, Mode> getMode( void )
{
Mode aMode;
ErrorCode anErrorCode = ErrorCode::CANT_CONFIGURE_INTERFACE;
if( theState != State::CLOSED && theFileDescriptor != -1 )
{
if( ::ioctl(
theFileDescriptor,
SPI_IOC_RD_MODE32,
&aMode ) != -1 )
{
anErrorCode = ErrorCode::OPERATION_SUCESS;
}
else
{
trace(
DEBUG_GENERAL,
"failed reading mode\r\n" );
}
}
return std::make_pair( anErrorCode, aMode );
}
inline ErrorCode setBitsPerWord( const Bpw& aBitsPerWord )
{
ErrorCode anErrorCode = ErrorCode::CANT_CONFIGURE_INTERFACE;
if( theState != State::CLOSED && theFileDescriptor != -1 )
{
if( ::ioctl(
theFileDescriptor,
SPI_IOC_WR_BITS_PER_WORD,
&aBitsPerWord ) != -1 )
{
auto aResult = getBitsPerWord();
if( aResult.first == ErrorCode::OPERATION_SUCESS &&
aResult.second == aBitsPerWord )
{
anErrorCode = ErrorCode::OPERATION_SUCESS;
theFrame[0].bits_per_word =
static_cast<uint8_t>( aBitsPerWord );
trace(
DEBUG_INFO,
"bpw set to %d\r\n",
aBitsPerWord );
}
else
{
close();
trace(
DEBUG_GENERAL,
"bpw incongruence\r\n" );
}
}
else
{
close();
trace(
DEBUG_GENERAL,
"failed setting bpw\r\n" );
}
}
return std::move( anErrorCode );
}
inline std::pair<ErrorCode, Bpw> getBitsPerWord( void )
{
uint8_t aBitsPerWord;
ErrorCode anErrorCode = ErrorCode::CANT_CONFIGURE_INTERFACE;
if( theState != State::CLOSED && theFileDescriptor != -1 )
{
if( ::ioctl(
theFileDescriptor,
SPI_IOC_RD_BITS_PER_WORD,
&aBitsPerWord ) != -1 )
{
anErrorCode = ErrorCode::OPERATION_SUCESS;
}
else
{
trace(
DEBUG_GENERAL,
"failed reading bpw\r\n" );
}
}
return std::make_pair(
anErrorCode,
static_cast<Bpw>( aBitsPerWord ) );
}
inline ErrorCode setMaxSpeedHz( const uint32_t aSpeed )
{
ErrorCode anErrorCode = ErrorCode::CANT_CONFIGURE_INTERFACE;
if( theState != State::CLOSED && theFileDescriptor != -1 )
{
if( ::ioctl(
theFileDescriptor,
SPI_IOC_WR_MAX_SPEED_HZ,
&aSpeed ) != -1 )
{
auto aResult = getMaxSpeedHz();
if( aResult.first == ErrorCode::OPERATION_SUCESS &&
aResult.second == aSpeed )
{
anErrorCode = ErrorCode::OPERATION_SUCESS;
theFrame[0].speed_hz = aSpeed;
trace(
DEBUG_INFO,
"maximum speed set to %d Hz\r\n",
aSpeed );
}
else
{
close();
trace(
DEBUG_GENERAL,
"maximum speed incongruence\r\n" );
}
}
else
{
close();
trace(
DEBUG_GENERAL,
"failed setting maximum speed\r\n" );
}
}
return std::move( anErrorCode );
}
inline std::pair<ErrorCode, uint32_t> getMaxSpeedHz( void )
{
uint32_t aSpeed;
ErrorCode anErrorCode = ErrorCode::CANT_CONFIGURE_INTERFACE;
if( theState != State::CLOSED && theFileDescriptor != -1 )
{
if( ::ioctl(
theFileDescriptor,
SPI_IOC_RD_MAX_SPEED_HZ,
&aSpeed ) != -1 )
{
anErrorCode = ErrorCode::OPERATION_SUCESS;
}
else
{
trace(
DEBUG_GENERAL,
"failed setting maximum speed\r\n" );
}
}
return std::make_pair( anErrorCode, aSpeed );
}
std::pair<ErrorCode, std::vector<uint8_t>> transfer(
const std::vector<uint8_t>& aBuffer,
uint32_t aLenght );
std::pair<ErrorCode, std::vector<uint8_t>>
read( uint32_t aLenght );
ErrorCode write( const std::vector<uint8_t>& aBuffer );
private:
ErrorCode open( void );
ErrorCode close( void );
int32_t theFileDescriptor;
std::string theDevice;
struct spi_ioc_transfer theFrame[1];
State theState;
};
} // end namespace lnx
} // end namespace spi
} // end namespace interfaces
Spi.cpp
#include <interfaces/lnx/Spi.hpp>
namespace interfaces
{
namespace spi
{
namespace lnx
{
ErrorCode Spi::open( void )
{
ErrorCode anErrorCode = ErrorCode::CANT_OPEN_DEV;
if( !theDevice.empty() )
{
theFileDescriptor = ::open(
theDevice.c_str(), O_SYNC | O_RDWR );
if( theFileDescriptor != -1 )
{
anErrorCode = ErrorCode::OPERATION_SUCESS;
theState = State::OPEN;
trace(
DEBUG_INFO,
"device %s opened\r\n",
theDevice.c_str() );
}
else
{
trace(
DEBUG_GENERAL,
"device %s could not be opened\r\n",
theDevice.c_str() );
}
}
return std::move( anErrorCode );
}
ErrorCode Spi::close( void )
{
ErrorCode anErrorCode = ErrorCode::CANT_CLOSE_DEV;
if( theState != State::CLOSED && theFileDescriptor != -1 )
{
if( ::close( theFileDescriptor ) == 0 )
{
anErrorCode = ErrorCode::OPERATION_SUCESS;
theFileDescriptor = -1;
theState = State::CLOSED;
trace(
DEBUG_INFO,
"device %s closed\r\n",
theDevice.c_str() );
}
}
return std::move( anErrorCode );
}
std::pair<ErrorCode, std::vector<uint8_t>> Spi::transfer(
const std::vector<uint8_t>& aRequest, uint32_t aLenght )
{
std::vector<uint8_t> aBuffer( aLenght, 0xFF );
ErrorCode anErrorCode = ErrorCode::CANT_READ_FROM_INTERFACE;
if( aRequest.empty() || aLenght <= 0 )
{
trace(
DEBUG_GENERAL,
"provided arguments not complains the conditions\r\n" );
goto exit;
}
if( theState != State::CLOSED && theFileDescriptor != -1 )
{
theFrame[0].tx_buf = reinterpret_cast<uintptr_t>( aRequest.data() );
theFrame[0].rx_buf = reinterpret_cast<uintptr_t>( &aBuffer[0] );
// Length of the command to write/read
theFrame[0].len = aLenght;
if( ::ioctl(
theFileDescriptor,
SPI_IOC_MESSAGE( 1 ),
&theFrame ) < 1 )
{
trace(
DEBUG_GENERAL,
"failed doing full duplex transfer\r\n" );
}
else
{
anErrorCode = ErrorCode::OPERATION_SUCESS;
vprint( aBuffer.data(), aBuffer.size() );
}
}
exit:
return std::make_pair( anErrorCode, aBuffer );
}
std::pair<ErrorCode, std::vector<uint8_t>>
Spi::read( uint32_t aLenght )
{
std::vector<uint8_t> aBuffer( aLenght, 0xFF );
ErrorCode anErrorCode = ErrorCode::CANT_READ_FROM_INTERFACE;
if( aLenght <= 0 )
{
trace(
DEBUG_GENERAL,
"provided arguments not complains the conditions\r\n" );
goto exit;
}
if( theState != State::CLOSED && theFileDescriptor != -1 )
{
theFrame[0].tx_buf = static_cast<uintptr_t>( NULL );
theFrame[0].rx_buf = reinterpret_cast<uintptr_t>( &aBuffer[0] );
theFrame[0].len = aLenght;
if( ::ioctl(
theFileDescriptor,
SPI_IOC_MESSAGE( 1 ),
&theFrame ) < 1 )
{
trace(
DEBUG_GENERAL,
"failed receiving message\r\n" );
}
else
{
anErrorCode = ErrorCode::OPERATION_SUCESS;
vprint( aBuffer.data(), aBuffer.size() );
}
}
exit:
return std::make_pair( anErrorCode, aBuffer );
}
ErrorCode Spi::write( const std::vector<uint8_t>& aBuffer )
{
ErrorCode anErrorCode = ErrorCode::CANT_WRITE_TO_INTERFACE;
if( aBuffer.empty() )
{
trace(
DEBUG_GENERAL,
"provided arguments not complains the conditions\r\n" );
goto exit;
}
if( theState != State::CLOSED && theFileDescriptor != -1 )
{
theFrame[0].tx_buf = reinterpret_cast<uintptr_t>( aBuffer.data() );
theFrame[0].rx_buf = static_cast<uintptr_t>( NULL );
theFrame[0].len = aBuffer.size();
if( ::ioctl(
theFileDescriptor,
SPI_IOC_MESSAGE( 1 ),
&theFrame ) < 1 )
{
trace(
DEBUG_GENERAL,
"failed sending message\r\n" );
}
else
{
anErrorCode = ErrorCode::OPERATION_SUCESS;
vprint( aBuffer.data(), aBuffer.size() );
}
}
exit:
return std::move( anErrorCode );
}
} // end namespace lnx
} // end namespace spi
} // end namespace interfaces
myboard.dts
...
&spi0 {
num-cs = <2>;
spi-cpol = <0>;
spi-cpha = <0>;
status = "okay";
spidev#0 {
compatible = "xlnx,spidev";
reg = <0>;
spi-max-frequency = <1296875>;
};
};
...
I use the transfer function to achieve my purpose over lnx-xlnx 4.14
Trying to run the following
std::wstring query1 = L"SELECT st.table_id FROM information_schema.INNODB_TABLES st WHERE st.name = ?;";
or
std::wstring query1 = L"SELECT st.table_id FROM information_schema.INNODB_TABLES st WHERE st.name = CONCAT(?, '/', ?);";
returns SQL_NO_DATA, but if the parameter is spelled out the record is returned.
Code is as follows:
auto res1 = mysql_stmt_init( m_db );
if( !res1 )
{
std::wstring err = m_pimpl->m_myconv.from_bytes( mysql_stmt_error( res1 ) );
errors.push_back( err );
result = 1;
}
else
{
if( mysql_stmt_prepare( res1, m_pimpl->m_myconv.to_bytes( query1.c_str() ).c_str(), query1.length() ) )
{
std::wstring err = m_pimpl->m_myconv.from_bytes( mysql_stmt_error( res1 ) );
errors.push_back( err );
result = 1;
}
else
{
MYSQL_BIND params[2];
unsigned long str_length1, str_length2;
str_length1 = strlen( m_pimpl->m_myconv.to_bytes( schema.c_str() ) .c_str() ) * 2;
str_length2 = strlen( m_pimpl->m_myconv.to_bytes( table.c_str() ).c_str() ) * 2;
char *str_data1 = new char[str_length1], *str_data2 = new char[str_length2];
memset( str_data1, '\0', str_length1 );
memset( str_data2, '\0', str_length2 );
memset( params, 0, sizeof( params ) );
strncpy( str_data1, m_pimpl->m_myconv.to_bytes( schema.c_str() ) .c_str(), str_length1 );
strncpy( str_data2, m_pimpl->m_myconv.to_bytes( table.c_str() ).c_str(), str_length2 );
params[0].buffer_type = MYSQL_TYPE_STRING;
params[0].buffer = (char *) str_data1;
params[0].buffer_length = strlen( str_data1 );
params[0].is_null = 0;
params[0].length = &str_length1;
params[1].buffer_type = MYSQL_TYPE_STRING;
params[1].buffer = (char *) str_data2;
params[1].buffer_length = strlen( str_data2 );
params[1].is_null = 0;
params[1].length = &str_length2;
if( mysql_stmt_bind_param( res1, params ) )
{
std::wstring err = m_pimpl->m_myconv.from_bytes( mysql_stmt_error( res1 ) );
errors.push_back( err );
result = 1;
}
else
{
auto prepare_meta_result = mysql_stmt_result_metadata( res1 );
if( !prepare_meta_result )
{
std::wstring err = m_pimpl->m_myconv.from_bytes( mysql_stmt_error( res1 ) );
errors.push_back( err );
result = 1;
}
else
{
if( mysql_stmt_execute( res1 ) )
{
std::wstring err = m_pimpl->m_myconv.from_bytes( mysql_stmt_error( res1 ) );
errors.push_back( err );
result = 1;
}
else
{
MYSQL_BIND results1[1];
bool is_null[1], error[1];
unsigned long length[1];
memset( results1, 0, sizeof( results1 ) );
results1[0].buffer_type = MYSQL_TYPE_LONG;
results1[0].buffer = (char *) &tableId;
results1[0].is_null = &is_null[1];
results1[0].error = &error[1];
results1[0].length = &length[1];
if( mysql_stmt_bind_result( res1, results1 ) )
{
std::wstring err = m_pimpl->m_myconv.from_bytes( mysql_stmt_error( res1 ) );
errors.push_back( err );
result = 1;
}
else
{
while( true )
{
auto dataset = mysql_stmt_fetch( res1 );
if( dataset == 1 || dataset == MYSQL_NO_DATA )
break;
else
id = tableId;
}
mysql_free_result( prepare_meta_result );
}
}
}
}
}
}
if( mysql_stmt_close( res1 ) )
{
std::wstring err = m_pimpl->m_myconv.from_bytes( mysql_stmt_error( res1 ) );
errors.push_back( err );
result = 1;
}
What am I missing?
I suspect you have a lifetime issue. Consider the following code:
{
if( mysql_stmt_prepare( res1, m_pimpl->m_myconv.to_bytes( query1.c_str() ).c_str(), query1.length() ) )
{
You take your wstring query1 (and WHY is it a wstring if you need it to be a std::string???), and pass it to m_pimpl->m_myconv.to_bytes. I assume that function does the Unicode-to-ANSI translation and returns a std::string. You then call c_str() on that to get a buffer, and pass that to mysql_stmt_prepare.
HOWEVER, what to_bytes returns is a temporary. As soon as the if statement exits, that string goes out of scope and will be destroyed, leaving the statement holding a pointer into nothing. I suggest you try:
std::string query1s = m_pimpl->m_myconv.to_bytes( query1.c_str() );
if( mysql_stmt_prepare( res1, query1s.c_str(), query1s.length() ) )
{
This has the additional benefit of letting you print the value of query1s to make sure it matches your expectation.
Now, IF mysql_stmt_prepare actually copies the input string, instead of just grabbing a pointer, then this won't fix anything.
I have some C++ code that I need to use for serial communication between PC and Arduino. The file "Serial.cpp" is including a file called "stdafx.h" that doesn't exist in the project or anywhere on my computer, which obviously causes an error.
Other than that, I also get other errors, such as C2065 'CSerial': undeclared identifier.
Here are the three files that are in the project:
Serial.h
#ifndef __SERIAL_H__
#define __SERIAL_H__
#pragma once
#include <Windows.h>
#include <memory.h>
#define FC_DTRDSR 0x01
#define FC_RTSCTS 0x02
#define FC_XONXOFF 0x04
#define ASCII_BEL 0x07
#define ASCII_BS 0x08
#define ASCII_LF 0x0A
#define ASCII_CR 0x0D
#define ASCII_XON 0x11
#define ASCII_XOFF 0x13
class CSerial
{
public:
CSerial();
~CSerial();
BOOL Open( int nPort = 2, int nBaud = 9600 );
BOOL Close( void );
int ReadData( void *, int );
int SendData( const char *, int );
int ReadDataWaiting( void );
BOOL IsOpened( void ){ return( m_bOpened ); }
protected:
BOOL WriteCommByte( unsigned char );
HANDLE m_hIDComDev;
OVERLAPPED m_OverlappedRead, m_OverlappedWrite;
bool m_bOpened;
};
#endif
Serial.cpp
// Serial.cpp
#include "stdafx.h"
#include "Serial.h"
CSerial::CSerial()
{
memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );
m_hIDComDev = NULL;
m_bOpened = false;
}
CSerial::~CSerial()
{
Close();
}
BOOL CSerial::Open( int nPort, int nBaud )
{
if( m_bOpened ) return( TRUE );
wchar_t szPort[15];
wchar_t szComParams[50];
DCB dcb;
wsprintf( szPort, L"COM%d", nPort );
m_hIDComDev = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL );
if( m_hIDComDev == NULL ) return( FALSE );
memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );
COMMTIMEOUTS CommTimeOuts;
CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.ReadTotalTimeoutConstant = 0;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutConstant = 5000;
SetCommTimeouts( m_hIDComDev, &CommTimeOuts );
wsprintf( szComParams, L"COM%d:%d,n,8,1", nPort, nBaud );
m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
dcb.DCBlength = sizeof( DCB );
GetCommState( m_hIDComDev, &dcb );
dcb.BaudRate = nBaud;
dcb.ByteSize = 8;
unsigned char ucSet;
ucSet = (unsigned char) ( ( FC_RTSCTS & FC_DTRDSR ) != 0 );
ucSet = (unsigned char) ( ( FC_RTSCTS & FC_RTSCTS ) != 0 );
ucSet = (unsigned char) ( ( FC_RTSCTS & FC_XONXOFF ) != 0 );
if( !SetCommState( m_hIDComDev, &dcb ) ||
!SetupComm( m_hIDComDev, 10000, 10000 ) ||
m_OverlappedRead.hEvent == NULL ||
m_OverlappedWrite.hEvent == NULL ){
DWORD dwError = GetLastError();
if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
CloseHandle( m_hIDComDev );
return( FALSE );
}
m_bOpened = TRUE;
return( m_bOpened );
}
BOOL CSerial::Close( void )
{
if( !m_bOpened || m_hIDComDev == NULL ) return( TRUE );
if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
CloseHandle( m_hIDComDev );
m_bOpened = FALSE;
m_hIDComDev = NULL;
return( TRUE );
}
BOOL CSerial::WriteCommByte( unsigned char ucByte )
{
BOOL bWriteStat;
DWORD dwBytesWritten;
bWriteStat = WriteFile( m_hIDComDev, (LPSTR) &ucByte, 1, &dwBytesWritten, &m_OverlappedWrite );
if( !bWriteStat && ( GetLastError() == ERROR_IO_PENDING ) ){
if( WaitForSingleObject( m_OverlappedWrite.hEvent, 1000 ) ) dwBytesWritten = 0;
else{
GetOverlappedResult( m_hIDComDev, &m_OverlappedWrite, &dwBytesWritten, FALSE );
m_OverlappedWrite.Offset += dwBytesWritten;
}
}
return( TRUE );
}
int CSerial::SendData( const char *buffer, int size )
{
if( !m_bOpened || m_hIDComDev == NULL ) return( 0 );
DWORD dwBytesWritten = 0;
int i;
for( i=0; i<size; i++ ){
WriteCommByte( buffer[i] );
dwBytesWritten++;
}
return( (int) dwBytesWritten );
}
int CSerial::ReadDataWaiting( void )
{
if( !m_bOpened || m_hIDComDev == NULL ) return( 0 );
DWORD dwErrorFlags;
COMSTAT ComStat;
ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );
return( (int) ComStat.cbInQue );
}
int CSerial::ReadData( void *buffer, int limit )
{
if( !m_bOpened || m_hIDComDev == NULL ) return( 0 );
BOOL bReadStatus;
DWORD dwBytesRead, dwErrorFlags;
COMSTAT ComStat;
ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );
if( !ComStat.cbInQue ) return( 0 );
dwBytesRead = (DWORD) ComStat.cbInQue;
if( limit < (int) dwBytesRead ) dwBytesRead = (DWORD) limit;
bReadStatus = ReadFile( m_hIDComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead );
if( !bReadStatus ){
if( GetLastError() == ERROR_IO_PENDING ){
WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );
return( (int) dwBytesRead );
}
return( 0 );
}
return( (int) dwBytesRead );
}
SerialExample.cpp
bool sendExample(int port, int baudRate)
{
char data[4];
CSerial* s = new CSerial();
if(!s->Open(port, baudRate))
{
std_out << _T("Could not open COM") << port << endl;
return false;
}
// Sending a string of 4 characters
data[0] = 0x31;
data[1] = 0x32;
data[2] = 0x33;
data[3] = 0x0D; // ASCII CR
s->SendData(data, 4);
s->Close();
delete s;
}
Does anyone know what I have to do?
stdafx.h is a precompiled header for Visual studio. so if you are not working in visual studio, you can just remove it and it should work just fine.
In regard to the compiler not recognizing the CSerial class -
I don't see where you include "CSerial.h" in SerialExample.cpp (i.e: #include "CSerial.h"), but if you do, this may also be a symptom of CSerial.cpp not compiling (less likely though)...
Hope this helps,
Lior
ALL,
I'm getting the Commands were executed in an improper order. trying to execute following code:
std::wstring query6 = L"SELECT( IF( ( SELECT 1 FROM information_schema.statistics WHERE index_name=\'abcattbl_tnam_ownr\' AND table_name=\'abcattbl\' ) > 0, \"SELECT 0\", \"CREATE INDEX abcattbl_tnam_ownr ON abcattbl(abt_tnam ASC, abt_ownr ASC)\"));";
std::wstring query7 = L"SELECT( IF( ( SELECT 1 FROM information_schema.statistics WHERE index_name=\'abcatcol_tnam_ownr_cnam\' AND table_name=\'abcatcol\' ) > 0, \"SELECT 0\", \"CREATE INDEX abcatcol_tnam_ownr_cnam ON abcatcoll(abc_tnam ASC, abc_ownr ASC, abc_cnam ASC)\"));";
res_stmt = mysql_stmt_init( m_db );
if( !res_stmt )
{
std::wstring err = m_pimpl->m_myconv.from_bytes( mysql_stmt_error( res_stmt ) );
errorMsg.push_back( err );
}
else
{
if( mysql_stmt_prepare( res_stmt, m_pimpl->m_myconv.to_bytes( query.c_str() ).c_str(), query.length() ) )
{
std::wstring err = m_pimpl->m_myconv.from_bytes( mysql_stmt_error( res_stmt ) );
errorMsg.push_back( err );
}
else
{
bool index_exist = IsSystemIndexExists( res_stmt, L"abcattbl_tnam_ownr", L"abcattbl", errorMsg );
if( !index_exist )
{
res = mysql_query( m_db, m_pimpl->m_myconv.to_bytes( query6.c_str() ).c_str() );
}
}
bool index_exist = IsSystemIndexExists( res_stmt, L"abcatcol_tnam_ownr_cnam", L"abcatcol", errorMsg );
if( !index_exist )
{
res = mysql_query( m_db, m_pimpl->m_myconv.to_bytes( query7.c_str() ).c_str() );
if( mysql_stmt_close( res_stmt ) )
{
std::wstring err = m_pimpl->m_myconv.from_bytes( mysql_stmt_error( res_stmt ) );
errorMsg.push_back( err );
}
}
}
bool MySQLDatabase::IsSystemIndexExists(MYSQL_STMT *res, const std::wstring &indexName, const std::wstring &tableName, std::vector<std::wstring> &errorMsg)
{
bool exists = false;
char *str_data[2] = { NULL, NULL };
unsigned long *str_length[3];
MYSQL_BIND values[2];
memset( values, 0, sizeof( values ) );
str_data[0] = new char[tableName.length() + 1];
str_data[1] = new char[indexName.length() + 1];
memset( str_data[0], 0, tableName.length() + 1 );
memset( str_data[1], 0, indexName.length() + 1 );
str_length[0] = new unsigned long;
str_length[1] = new unsigned long;
values[0].buffer_type = MYSQL_TYPE_STRING;
values[1].buffer_type = MYSQL_TYPE_STRING;
values[0].buffer = str_data[0];
values[1].buffer = str_data[1];
values[0].buffer_length = tableName.length();
values[1].buffer_length = indexName.length();
values[0].is_null = 0;
values[1].is_null = 0;
values[0].length = str_length[0];
values[1].length = str_length[1];
strncpy( str_data[0], m_pimpl->m_myconv.to_bytes( tableName.c_str() ).c_str(), tableName.length() );
strncpy( str_data[1], m_pimpl->m_myconv.to_bytes( indexName.c_str() ).c_str(), indexName.length() );
*str_length[0] = tableName.length();
*str_length[1] = indexName.length();
if( mysql_stmt_bind_param( res, values ) )
{
std::wstring err = m_pimpl->m_myconv.from_bytes( mysql_stmt_error( res ) );
errorMsg.push_back( err );
}
else
{
if( mysql_stmt_execute( res ) )
{
std::wstring err = m_pimpl->m_myconv.from_bytes( mysql_stmt_error( res ) );
errorMsg.push_back( err );
}
else
{
if( mysql_stmt_fetch( res ) != MYSQL_NO_DATA )
exists = 1;
}
}
}
delete str_data[0];
str_data[0] = NULL;
delete str_data[1];
str_data[1] = NULL;
delete str_length[0];
str_length[0] = NULL;
delete str_length[1];
str_length[1] = NULL;
return exists;
}
The first time function is called everything is executed correctly. However the second time the call fails with the above mentioned error.
What am I missing? Is there maybe a parameters un-bind function that needs to be called?
I feel like I'm missing something really obvious.
TIA!
[EDIT]:
Calling mysql_stmt_reset()/mysql_stmt_free_result() after _fetch() doesn't change the result.
[/EDIT]
I have the following problem:
I want to keep track of the running processes by using CreateToolhelp32Snapshot and Process32First/Next. However I want to use the Unicode charset by default.
bool active( const std::wstring& process_name )
{
HANDLE snapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
if ( snapshot == INVALID_HANDLE_VALUE )
return false;
PROCESSENTRY32 entry;
if ( Process32First( snapshot, &entry ) )
{
if ( process_name.compare( entry.szExeFile ) == 0 )
{
CloseHandle( snapshot );
return true;
}
}
while ( Process32Next( snapshot, &entry ) )
{
if ( process_name.compare( entry.szExeFile ) == 0 )
{
CloseHandle( snapshot );
return true;
}
}
CloseHandle( snapshot );
return false;
}
int main( )
{
SetConsoleTitle( L"Lel" );
if ( active( L"notepad++.exe" ) )
std::cout << "Hello" << std::endl;
else
std::cout << ":(" << std::endl;
}
However, if I use multibyte-charset everything's working fine.
You must initialize entry and set dwSize value. dwSize value is Windows's idea of version control and is required:
PROCESSENTRY32 entry = { 0 };
entry.dwSize = sizeof(PROCESSENTRY32);
Comparison should not be case sensitive:
while (Process32Next(snapshot, &entry))
{
if (_wcsicmp(process_name.c_str(), entry.szExeFile) == 0)
{
CloseHandle(snapshot);
return true;
}
}