ZwQueryDirectoryFile Buffer Overflow - windows

I am trying to write Windows driver code to scan a directory for file names:
HANDLE directory_handle;
FILE_BOTH_DIR_INFORMATION directory_information;
IO_STATUS_BLOCK io_status_block;
NTSTATUS status;
OBJECT_ATTRIBUTES directory_attributes;
InitializeObjectAttributes(&directory_attributes ,
&directory_name ,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
0 ,
0 );
status = ZwCreateFile(&directory_handle ,
FILE_LIST_DIRECTORY | SYNCHRONIZE ,
&directory_attributes ,
&io_status_block ,
0 ,
0 ,
FILE_SHARE_VALID_FLAGS ,
FILE_OPEN ,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE,
0 ,
0 );
status = ZwQueryDirectoryFile(directory_handle ,
NULL ,
0 ,
0 ,
&io_status_block ,
&directory_information ,
sizeof(directory_information),
FileBothDirectoryInformation ,
TRUE ,
NULL ,
FALSE );
status = ZwQueryDirectoryFile(directory_handle ,
NULL ,
0 ,
0 ,
&io_status_block ,
&directory_information ,
sizeof(directory_information),
FileBothDirectoryInformation ,
TRUE ,
NULL ,
FALSE );
The first call to ZwQueryDirectoryFile() returns a STATUS_SUCCESS (0x00000000) result, but the second call returns a status of STATUS_BUFFER_OVERFLOW (0x80000005). Do you know what might cause this buffer-overflow error?
Thank you.

STATUS_BUFFER_OVERFLOW indicates that the buffer isn't big enough to return the full filename (however we know the buffer is big enough for at least the base structure, else STATUS_BUFFER_TOO_SMALL).
What's happening here is the first call successfully returned the "." entry (as there is room in the base structure for a single character filename), but the second call failed with STATUS_BUFFER_OVERFLOW because the buffer isn't big enough for the ".." entry.

FILE_ID_BOTH_DIR_INFORMATION is a variable-length structure.
You will need to allocate suffucient space to receive the path string at the end of the structure.
You will need to pass the size of the allocated buffer to ZwQueryDirectoryFile rather than sizeof(FILE_ID_BOTH_DIR_INFORMATION)
No idea why the first one works.

Related

Visual Studio 2013 SerialPort not receiving all data

I am currently working on a project that requires serial communication between PIC 24FV16KA302 and a PC software.
I have searched the Internet for the past 3 days and i cant find an answer for my problem so i decided to ask here . This is my first visual studio program so i dont have any experience with the software.
The PIC has few variables and two 8x16 tables that i need to view and modify on the PC side . The problem comes when i send the tables , all other information is received without a problem . I am using serial connection ( 38400/8-N-1 ) via uart to usb converter
FT232
When the PC send "AT+RTPM" to the PIC .
Button7.Click
SerialPort1.ReceivedBytesThreshold = 128
MachineState = MS.Receive_table
SerialPort1.Write("AT+RTPM")
End Sub
The PIC sends back 128 Bytes( the values in the table )
case read_table_pwm : // send pwm table
for (yy = 0 ; yy < 8 ; yy ++) {
for (xx = 0 ; xx < 16 ; xx++ ) {
uart_send_char(controll_by_pmw_map_lb[yy][xx]) ;
}
}
at_command = receive_state_idle ;
break ;
Which the software is suppose to get and display in a DataGrid.
Private Sub SerialPort1_DataReceived(sender As Object, e As IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
If MachineState = MS.Receive_table Then
SerialPort1.Read(Buffer_array_received_data, 0, 128)
cellpos = 0
For grid_y As Int16 = 0 To 7 Step 1
For grid_x As Int16 = 0 To 15 Step 1
DataGridView1.Rows(grid_y).Cells(grid_x).Value = Buffer_array_received_data(cellpos)
cellpos += 1
Next
Next
End Sub
The problem is that most of the time ( 99 % ) it displays only part of the dataset and zeros to the end , and when i try to do it again it display the other part and it starts from the beginning .
First request
Second request
If i try the same thing with another program i always get the full dataset
Realterm
Termite
I have tried doing it cell by cell , but it only works if i request them one very second , other wise i get the same problem .
After that i need to use a timer ( 100 ms ) to request live data from the PIC .
this work better but still some of the time i get some random data. I haven't focused on that for the moment because without the dataset everything else is useless .
Am i missing something or has anyone encountered the same problem ?
I managed to solve the problem by replacing
SerialPort1.Read(Buffer_array_received_data, 0, 128)
with
For byte_pos As Int16 = 0 To 127 Step 1
Buffer_array_received_data(byte_pos) = SerialPort1.ReadByte()
Next
But aren't they supposed to be the same ?

CT_FETCH error in PowerBuilder Program

I'm still learning PowerBuilder and trying to get familiar with it. I'm receiving the following error when I try to run a program against a specific document in my database:
ct_fetch(): user api layer: internal common library error: The bind of result set item 4 resulted in an overflow. ErrCode: 2.
What does this error mean? What is item 4? This is only when I run this program against a specific document in my database, any other document works fine. Please see code below:
string s_doc_nmbr, s_doc_type, s_pvds_doc_status, s_sql
long l_rtn, l_current_fl, l_apld_fl, l_obj_id
integer l_pvds_obj_id, i_count
IF cbx_1.checked = True THEN
SELECT dsk_obj.obj_usr_num,
dsk_obj.obj_type,
preaward_validation_doc_status.doc_status,
preaward_validation_doc_status.obj_id
INTO :s_doc_nmbr, :s_doc_type, :s_pvds_doc_status, :l_pvds_obj_id
FROM dbo.dsk_obj dsk_obj,
preaward_validation_doc_status
WHERE dsk_obj.obj_id = :gx_l_doc_obj_id
AND preaward_validation_doc_status.obj_id = dsk_obj.obj_id
using SQLCA;
l_rtn = sqlca.uf_sqlerrcheck("w_pdutl095_main", "ue_run_script", TRUE)
IF l_rtn = -1 THEN
RETURN -1
END IF
//check to see if document (via obj_id) exists in the preaward_validation_doc_status table.
SELECT count(*)
into :i_count
FROM preaward_validation_doc_status
where obj_id = :l_pvds_obj_id
USING SQLCA;
IF i_count = 0 THEN
//document doesn't exist
// messagebox("Update Preaward Validation Doc Status", + gx_s_doc_nmbr + ' does not exist in the Preaward Validation Document Status table.', Stopsign!)
//MC - 070815-0030-MC Updating code to insert row into preaward_validation_doc_status if row doesn't already exist
// s_sql = "insert into preaward_validation_doc_status(obj_id, doc_status) values (:gx_l_doc_obj_id, 'SUCCESS') "
INSERT INTO preaward_validation_doc_status(obj_id, doc_status)
VALUES (:gx_l_doc_obj_id, 'SUCCESS')
USING SQLCA;
IF sqlca.sqldbcode <> 0 then
messagebox('SQL ERROR Message',string(sqlca.sqldbcode)+'-'+sqlca.sqlerrtext)
return -1
end if
MessageBox("PreAward Validation ", 'Document number ' + gx_s_doc_nmbr + ' has been inserted and marked as SUCCESS for PreAward Validation.')
return 1
Else
//Update document status in the preaward_validation_doc_status table to SUCCESS
Update preaward_validation_doc_status
Set doc_status = 'SUCCESS'
where obj_id = :l_pvds_obj_id
USING SQLCA;
IF sqlca.sqldbcode <> 0 then
messagebox('SQL ERROR Message',string(sqlca.sqldbcode)+'-'+sqlca.sqlerrtext)
return -1
end if
MessageBox("PreAward Validation ", 'Document number '+ gx_s_doc_nmbr + ' has been marked as SUCCESS for PreAward Validation.')
End IF
update crt_script
set alt_1 = 'Acknowledged' where
ticket_nmbr = :gx_s_ticket_nmbr and
alt_2 = 'Running' and
doc_nmbr = :gx_s_doc_nmbr
USING SQLCA;
Return 1
ElseIF cbx_1.checked = False THEN
messagebox("Update Preaward Validation Doc Status", 'The acknowledgment checkbox must be selected for the script to run successfully. The script will now exit. Please relaunch the script and try again . ', Stopsign!)
Return -1
End IF
Save yourself a ton of headaches and use datawindows... You'd reduce that entire script to about 10 lines of code.
Paul Horan gave you good advice. This would be simple using DataWindows or DataStores. Terry Voth is on the right track for your problem.
In your code, Variable l_pvds_obj_id needs to be the same type as gx_l_doc_obj_id because if you get a result, it will always be equal to it. From the apparent naming scheme it was intended to be long. This is the kind of stuff we look for in peer reviews.
A few other things:
Most of the time you want SQLCode not SQLDbCode but you didn't say what database you're using.
After you UPDATE crt_script you need to check the result.
I don't see COMMIT or ROLLBACK. Autocommit isn't suitable when you need to update multiple tables.
You aren't using most of the values from the first SELECT. Perhaps you've simplified your code for posting or troubleshooting.

Query returning -> ORA-19011: Character string buffer too small

i'm running this query below, and oracle returning the following message: Query returning -> ORA-19011: Character string buffer too small
When i uncomment the last line, it works. I think thats why this return few results. how to solve this?
select substr(xmlagg(xmlelement (e, str||',')).extract ('//text()'),1,(Length(Trim(xmlagg (xmlelement (e, str||',')).extract ('//text()')))-2)) motivos
FROM (
select to_char(lo_valor) str
from editor_layout el,
editor_versao_documento ev,
editor_documento ed,
editor_layout_campo elc,
editor_campo ec,
editor_registro er,
editor_registro_campo erc,
pw_editor_clinico pec,
pw_documento_clinico pdc
where pec.cd_editor_registro = er.cd_registro
and pdc.cd_documento_clinico = pec.cd_documento_clinico
and ed.cd_documento = ev.cd_documento
and el.cd_versao_documento = ev.cd_versao_documento
and el.cd_layout = elc.cd_layout
and elc.cd_campo = ec.cd_campo
and elc.cd_campo = erc.cd_campo
and er.cd_registro = erc.cd_registro
and er.cd_layout = el.cd_layout
and ec.ds_identificador = 'nut_orientacoes_entregues_1'
AND To_Char(lo_valor) IS NOT null
--and Trunc(pdc.dh_documento) BETWEEN Trunc(SYSDATE-5) AND Trunc(SYSDATE)
)
The contents of the xmlagg(xmlelement ...) call returns a clob, and you are trying to stuff it into a varchar2 since you call substr for example. That will fail if the clob is too large.
The reason it will fail when you uncomment the last line is that outside that range, there are rows having the contents that is too long.

How to convert windows-1256 to utf-8 in lua?

I need to convert Arabic text from windows-1256 to utf-8 how can I do that? any help?
thanks
Try lua-iconv, which binds iconv to Lua.
local win2utf_list = [[
0x00 0x0000 #NULL
0x01 0x0001 #START OF HEADING
0x02 0x0002 #START OF TEXT
-- Download full text from
-- http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1256.TXT
0xFD 0x200E #LEFT-TO-RIGHT MARK
0xFE 0x200F #RIGHT-TO-LEFT MARK
0xFF 0x06D2 #ARABIC LETTER YEH BARREE
]]
local win2utf = {}
for w, u in win2utf_list:gmatch'0x(%x%x)%s+0x(%x+)' do
local c, t, h = tonumber(u,16), {}, 128
while c >= h do
t[#t+1] = 128 + c%64
c = math.floor(c/64)
h = h > 32 and 32 or h/2
end
t[#t+1] = 256 - 2*h + c
win2utf[w.char(tonumber(w,16))] =
w.char((table.unpack or unpack)(t)):reverse()
end
local function convert_to_utf8(win_string)
return win_string:gsub('.', win2utf)
end
Windows-1256 is one of the character-sets designed as an 8-bit overlay of ASCII. It therefore has 256 characters, each encoded as one byte.
UTF-8 is an encoding of the Unicode character-set. Being "universal", it works out that it is a superset of the Windows-1256 character-set. So, there is no loss of information by having to use "substitution characters" in place of ones that aren't members of the character-set.
Conversion is a simple matter of transforming the Windows-1256 byte for each character to the corresponding UTF-8 bytes. A lookup table is an easy way to do it.
local encoding = {
-- table maps the one byte Windows-1256 encoding for a character to a Lua string with the UTF-8 encoding for the character
"\000" , "\001" , "\002" , "\003" , "\004" , "\005" , "\006" , "\007" ,
"\008" , "\009" , "\010" , "\011" , "\012" , "\013" , "\014" , "\015" ,
"\016" , "\017" , "\018" , "\019" , "\020" , "\021" , "\022" , "\023" ,
"\024" , "\025" , "\026" , "\027" , "\028" , "\029" , "\030" , "\031" ,
"\032" , "\033" , "\034" , "\035" , "\036" , "\037" , "\038" , "\039" ,
"\040" , "\041" , "\042" , "\043" , "\044" , "\045" , "\046" , "\047" ,
"\048" , "\049" , "\050" , "\051" , "\052" , "\053" , "\054" , "\055" ,
"\056" , "\057" , "\058" , "\059" , "\060" , "\061" , "\062" , "\063" ,
"\064" , "\065" , "\066" , "\067" , "\068" , "\069" , "\070" , "\071" ,
"\072" , "\073" , "\074" , "\075" , "\076" , "\077" , "\078" , "\079" ,
"\080" , "\081" , "\082" , "\083" , "\084" , "\085" , "\086" , "\087" ,
"\088" , "\089" , "\090" , "\091" , "\092" , "\093" , "\094" , "\095" ,
"\096" , "\097" , "\098" , "\099" , "\100" , "\101" , "\102" , "\103" ,
"\104" , "\105" , "\106" , "\107" , "\108" , "\109" , "\110" , "\111" ,
"\112" , "\113" , "\114" , "\115" , "\116" , "\117" , "\118" , "\119" ,
"\120" , "\121" , "\122" , "\123" , "\124" , "\125" , "\126" , "\127" ,
"\226\130\172", "\217\190" , "\226\128\154", "\198\146" , "\226\128\158", "\226\128\166", "\226\128\160", "\226\128\161",
"\203\134" , "\226\128\176", "\217\185" , "\226\128\185", "\197\146" , "\218\134" , "\218\152" , "\218\136" ,
"\218\175" , "\226\128\152", "\226\128\153", "\226\128\156", "\226\128\157", "\226\128\162", "\226\128\147", "\226\128\148",
"\218\169" , "\226\132\162", "\218\145" , "\226\128\186", "\197\147" , "\226\128\140", "\226\128\141", "\218\186" ,
"\194\160" , "\216\140" , "\194\162" , "\194\163" , "\194\164" , "\194\165" , "\194\166" , "\194\167" ,
"\194\168" , "\194\169" , "\218\190" , "\194\171" , "\194\172" , "\194\173" , "\194\174" , "\194\175" ,
"\194\176" , "\194\177" , "\194\178" , "\194\179" , "\194\180" , "\194\181" , "\194\182" , "\194\183" ,
"\194\184" , "\194\185" , "\216\155" , "\194\187" , "\194\188" , "\194\189" , "\194\190" , "\216\159" ,
"\219\129" , "\216\161" , "\216\162" , "\216\163" , "\216\164" , "\216\165" , "\216\166" , "\216\167" ,
"\216\168" , "\216\169" , "\216\170" , "\216\171" , "\216\172" , "\216\173" , "\216\174" , "\216\175" ,
"\216\176" , "\216\177" , "\216\178" , "\216\179" , "\216\180" , "\216\181" , "\216\182" , "\195\151" ,
"\216\183" , "\216\184" , "\216\185" , "\216\186" , "\217\128" , "\217\129" , "\217\130" , "\217\131" ,
"\195\160" , "\217\132" , "\195\162" , "\217\133" , "\217\134" , "\217\135" , "\217\136" , "\195\167" ,
"\195\168" , "\195\169" , "\195\170" , "\195\171" , "\217\137" , "\217\138" , "\195\174" , "\195\175" ,
"\217\139" , "\217\140" , "\217\141" , "\217\142" , "\195\180" , "\217\143" , "\217\144" , "\195\183" ,
"\217\145" , "\195\185" , "\217\146" , "\195\187" , "\195\188" , "\226\128\142", "\226\128\143", "\219\146"
}
--
encoding.convert = function(str)
assert(type(str) == "string", "Parameter 1 must be a string")
local result = {}
for i = 1, string.len(str) do
table.insert(result, encoding[string.byte(str,i)+1])
end
return table.concat(result)
end
assert(encoding.convert("test1") == "test1", "test1 failed")
Refs:
Joel Spolsky, The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)
Roberto Ierusalimschy, Creating Strings Piece by Piece
Generally, convert from a code page (character set) to another. Must use a map table.
Which like: http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1256.TXT, from CP1256 to Unicode.
Then convert from Unicode to Utf8 (encode/decode method works between Unicode & UTF-8 , without a big map).

Suppress ORA-01403: no data found excpetion

I have the following code
SELECT SUM(nvl(book_value,
0))
INTO v_balance
FROM account_details
WHERE currency = 'UGX';
--Write the balance away
SELECT SUM(nvl(book_value,
0))
INTO v_balance
FROM account_details
WHERE currency = 'USD';
--Write the balance away
Now the problem is, there might not be data in the table for that specific currency, but there might be data for the 'USD' currency. So basically I want to select the sum into my variable and if there is no data I want my stored proc to continue and not throw the 01403 exception.
I don't want to put every select into statement in a BEGIN EXCEPTION END block either, so is there some way I can suppress the exception and just leave the v_balance variable in an undefined (NULL) state without the need for exception blocks?
select nvl(balance,0)
into v_balance
from
(
select sum(nvl(book_value,0)) as balance
from account_details
where currency = 'UGX'
);
SELECT L1.PKCODE L1CD, L1.NAME L1N, L1.LVL L1LVL,
L2.PKCODE L2CD, L2.NAME L2N, L2.LVL L2LVL,
L5.PKCODE L5CD, L5.NAME L5N,
INFOTBLM.OPBAL ( L5.PKCODE, :PSTDT, :PSTUC, :PENUC, :PSTVT, :PENVT ) OPBAL,
INFOTBLM.DEBIT ( L5.PKCODE, :PSTDT,:PENDT, :PSTUC, :PENUC, :PSTVT, :PENVT ) AMNTDR,
INFOTBLM.CREDIT ( L5.PKCODE, :PSTDT,:PENDT, :PSTUC, :PENUC, :PSTVT, :PENVT ) AMNTCR
FROM FSLVL L1, FSLVL L2, FSMAST L5
WHERE L2.FKCODE = L1.PKCODE
AND L5.FKCODE = L2.PKCODE
AND L5.PKCODE Between :PSTCD AND NVL(:PENCD,:PSTCD)
GROUP BY L1.PKCODE , L1.NAME , L1.LVL ,
L2.PKCODE , L2.NAME , L2.LVL ,
L5.PKCODE , L5.NAME
ORDER BY L1.PKCODE, L2.PKCODE, L5.PKCODE

Resources