I am writing display drivers for micro oled.
board is dart4460 (omap4460) which provides dss(display subsystem).
so I am writing drivers using dss.
but I dont know what I wrote is right or not
oled display use dpi interface and i2c for commands
I referred to pico dlp projector driver source which uses dpi and i2c.
here are datasheets
dart4460: http://www.variscite.com/images/DART-4460-DS_107.pdf
micro oled display: https://www.dropbox.com/s/ixpws4qzo3ttj6e/SVGA050.pdf?dl=0
Code:
panel-svga.c
#define SLAVE_ADDR_READ 0x1F
#define SLAVW_ADDR_WRITE 0x1E
struct svga050_i2c_data {
struct mutex xfer_lock;
};
struct svga050_data {
struct i2c_client *client;
struct mutex lock;
};
static struct i2c_board_info svga050_i2c_board_info = {
I2C_BOARD_INFO("svga050_i2c_drive",SLAVE_ADDR_WRITE);
}
static struct omap_video_timings svga050_timings = {
.x_res = 800,
.y_res = 600,
.pixel_clock = 40000,
.hsw = 128,
.hfp = 40,
.hbp = 88,
.vsw = 4,
.vfp = 1,
.vbp = 23,
};
static int svga050_panel_power_on(struct omap_dss_device *dssdev)
{
int r;
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
return 0;
r = omapdss_dpi_display_enable(dssdev);
if (r)
goto err0;
if (dssdev->platform_enable) {
r = dssdev->platform_enable(dssdev);
if (r)
goto err1;
}
return 0;
err1:
omapdss_dpi_display_disable(dssdev);
err0:
return r;
}
static void svga050_panel_power_off(struct omap_dss_device *dssdev)
{
if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
return;
if (dssdev->platform_disable)
dssdev->platform_disable(dssdev);
omapdss_dpi_display_disable(dssdev);
}
static inline struct svga050_panel_data *get_panel_data(const struct omap_dss_device *dssdev)
{
return (struct svga050_panel_data *)dssdev->data;
}
static int svga050_panel_probe(struct omap_dss_device *dssdev)
{
struct svga050_data *svga_data;
struct i2c_adapter *adapter;
struct i2c_client *svga_i2c_client;
struct svga050_panel_data *svga_pdata=get_panel_data(dssdev);
int r;
dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
OMAP_DSS_LCD_IHS;
dssdev->panel.timings = svga050_timings;
svga_data = devm_kzalloc(&dssdev->dev,sizeof(*svga_data), GFP_KERNEL);
if (!svga_data) {
r = -ENOMEM;
goto err;
}
mutex_init(&ld->lock);
dev_set_drvdata(&dssdev->dev, ld);
return 0;
err:
return r;
}
static void svga050_panel_remove(struct omap_dss_device *dssdev)
{
struct svga050_data *ld = dev_get_drvdata(&dssdev->dev);
kfree(ld);
}
static int svga050_panel_enable(struct omap_dss_device *dssdev)
{
struct svga050_data *ld = dev_get_drvdata(&dssdev->dev);
int r;
mutex_lock(&ld->lock);
r = svga050_panel_power_on(dssdev);
if (r)
goto err;
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
mutex_unlock(&ld->lock);
return 0;
err:
mutex_unlock(&ld->lock);
return r;
}
static void svga050_panel_disable(struct omap_dss_device *dssdev)
{
struct svga050_data *ld = dev_get_drvdata(&dssdev->dev);
mutex_lock(&ld->lock);
svga050_panel_power_off(dssdev);
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
mutex_unlock(&ld->lock);
}
static int svga050_panel_suspend(struct omap_dss_device *dssdev)
{
struct svga050_data *ld = dev_get_drvdata(&dssdev->dev);
mutex_lock(&ld->lock);
svga050_panel_power_off(dssdev);
dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
mutex_unlock(&ld->lock);
return 0;
}
static int svga050_panel_resume(struct omap_dss_device *dssdev)
{
struct svga050_data *ld = dev_get_drvdata(&dssdev->dev);
int r;
mutex_lock(&ld->lock);
r = svga050_panel_power_on(dssdev);
if (r)
goto err;
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
mutex_unlock(&ld->lock);
return 0;
err:
mutex_unlock(&ld->lock);
return r;
}
static struct omap_dss_driver svga050_driver = {
.probe = svga050_panel_probe,
.remove = svga050_panel_remove,
.enable = svga050_panel_enable,
.disable = svga050_panel_disable,
.suspend = svga050_panel_suspend,
.resume = svga050_panel_resume,
.driver = {
.name = "svga050",
.owner = THIS_MODULE,
},
};
static int svga050_i2c_read(struct i2c_client *client, u8 reg)
{
u8 read_cmd[] = { SLAVE_ADDR_READ, reg }, data;
struct svga050_i2c_data *picodlp_i2c_data = i2c_get_clientdata(client);
struct i2c_msg msg[2];
mutex_lock(&svga050_i2c_data->xfer_lock);
msg[0].addr = client->addr;
msg[0].flags = 0;
msg[0].len = 2;
msg[0].buf = read_cmd;
msg[1].addr = client->addr;
msg[1].flags = I2C_M_RD;
msg[1].len = 2;
msg[1].buf = data;
i2c_transfer(client->adapter, msg, 2);
mutex_unlock(&svga050_i2c_data->xfer_lock);
return data;
}
static int svga050_i2c_write(struct i2c_client *client, u8 reg, u8 value)
{
u8 data[2];
int i;
struct i2c_msg msg;
int i, r, msg_count = 1;
struct svga050_i2c_data *picodlp_i2c_data = i2c_get_clientdata(client);
data[0] = reg;
data[1] = value;
mutex_lock(&svga050_i2c_data->xfer_lock);
msg.addr = client->addr;
msg.flags = 0;
msg.len = 2;
msg.buf = data;
r = i2c_transfer(client->adapter, &msg, msg_count);
mutex_unlock(&svga050_i2c_data->xfer_lock);
/*
* i2c_transfer returns:
* number of messages sent in case of success
* a negative error number in case of failure
*/
if (r != msg_count)
goto err;
/* In case of success */
for (i = 0; i < 2; i++)
dev_dbg(&client->dev,
"addr %x bw 0x%02x[%d]: 0x%02x\n",
client->addr, data[0] + i, i, data[i]);
return 0;
err:
dev_err(&client->dev, "svga050_i2c_write error\n");
return r;
}
static int svga050_i2c_write_array(struct i2c_client *client,
const struct svga050_i2c_command commands[],
int count)
{
int i, r = 0;
for (i = 0; i < count; i++) {
r = svga050_i2c_write(client, commands[i].reg,
commands[i].value);
if (r)
return r;
}
return r;
}
static void init_svga050_panel(struct spi_device *spi)
{
}
static int __devinit svga050_panel_i2c_probe(struct i2c_client *client,const struct i2c_device_id *id)
{
struct svga050_i2c_data *svga_i2c_data;
svga_i2c_data=kzalloc(sizeof(struct svga050_i2c_data),GFP_KERNEL);
if(svga_i2c_data == NULL)
return -ENOMEM;
i2c_set_clientdata(client,svga_i2c_data);
mutex_init(&svga_i2c_data->xfer_lock);
dev_err(&client->dev,"svga i2c initialized\n");
return 0;
}
static int __devexit svga050_panel_i2c_remove(struct i2c_client *client)
{
struct svga050_i2c_data *sd1= i2c_get_clientdata(client);
i2c_set_clientdata(client,NULL);
kfree(sd1);
return 0;
}
static const struct i2c_device_id svga050_i2c_idtable[]={
{"svga050_i2c_driver",0},
{},
};
static struct i2c_driver svga050_i2c_driver = {
.driver = {
.name = "svga050_i2c",
.owner = THIS_MODULE,
},
.probe = svga050_panel_i2c_probe,
.remove = __exit_p(svga050_panel_i2c_remove),
.id_table = svga050_i2c_idtable,
};
static int __init svga050_panel_drv_init(void)
{
int r;
r= i2c_add_driver(&svga050_i2c_driver);
if(r < 0){
printk(KERN_WARNING "svga050 i2c driver registration failed\n");
return r;
}
r=omap_dss_register_driver(&svga050_driver);
if(r < 0){
printk(KERN_WARNING "svga050 dss driver registration failed\n");
i2c_del_driver(&svga050_i2c_driver);
}
return r;
}
static void __exit svga050_panel_drv_exit(void)
{
omap_dss_unregister_driver(&svga050_driver);
i2c_del_driver(&svga050_i2c_driver);
}
module_init(svga050_panel_drv_init);
module_exit(svga050_panel_drv_exit);
MODULE_LICENSE("GPL");
Board.c
static struct omap_dss_device svga050_device = {
.name = "svga050",
.driver_name = "svga050",
.type = OMAP_DISPLAY_TYPE_DPI,
.phy.dpi.data_lines = 24,
.channel = OMAP_DSS_CHANNEL_LCD2,
.platform_enable = svga050_panel_enable_picodlp,
.platform_disable = svga050_panel_disable_picodlp,
.data = &svga050_pdata,
};
static struct omap_dss_device *svga050_dss_devices[] = {
&svga050_device,
};
static struct picodlp_panel_data sdp4430_picodlp_pdata = {
.svga050_adapter_id = 2,
};
my questions are :
My code is right?
I don't know how to write display init code by seeing datasheet.
Can I write display init code by seeing this datasheet ?
In panel_probe function, how can I get adapter ID ?
how do I choose adapter I ?
Is it right that I should write only i2c slave driver code in panel code ?
How can I select I2C master ? I want to use I2C3 or I2C4 for display commands
Related
So i was trying this question in which I have written the below code:-
#include <bits/stdc++.h>
using namespace std;
struct Node
{
char data;
struct Node* next;
};
struct Node *reverseList(struct Node *head)
{
Node *current = head;
Node *prev = NULL, *next = NULL;
while (current != NULL)
{
next = current->next;
current->next = prev;
prev = current;
current = next;
}
head = prev;
return head;
}
bool isPalindrome(struct Node* head)
{
Node* frontHead = head;
Node* reverseHead = reverseList(head);
Node* temp = reverseHead;
cout<<"back view"<<endl;
while(temp)
{
cout<<temp->data<<"->";
temp = temp ->next;
}
cout<<endl;
cout<<"front view"<<endl;
temp = frontHead;
while(temp)
{
cout<<temp->data<<"->";
temp = temp ->next;
}
cout<<endl;
bool flag = true;
// while(frontHead && reverseHead)
// {
// // cout<<frontHead->data<<"-->"<<reverseHead->data<<endl;
// if(frontHead->data !=reverseHead->data)
// {
// flag=false;
// break;
// }
// frontHead = frontHead->next;
// reverseHead = reverseHead->next;
// }
return flag;
}
void push(struct Node** head_ref, char new_data)
{
struct Node* new_node = (struct Node*)malloc(
sizeof(struct Node));
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
void printList(struct Node* ptr)
{
while (ptr != NULL)
{
cout << ptr->data << "->";
ptr = ptr->next;
}
cout << "NULL" << "\n";
}
// Driver code
int main()
{
struct Node* head = NULL;
char str[] = "abacba";
int i;
for (i = 0; i<strlen(str); i++)
push(&head, str[i]);
// printList(head);
isPalindrome(head) ? cout << "Is Palindrome" << "\n\n" : cout << "Not Palindrome" << "\n\n";
return 0;
}
When I try to print the node form the front as well as from the backward(after reversing the linked list I got this output:-
back view
a->b->a->c->b->a->
front view
a->
Is Palindrome
can Anyone tell me why i am not able to get the front view of the linked list .
Any help will be appreciated
im working over foreing code, its an antihack for a mmorpg game. Being said that, the code present crash or false detection in some Windows 10 users (it works always great for 7 and 8.1), te problem came from a function that uses NtQuerySystemInformation and then compare process handles.
Thx for any who can help or give a hint.
Im gonna leave the code for you:
ProcessQuery.h
#pragma once
typedef LONG KPRIORITY;
typedef NTSTATUS(WINAPI*NTQUERYSYSTEMINFORMATION)(SYSTEM_INFORMATION_CLASS,PVOID,ULONG,PULONG);
#define STATUS_SUCCESS ((NTSTATUS)0x00000000)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004)
#define STATUS_DATA_ERROR ((NTSTATUS)0xC000003E)
#define SystemExtendedProcessInformation ((SYSTEM_INFORMATION_CLASS)57)
#define SystemHandleInformation ((SYSTEM_INFORMATION_CLASS)16)
#define SystemExtendedHandleInformation ((SYSTEM_INFORMATION_CLASS)64)
#define SystemKernelDebuggerInformation ((SYSTEM_INFORMATION_CLASS)35)
enum THREAD_STATE
{
Running = 2,
Waiting = 5,
};
enum KWAIT_REASON
{
Executive = 0,
FreePage = 1,
PageIn = 2,
PoolAllocation = 3,
DelayExecution = 4,
Suspended = 5,
UserRequest = 6,
WrExecutive = 7,
WrFreePage = 8,
WrPageIn = 9,
WrPoolAllocation = 10,
WrDelayExecution = 11,
WrSuspended = 12,
WrUserRequest = 13,
WrEventPair = 14,
WrQueue = 15,
WrLpcReceive = 16,
WrLpcReply = 17,
WrVirtualMemory = 18,
WrPageOut = 19,
WrRendezvous = 20,
Spare2 = 21,
Spare3 = 22,
Spare4 = 23,
Spare5 = 24,
WrCalloutStack = 25,
WrKernel = 26,
WrResource = 27,
WrPushLock = 28,
WrMutex = 29,
WrQuantumEnd = 30,
WrDispatchInt = 31,
WrPreempted = 32,
WrYieldExecution = 33,
WrFastMutex = 34,
WrGuardedMutex = 35,
WrRundown = 36,
MaximumWaitReason = 37,
};
struct CLIENT_ID
{
PVOID UniqueProcess;
PVOID UniqueThread;
};
struct SYSTEM_THREAD_INFO
{
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientId;
KPRIORITY Priority;
LONG BasePriority;
ULONG ContextSwitches;
ULONG ThreadState;
KWAIT_REASON WaitReason;
};
struct SYSTEM_EXTENDED_THREAD_INFO
{
SYSTEM_THREAD_INFO ThreadInfo;
PVOID StackBase;
PVOID StackLimit;
PVOID Win32StartAddress;
PVOID TebAddress; // since VISTA
ULONG Reserved1;
ULONG Reserved2;
ULONG Reserved3;
};
struct SYSTEM_PROCESS_INFO
{
ULONG NextEntryOffset;
ULONG NumberOfThreads;
LARGE_INTEGER WorkingSetPrivateSize; // since VISTA
ULONG HardFaultCount; // since WIN7
ULONG NumberOfThreadsHighWatermark; // since WIN7
ULONGLONG CycleTime; // since WIN7
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
KPRIORITY BasePriority;
HANDLE UniqueProcessId;
HANDLE InheritedFromUniqueProcessId;
ULONG HandleCount;
ULONG SessionId;
ULONG_PTR UniqueProcessKey; // since VISTA (requires SystemExtendedProcessInformation)
SIZE_T PeakVirtualSize;
SIZE_T VirtualSize;
ULONG PageFaultCount;
SIZE_T PeakWorkingSetSize;
SIZE_T WorkingSetSize;
SIZE_T QuotaPeakPagedPoolUsage;
SIZE_T QuotaPagedPoolUsage;
SIZE_T QuotaPeakNonPagedPoolUsage;
SIZE_T QuotaNonPagedPoolUsage;
SIZE_T PagefileUsage;
SIZE_T PeakPagefileUsage;
SIZE_T PrivatePageCount;
LARGE_INTEGER ReadOperationCount;
LARGE_INTEGER WriteOperationCount;
LARGE_INTEGER OtherOperationCount;
LARGE_INTEGER ReadTransferCount;
LARGE_INTEGER WriteTransferCount;
LARGE_INTEGER OtherTransferCount;
SYSTEM_THREAD_INFO Threads[1];
};
struct SYSTEM_EXTENDED_PROCESS_INFO
{
ULONG NextEntryOffset;
ULONG NumberOfThreads;
LARGE_INTEGER WorkingSetPrivateSize; // since VISTA
ULONG HardFaultCount; // since WIN7
ULONG NumberOfThreadsHighWatermark; // since WIN7
ULONGLONG CycleTime; // since WIN7
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
KPRIORITY BasePriority;
HANDLE UniqueProcessId;
HANDLE InheritedFromUniqueProcessId;
ULONG HandleCount;
ULONG SessionId;
ULONG_PTR UniqueProcessKey; // since VISTA (requires SystemExtendedProcessInformation)
SIZE_T PeakVirtualSize;
SIZE_T VirtualSize;
ULONG PageFaultCount;
SIZE_T PeakWorkingSetSize;
SIZE_T WorkingSetSize;
SIZE_T QuotaPeakPagedPoolUsage;
SIZE_T QuotaPagedPoolUsage;
SIZE_T QuotaPeakNonPagedPoolUsage;
SIZE_T QuotaNonPagedPoolUsage;
SIZE_T PagefileUsage;
SIZE_T PeakPagefileUsage;
SIZE_T PrivatePageCount;
LARGE_INTEGER ReadOperationCount;
LARGE_INTEGER WriteOperationCount;
LARGE_INTEGER OtherOperationCount;
LARGE_INTEGER ReadTransferCount;
LARGE_INTEGER WriteTransferCount;
LARGE_INTEGER OtherTransferCount;
SYSTEM_EXTENDED_THREAD_INFO Threads[1];
};
struct SYSTEM_HANDLE_ENTRY_INFO
{
USHORT UniqueProcessId;
USHORT CreatorBackTraceIndex;
UCHAR ObjectTypeIndex;
UCHAR HandleAttributes;
USHORT HandleValue;
PVOID Object;
ULONG GrantedAccess;
};
struct SYSTEM_HANDLE_INFO
{
ULONG NumberOfHandles;
SYSTEM_HANDLE_ENTRY_INFO Handles[1];
};
struct SYSTEM_HANDLE_ENTRY_INFO_EX
{
PVOID Object;
ULONG UniqueProcessId;
ULONG HandleValue;
ULONG GrantedAccess;
USHORT CreatorBackTraceIndex;
USHORT ObjectTypeIndex;
ULONG HandleAttributes;
ULONG Reserved;
};
struct SYSTEM_HANDLE_INFO_EX
{
ULONG NumberOfHandles;
ULONG Reserved;
SYSTEM_HANDLE_ENTRY_INFO_EX Handles[1];
};
struct SYSTEM_KERNEL_DEBUGGER_INFO
{
BOOLEAN DebuggerEnabled;
BOOLEAN DebuggerNotPresent;
};
class CProcessQuery
{
public:
CProcessQuery();
virtual ~CProcessQuery();
void Start();
void Close();
bool Fetch(SYSTEM_INFORMATION_CLASS SysInfoClass,DWORD QuerySize);
SYSTEM_HANDLE_INFO* GetHandleInfo();
SYSTEM_HANDLE_INFO_EX* GetExtendedHandleInfo();
SYSTEM_KERNEL_DEBUGGER_INFO* GetKernelDebuggerInfo();
SYSTEM_PROCESS_INFO* GetProcessInfoByID(HANDLE ProcessId);
SYSTEM_EXTENDED_PROCESS_INFO* GetExtendedProcessInfoByID(HANDLE ProcessId);
SYSTEM_THREAD_INFO* GetThreadInfoByID(SYSTEM_PROCESS_INFO* lpSystemProcessInfo,HANDLE ThreadId);
SYSTEM_EXTENDED_THREAD_INFO* GetExtendedThreadInfoByID(SYSTEM_EXTENDED_PROCESS_INFO* lpSystemProcessInfo,HANDLE ThreadId);
public:
static NTQUERYSYSTEMINFORMATION m_NtQuerySystemInformation;
private:
BYTE* m_QueryData;
DWORD m_QuerySize;
NTSTATUS m_QueryStatus;
};
ProcessQuery.cpp:
void CProcessQuery::Start() // OK
{
this->m_QueryData = 0;
this->m_QuerySize = 0;
this->m_QueryStatus = STATUS_SUCCESS;
}
void CProcessQuery::Close() // OK
{
this->m_QueryData = ((this->m_QueryData==0)?(BYTE*)0:((HeapFree(GetProcessHeap(),0,this->m_QueryData)==0)?(BYTE*)0:(BYTE*)0));
this->m_QuerySize = 0;
this->m_QueryStatus = STATUS_SUCCESS;
}
bool CProcessQuery::Fetch(SYSTEM_INFORMATION_CLASS SysInfoClass,DWORD QuerySize) // OK
{
while(this->m_QueryData != 0 || (this->m_QueryData=(BYTE*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(this->m_QuerySize=((this->m_QuerySize<QuerySize)?QuerySize:this->m_QuerySize)))) != 0)
{
DWORD ReturnLength;
if((this->m_QueryStatus=CProcessQuery::m_NtQuerySystemInformation(SysInfoClass,this->m_QueryData,this->m_QuerySize,&ReturnLength)) == STATUS_INFO_LENGTH_MISMATCH)
{
this->m_QueryData = ((this->m_QueryData==0)?(BYTE*)0:((HeapFree(GetProcessHeap(),0,this->m_QueryData)==0)?(BYTE*)0:(BYTE*)0));
this->m_QuerySize = ReturnLength;
}
else
{
return ((this->m_QueryStatus==STATUS_SUCCESS)?1:0);
}
}
return 0;
}
SYSTEM_HANDLE_INFO* CProcessQuery::GetHandleInfo() // OK
{
return ((SYSTEM_HANDLE_INFO*)this->m_QueryData);
}
SYSTEM_HANDLE_INFO_EX* CProcessQuery::GetExtendedHandleInfo() // OK
{
return ((SYSTEM_HANDLE_INFO_EX*)this->m_QueryData);
}
SYSTEM_KERNEL_DEBUGGER_INFO* CProcessQuery::GetKernelDebuggerInfo() // OK
{
return ((SYSTEM_KERNEL_DEBUGGER_INFO*)this->m_QueryData);
}
SYSTEM_PROCESS_INFO* CProcessQuery::GetProcessInfoByID(HANDLE ProcessId) // OK
{
SYSTEM_PROCESS_INFO* lpSystemProcessInfo = (SYSTEM_PROCESS_INFO*)this->m_QueryData;
while(true)
{
if(lpSystemProcessInfo->UniqueProcessId == ProcessId)
{
return lpSystemProcessInfo;
}
if(lpSystemProcessInfo->NextEntryOffset == 0)
{
break;
}
lpSystemProcessInfo = (SYSTEM_PROCESS_INFO*)((BYTE*)lpSystemProcessInfo+lpSystemProcessInfo->NextEntryOffset);
}
return 0;
}
SYSTEM_EXTENDED_PROCESS_INFO* CProcessQuery::GetExtendedProcessInfoByID(HANDLE ProcessId) // OK
{
SYSTEM_EXTENDED_PROCESS_INFO* lpSystemProcessInfo = (SYSTEM_EXTENDED_PROCESS_INFO*)this->m_QueryData;
while(true)
{
if(lpSystemProcessInfo->UniqueProcessId == ProcessId)
{
return lpSystemProcessInfo;
}
if(lpSystemProcessInfo->NextEntryOffset == 0)
{
break;
}
lpSystemProcessInfo = (SYSTEM_EXTENDED_PROCESS_INFO*)((BYTE*)lpSystemProcessInfo+lpSystemProcessInfo->NextEntryOffset);
}
return 0;
}
SYSTEM_THREAD_INFO* CProcessQuery::GetThreadInfoByID(SYSTEM_PROCESS_INFO* lpSystemProcessInfo,HANDLE ThreadId) // OK
{
SYSTEM_THREAD_INFO* lpSystemThreadInfo = lpSystemProcessInfo->Threads;
for(DWORD n=0;n < lpSystemProcessInfo->NumberOfThreads;n++,lpSystemThreadInfo++)
{
if(lpSystemThreadInfo->ClientId.UniqueThread == ThreadId)
{
return lpSystemThreadInfo;
}
}
return 0;
}
SYSTEM_EXTENDED_THREAD_INFO* CProcessQuery::GetExtendedThreadInfoByID(SYSTEM_EXTENDED_PROCESS_INFO* lpSystemProcessInfo,HANDLE ThreadId) // OK
{
SYSTEM_EXTENDED_THREAD_INFO* lpSystemThreadInfo = lpSystemProcessInfo->Threads;
for(DWORD n=0;n < lpSystemProcessInfo->NumberOfThreads;n++,lpSystemThreadInfo++)
{
if(lpSystemThreadInfo->ThreadInfo.ClientId.UniqueThread == ThreadId)
{
return lpSystemThreadInfo;
}
}
return 0;
}
Scan Function:
bool HANDLE_PROTECTION_INIT() // OK
{
CProcessQuery ProcessQuery;
HANDLE HandleValue = OpenProcess(PROCESS_VM_READ,0,GetCurrentProcessId());
if(ProcessQuery.Fetch(SystemExtendedHandleInformation,sizeof(SYSTEM_HANDLE_INFO_EX)) != 0)
{
SYSTEM_HANDLE_INFO_EX* lpSystemHandleInfo = ProcessQuery.GetExtendedHandleInfo();
if(lpSystemHandleInfo != 0)
{
SYSTEM_HANDLE_ENTRY_INFO_EX* lpSystemHandleEntryInfo = lpSystemHandleInfo->Handles;
if(lpSystemHandleEntryInfo != 0)
{
for(DWORD n=0;n < lpSystemHandleInfo->NumberOfHandles;n++,lpSystemHandleEntryInfo++)
{
if(lpSystemHandleEntryInfo->UniqueProcessId == GetCurrentProcessId() && lpSystemHandleEntryInfo->HandleValue == ((DWORD)HandleValue))
{
HandleProtectionNumber = (DWORD)lpSystemHandleEntryInfo->ObjectTypeIndex;
HandleProtectionObject = (DWORD)lpSystemHandleEntryInfo->Object;
ProcessQuery.Close();
return 1;
}
}
}
}
}
ProcessQuery.Close();
return 0;
}
bool HANDLE_PROTECTION_SCAN() // THIS FUNCTION IS CALLED IN A THREAD EVERY 2000 MS.
{
if(gMemoryGuardSwitch == 0 || (gMemoryGuardNumber & MEMORY_GUARD_NUMBER_HANDLE) == 0)
{
return 1;
}
static CProcessQuery ProcessQuery;
std::map<DWORD,std::vector<DWORD>> HandleProtectionTable;
if(ProcessQuery.Fetch(SystemExtendedHandleInformation,sizeof(SYSTEM_HANDLE_INFO_EX)) != 0)
{
SYSTEM_HANDLE_INFO_EX* lpSystemHandleInfo = ProcessQuery.GetExtendedHandleInfo();
if(lpSystemHandleInfo != 0)
{
SYSTEM_HANDLE_ENTRY_INFO_EX* lpSystemHandleEntryInfo = lpSystemHandleInfo->Handles;
if(lpSystemHandleEntryInfo != 0)
{
for(DWORD n=0;n < lpSystemHandleInfo->NumberOfHandles;n++,lpSystemHandleEntryInfo++)
{
if(lpSystemHandleEntryInfo->UniqueProcessId != GetCurrentProcessId() && lpSystemHandleEntryInfo->ObjectTypeIndex == HandleProtectionNumber && lpSystemHandleEntryInfo->Object == ((LPVOID)HandleProtectionObject) && (lpSystemHandleEntryInfo->GrantedAccess & PROCESS_VM_WRITE) != 0)
{
std::map<DWORD,std::vector<DWORD>>::iterator it = HandleProtectionTable.find(lpSystemHandleEntryInfo->UniqueProcessId);
if(it == HandleProtectionTable.end())
{
HandleProtectionTable.insert(std::pair<DWORD,std::vector<DWORD>>(lpSystemHandleEntryInfo->UniqueProcessId,std::vector<DWORD>(1,lpSystemHandleEntryInfo->HandleValue)));
continue;
}
else
{
if(it->second.size() >= MAX_HANDLE_PROTECTION_COUNT)
{
CGDetect(CLIENT_DISCONNECT_MEMORY_DETECTION, 0, 0);
//CHClientDisconnectSend(CLIENT_DISCONNECT_MEMORY_DETECTION,0,lpSystemHandleEntryInfo->UniqueProcessId);
return 0;
}
else
{
it->second.push_back(lpSystemHandleEntryInfo->HandleValue);
continue;
}
}
}
}
}
}
}
return 1;
}
Memory Guard Struct:
enum eMemoryGuardNumber
{
MEMORY_GUARD_NUMBER_NONE = 0,
MEMORY_GUARD_NUMBER_HANDLE = 1,
MEMORY_GUARD_NUMBER_INJECT = 2,
};
if(IsWindows10OrGreater)
{
DWORD gMemoryGuardNumber = 8;
}
else
{
DWORD gMemoryGuardNumber = 3;
}
Well, in case is usefull to someone, problem is handlecount if different in w7 than in w10... have to put up to 12 in w10 for correctly use
I am trying to insert into a simply linked list from a file. Do you
guys have any idea why the function doesn't insert the last line in my
file?
This is the file:
10,Ghidul Ciberbobocului,Stan Daria,3,Popescu Matei,Ionescu Gigel,Ilinca Radu,100.5
2,Spring IT,Mirodene Cristina,4,Dumitru Mihai,Vasiliu Valentin,Balasa Silvia,Dumitru Ion,400.
89,Serile teatrului studentesc,Petre Ion,2,Nicolae Ramona,Stan Alberto,1000
1,Tutoring,Petre Miruna,2,Bode Cristina,Angelescu Paul,500.5
11,IT Fest,Ciurea Ion,2,Ionescu Georgiana,Neagu Bianca,100.6
My code:
struct Proiect {
int id;
char* numeProiect;
char* numeCoordonator;
unsigned int nrStudenti;
char** studenti;
float costInscriere;
};
struct nodLista {
Proiect proiect;
nodLista *next;
};
nodLista* inserareNod(nodLista *first, Proiect p) {
nodLista* newNode = new nodLista;
newNode->next = NULL;
newNode->proiect = p;
if (!first) {
return newNode;
}
nodLista* aux = first;
while (aux->next) {
aux = aux->next;
}
aux->next = newNode;
printf("%d\n", aux->proiect.id);
return first;
}
void main() {
nodLista* first = NULL;
Proiect proiect;
FILE *f = fopen("proiecte2.txt", "r");
char line[150];
int nrProiecte = 0;
if (f) {
while (fgets(line, sizeof(line), f)) {
nrProiecte++;
}
printf("Nr proiecte: %d",nrProiecte);
fclose(f);
}
else {
printf("Fisierul nu a fost gasit");
}
f = fopen("proiecte2.txt", "r");
char *token[150], sep_list[] = ",";
Proiect* listaProiecte;
listaProiecte = (Proiect*)malloc(nrProiecte * sizeof(Proiect));
int i = 0;
if (f) {
while(fgets(line, sizeof(line), f)) {
token[0] = strtok(line, sep_list);
listaProiecte[i].id = atoi(token[0]);
first = inserareNod(first, listaProiecte[i]);
i++;
}
}
else printf("Fisierul nu aputut fi deschis");
}
Output: It only displays 10 , 2, 89 and 1.
Did you make prints inside this function to check if it's doing the while correctly?
while(fgets(line, sizeof(line), f)) {
token[0] = strtok(line, sep_list);
listaProiecte[i].id = atoi(token[0]);
first = inserareNod(first, listaProiecte[i]);
i++;
}
I'm trying to get the gateway ip address of the wifi I'm connected to. I'm using the answer in this question but I'm getting an error on the codes.
When I use this in my project
- (NSString *)getGatewayIP {
NSString *ipString = nil;
struct in_addr gatewayaddr;
int r = getdefaultgateway(&(gatewayaddr.s_addr));
if(r >= 0) {
ipString = [NSString stringWithFormat: #"%s",inet_ntoa(gatewayaddr)];
NSLog(#"default gateway : %#", ipString );
} else {
NSLog(#"getdefaultgateway() failed");
}
return ipString;
}
I get this error when I try to build my project:
Undefined symbols for architecture arm64: "getdefaultgateway(unsigned int*)"
Here is the getgateway.c
int getdefaultgateway(in_addr_t * addr)
{
int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET,
NET_RT_FLAGS, RTF_GATEWAY};
size_t l;
char * buf, * p;
struct rt_msghdr * rt;
struct sockaddr * sa;
struct sockaddr * sa_tab[RTAX_MAX];
int i;
int r = -1;
if(sysctl(mib, sizeof(mib)/sizeof(int), 0, &l, 0, 0) < 0) {
return -1;
}
if(l>0) {
buf = malloc(l);
if(sysctl(mib, sizeof(mib)/sizeof(int), buf, &l, 0, 0) < 0) {
return -1;
}
for(p=buf; p<buf+l; p+=rt->rtm_msglen) {
rt = (struct rt_msghdr *)p;
sa = (struct sockaddr *)(rt + 1);
for(i=0; i<RTAX_MAX; i++) {
if(rt->rtm_addrs & (1 << i)) {
sa_tab[i] = sa;
sa = (struct sockaddr *)((char *)sa + ROUNDUP(sa->sa_len));
} else {
sa_tab[i] = NULL;
}
}
if( ((rt->rtm_addrs & (RTA_DST|RTA_GATEWAY)) == (RTA_DST|RTA_GATEWAY))
&& sa_tab[RTAX_DST]->sa_family == AF_INET
&& sa_tab[RTAX_GATEWAY]->sa_family == AF_INET) {
if(((struct sockaddr_in *)sa_tab[RTAX_DST])->sin_addr.s_addr == 0) {
char ifName[128];
if_indextoname(rt->rtm_index,ifName);
if(strcmp("en0",ifName)==0){
*addr = ((struct sockaddr_in *)(sa_tab[RTAX_GATEWAY]))->sin_addr.s_addr;
r = 0;
}
}
}
}
free(buf);
}
return r;
}
Do I need to add frameworks? I've got no idea how to make it work.
Yes. .mm was my next question to you.
You're running into C++ name mangling issues.
In whichever .h file where you define and ultimately include/import the getdefaultgateway function, add this before:
#ifdef __cplusplus
extern "C" {
#endif
and after:
#ifdef __cplusplus
}
#endif
The code below does compile, but it doesn't run as it should.
I'm not sure what am I doing wrong, so would someone be willing to tell me what I did wrong and what I should have done better.
What do I need to change to make it run properly?
#include<stdio.h>
#include<stdlib.h>
typedef struct sub_Node
{
int value;
struct sub_Node *next;
}sub_Node;
typedef struct Node
{
char *name;
struct Node *next;
struct sub_Node *sub_start;
}Node;
Node *start;
void add_player(char *name)
{
Node *temp;
temp = (Node *)malloc(sizeof(Node));
temp->next = start;
temp->name = name;
temp->sub_start = (sub_Node *)malloc(sizeof(sub_Node));
temp->sub_start->next = NULL;
temp->sub_start->value = -1;
start = temp;
}
void initialize()
{
char *p;
p = "\0";
add_player(p);
}
void remove_player(char *name)
{
Node *p;
for(p = start; p!= NULL; p = p->next)
if(p->name == name)
{
p->name = p->next->name;
p->next = p->next->next;
}
}
sub_Node* add_descending(sub_Node* sub_start, int piece_value)
{
sub_Node *temp, *prev, *next;
temp = (sub_Node *)malloc(sizeof(sub_Node));
temp->value = piece_value;
temp->next = NULL;
prev = NULL;
next = sub_start;
while(next && next->value >= piece_value)
{
prev = next;
next = next->next;
}
if(!next)
{
prev->next = temp;
}
else
{
if(prev)
{
temp->next = prev->next;
prev->next = temp;
}
else
{
temp->next = sub_start;
sub_start = temp;
}
}
return sub_start;
}
void add_piece(char *name, int piece_value)
{
Node *p;
int c;
for(p = start; p!=NULL; p = p->next)
if(p->name == name)
p->sub_start = add_descending(p->sub_start, piece_value);
}
void print_pieces(char *name)
{
Node *p;
sub_Node *q;
for(p = start; p!=NULL; p = p->next)
if(p->name == name)
{
printf("The values of the owned pieces are:");
for(q = p->sub_start; q->value != -1; q = q->next)
printf(" %d", q->value);
}
}
int lose_piece(char *name)
{
Node *p;
sub_Node *q;
int aux;
for(p = start; p!=NULL; p = p->next)
if(p->name == name)
{
for(q = p->sub_start; q->next->value != -1; q = q->next) {}
aux = q->value;
q->value = q->next->value;
q->next = q->next->next;
return aux;
}
}
void print_players()
{
Node *p;
printf("The players are: ");
for(p = start; p->name != "\0"; p = p->next)
printf("%s ", p->name);
printf("\n");
}
int main()
{
initialize();
int y, value;
char name[20];
printf("Insert a digit to execute the desired task:\n"
"<0> end the program\n"
"<1> add a player, who doesn't own any piece yet\n"
"<2> remove a player and all his pieces\n"
"<3> print the name of all the players\n"
"<4> a player gets a piece\n"
"<5> a player loses the piece with the lowest value out of the ones that he has\n"
"<6> prints the pieces of a player in a descending order by value\n\n");
do
{
printf("digit: ");
scanf("%d", &y);
switch(y)
{
case 1:
printf("Insert the player's name: ");
scanf("%s", name);
add_player(name);
break;
case 2:
printf("Insert the player's name: ");
scanf("%s", name);
remove_player(name);
break;
case 3:
print_players();
break;
case 4:
printf("Insert the player's name: ");
scanf("%s", name);
printf("Insert the value of the piece: ");
scanf("%d", value);
add_piece(name, value);
break;
case 5:
printf("Insert the player's name: ");
scanf("%s", name);
printf("\nThe player loses the piece: %d\n", lose_piece(name));
break;
case 6:
printf("Insert the player's name: ");
scanf("%s", name);
print_pieces(name);
}
} while(y != 0);
return 0;
}
your two main problems where this scanf("%d", value); value should be passed by reference like this scanf("%d", &value); and the second is string comparison in c as in your code p->name != "\0" and if(p->name == name) this is wrong because actually you are making comparison between addresses of strings (where it resides in memory) not strings values. to compare strings in c you have to use strcmp and families.
Actually 3 main problems. for setting string values as you did in temp->name = name; is little bit more complicated than that. because you are assigning to temp->name a string from the stack that is volatile (the stack will be more likely invalid soon you return from the function) . in your case you have to alloc a new string by using malloc (and friends) or just by using strdup.
here is as a bonus a slightly rewrite of your program, you will find many advises and is a good starting point for how to structure your code for an easy maintenance.
still want to advise you to change members and variables to more declarative names as in sub_start and sub_Node can be PieceNode and pieces respectively.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct sub_Node
{
int value;
struct sub_Node *next;
}sub_Node;
typedef struct Node
{
char *name;
struct Node *next;
struct Node *prev; // this to make life easyer
struct sub_Node *sub_start;
}Node;
Node *start = NULL;
Node *find_player(char *name){
Node *tmp = start;
while( tmp ){
if(strcmp(tmp->name,name) == 0 )
break;
tmp = tmp->next;
}
return tmp;
}
// int to return Error Code
//
int add_player(char *name)
{
Node *temp;
if( find_player(name)) {
printf("player %s already exists\n", name);
return 1;
}
// do not cast malloc
temp = malloc(sizeof(Node));
if( !temp ){
printf ("not enough memory\n");
return 2;
}
temp->name = strdup ( name); // here was your error
temp->sub_start = NULL; // keep it simple
temp->prev = NULL;
temp->next = start;
if(start)
start->prev = temp;
start = temp;
return 0; // no error
}
void DestroyPieces(sub_Node* piece){
if( piece ) {
DestroyPieces( piece->next );
free( piece );
}
}
// as usual use int to return error code
int remove_player(char *name)
{
Node *player = find_player(name);
if ( !player ){
return 1; // player not found
}
if ( player->next ){
player->next->prev = player->prev;
}
if ( player->prev ){
player->prev->next = player->next;
}
DestroyPieces(player->sub_start);
free(player->name);
free(player);
return 0; // success
}
sub_Node* new_piece(int value){
sub_Node *temp = malloc( sizeof(sub_Node) );
if(temp){
temp->value = value;
temp->next = NULL;
}
return temp;
}
// int to return error code
// pass sub_start as pointer to pointer, as it might be updated
int add_descending(sub_Node** psub_start, int piece_value)
{
sub_Node *piece, *current, *prev = NULL;
if( !psub_start){
return 5; // this should not happen
}
current = *psub_start;
piece = new_piece( piece_value );
if( !piece ) return 1; // no mem
if(!current){
// this is the first and only one
*psub_start = piece;
return 0; // OK
}
while(current && current->value >= piece_value)
{
prev = current;
current = current->next;
}
if( prev )
prev->next = piece;
piece->next = current;
if( current == *psub_start ){
*psub_start = piece;
}
return 0 ; // OK
}
void add_piece(Node * player, int piece_value)
{
if ( !player) {
return ;
}
if(add_descending (&(player->sub_start), piece_value) == 0 )
return ; //OK
printf("an error occured while adding a piece (%d) to player '%s'\n",piece_value,player->name);
}
void print_pieces(Node *player)
{
sub_Node *q;
if( !player ){
return;
}
if( !player->sub_start ){
printf("Player '%s' has no pieces\n",player->name);
return;
}
printf("The values of the owned pieces are:");
for(q = player->sub_start; q != NULL; q = q->next)
printf(" %d", q->value);
printf("\n");
}
void lose_piece(Node *player)
{
if( !player ){
return;
}
sub_Node *q, *prev = NULL;
int aux;
if( !player->sub_start ){
printf("Player '%s' has no pieces\n",player->name);
return;
}
// i think you want drop the last one
for(q = player->sub_start; q->next != NULL ;prev = q, q = q->next) {
;
}
if(prev)
prev->next = NULL;
else
player->sub_start = NULL;
aux = q->value;
free(q);
printf("\nThe player loses the piece: %d\n", aux);
return;
}
void print_players()
{
Node *p;
if( !start ){
printf("there are no players, try to add some\n");
return;
}
printf("The players are: ");
for(p = start; p != NULL; p = p->next)
printf("%s ", p->name);
printf("\n");
}
void print_menu(void){
printf("Insert a digit to execute the desired task:\n"
"<0> end the program\n"
"<1> add a player, who doesn't own any piece yet\n"
"<2> remove a player and all his pieces\n"
"<3> print the name of all the players\n"
"<4> a player gets a piece\n"
"<5> a player loses the piece with the lowest value out of the ones that he has\n"
"<6> prints the pieces of a player in a descending order by value\n\n");
}
Node * get_player(char *name){
Node *player = find_player(name);
if(!player)
printf("Player '%s' do not exists\n",name);
return player;
}
int main()
{
// initialize(); no more needed
int y, value;
char name[20];
Node *player;
print_menu();
do
{
printf("digit: ");
scanf("%d", &y);
switch(y)
{
case 1:
printf("Insert the player's name: ");
scanf("%s", name);
add_player(name);
break;
case 2:
printf("Insert the player's name: ");
scanf("%s", name);
player = get_player(name);
if( player )
break;
case 3:
print_players();
break;
case 4:
printf("Insert the player's name: ");
scanf("%s", name);
player = get_player(name);
if( player ){
printf("Insert the value of the piece: ");
scanf("%d", &value);
add_piece(player, value);
}
break;
case 5:
printf("Insert the player's name: ");
scanf("%s", name);
player = get_player(name);
lose_piece(player);
break;
case 6:
printf("Insert the player's name: ");
scanf("%s", name);
player = get_player(name);
print_pieces(player);
}
} while(y != 0);
return 0;
}