PTR DWORD in nim lang - pointers

what is the problem of This Code:
import winim
let CurrentProcessID = GetCurrentProcessId()
var SessionID :DWORD
let result1 = ProcessIdToSessionId(CurrentProcessID,cast [ptr DWORD](SessionID))
echo SessionID
Compile Command:
nim c -d=danger -d=mingw -d=strip --passc=-flto --passl=-flto --opt=size --app=console --cpu=amd64 --out=test.exe test.nim
OutPut in Windows10:
0
but the Correct answer is:
1

ProcessIdToSessionId needs a pointer to the variable to write to, but you're passing the value of the variable itself as a pointer, that's why it fails.
Correct code would be like this (untested):
import winim
let CurrentProcessID = GetCurrentProcessId()
var SessionID: DWORD
let result1 = ProcessIdToSessionId(CurrentProcessID, addr SessionID)
echo SessionID

Related

store image as blob into sqlite success, but can't read it?

Update:
add my Cargo.toml in case needed:
serde = { version = "1.0.117", default-features = false }
serde_json = "1.0.66"
sql-builder = "3.1"
sqlite = "0.26.0"
Update:
i did #cdhowie says on comment, add println!("{:?}", row[2].kind());, it's print String.
it's the way i store blob wrong, shouldn't use serde_json::to_string or something?
OP:
i writed a demo to learn sqlite and rust, here the code:
use std::{fs::File, io::{Read, Write}};
use sql_builder::{quote, SqlBuilder};
use sqlite::Connection;
fn main() {
// create sqlite databases on ./tmp/sqlite.db
let conn = Connection::open("./tmp/sqlite.db").unwrap();
// create table
conn.execute(
"CREATE TABLE IF NOT EXISTS icon (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
content BLOB,
used STRING
)",
)
.unwrap();
// read image file from disk and store to sqlite as blob
let mut file = File::open("./tmp/in.jpg").unwrap();
let mut contents = Vec::new();
file.read_to_end(&mut contents).unwrap();
println!("{:?}", contents);
// build sql query
let sql = SqlBuilder::insert_into("icon")
.fields(&["name", "content", "used"])
.values(&[
quote(serde_json::to_string("in").unwrap()),
quote(serde_json::to_string(&contents).unwrap()),
quote(serde_json::to_string("1").unwrap()),
])
.sql().unwrap();
// execute query
conn.execute(&sql).unwrap();
// read image file from sqlite and store to disk
let mut builder = SqlBuilder::select_from("icon");
builder.field("id");
builder.field("name");
builder.field("content");
builder.field("used");
let stmt = conn.prepare(&builder.sql().unwrap()).unwrap();
let mut cursor = stmt.into_cursor();
let row = cursor.next().unwrap().unwrap();
let id = row[0].as_integer().unwrap();
let name = row[1].as_string().unwrap();
let content = row[2].as_binary().unwrap(); // src/main.rs:51:38
let used = row[3].as_string().unwrap();
println!("{} {} {}", id, name, used);
let mut file = File::create("./tmp/out.jpg").unwrap();
file.write_all(content).unwrap();
}
when i run this code, will got error:
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src/main.rs:51:38
but where i check the sqlite.db file, it shows:
seems file stored success. but how can i fix the code make read form sqlite and store to disk work?
if you guys need more info, please let me know. :)
I can fix the issue now, but this may not be the best solution.
// ...
let content = row[2].as_string().unwrap();
// ...
// ...
let content: Vec<u8> = serde_json::from_str(&content).unwrap();
file.write_all(&content).unwrap();
// ...
also, I may have found a better one SQL generation lib, called diesel.
Maybe as I keep learning, I might find a better, more elegant way. Anyway, it's working now. :)

Executable binary file not working after XOR encryption and decyption

I want to encrypt an exe file (file.exe), write the encrypted version to a text file (fileenc.txt) and decrypt the data in the text file back to another exe file (filedec.exe).
file.exe and filedec.exe are the same and are expected to function the same way.
However, when I try to do this the filedec.exe does not work. Error Popup says: "This app cannot run on your PC".
Please what could be the problem?
However, when I just read the file.exe, write to fileenc.txt without encryption or decryption, and then read fileenc.txt and write data to filedec.exe without encryption or decryption, filedec.exe seems to work fine.
Also, when I try encrypting and decrypting a text file with this code, it works fine too.
But when I encrypt and decrypt an exe on the fly, filedec.exe doesn't work.
Please help me out. Thank you everyone.
Here is my full code:
Main();
function Main() {
var arrKey;
arrKey = "encryptionkey";
//Encrypt file.exe and write the encrypted form to file.txt
Crypt( "C:\\...\\file.exe", "C:\\...\\fileenc.txt", arrKey );
//Decrypt the previously encrypted file.txt and write the decrypted form to filedec.exe
Crypt( "C:\\...\\fileenc.txt", "C:\\...\\filedec.exe", arrKey );
//NOTE: file.exe and filedec.exe are expected to work fine when executed
}
function Crypt(fileIn, fileOut, key) {
var fileInRead;
//Read fileIn
var adTypeBinaryRead = 1;
var BinaryStreamRead;
BinaryStreamRead = new ActiveXObject("ADODB.Stream");
BinaryStreamRead.Type = adTypeBinaryRead;
BinaryStreamRead.Open();
BinaryStreamRead.LoadFromFile(fileIn);
fileInRead = BinaryStreamRead.Read();
//Convert fileIn binary data to string
var objRS = new ActiveXObject("ADODB.Recordset");
var DefinedSize = 1024;
var adSaveCreateOverWrite = 2;
var adFldLong = 0x80;
var adVarChar = 201;
var adTypeText = 2;
objRS.Fields.Append("filedata", adVarChar, DefinedSize, adFldLong);
objRS.Open();
objRS.AddNew();
objRS.Fields("filedata").AppendChunk(fileInRead);
var binString = objRS("filedata").value;
objRS.close();
//Make key as long as string version of fileIn
while (key.length < binString.length) {
key += key;
}
key = key;
//crypt converted string with key
var k, ss, q;
var cryptresult = "";
i = 0;
for (var index = 0; index < binString.length; index++) {
k = key.substr(i, 1);
q = binString.substr(i, 1);
ss = q.charCodeAt(0);
cryptresult = cryptresult + String.fromCharCode(q.charCodeAt(0) ^ k.charCodeAt(0));
i = i +1;
}
// write crypted string to file
var outStreamW = new ActiveXObject("ADODB.Stream");
outStreamW.Type = adTypeText;
// Charset: the default value seems to be `UTF-16` (BOM `0xFFFE` for text files)
outStreamW.Open();
outStreamW.WriteText(cryptresult);
outStreamW.Position = 0;
var outStreamA = new ActiveXObject("ADODB.Stream");
outStreamA.Type = adTypeText;
outStreamA.Charset = "windows-1252"; // important, see `cdoCharset Module Constants`
outStreamA.Open();
outStreamW.CopyTo(outStreamA); // convert encoding
outStreamA.SaveToFile(fileOut, adSaveCreateOverWrite);
outStreamW.Close();
outStreamA.Close();
}
EDIT:
More troubleshooting into my code shows that when I encrypt and decrypt file.exe ON THE FLY, and then write the decrypted data to fileenc.exe, fileenc.exe works well.
But when I encrypt file.exe and write the encrypted data to fileenc.txt and then read the fileenc.txt, decrypt the read encrypted data and write to fileenc.exe (just like in my code), fileenc.exe gets corrupted. My understanding suggests that the manner through which I write the encrypted data to fileenc.txt could be the problem here.
Please I need help, how do I go about with this.

Problems with migration from swift2 to swift3 with ranges

I have strings and determine the ranges of indexes. I will need later for instance .last .count for these ranges. How should I initialise the range for string to be able to get functionality .last .count for these ranges (that is obvious in swift2 but not in swift3) ?
For example, I am often using the .count for range of string in my code in swift2, like this
var str = "Hello, playground"
let myRange = str.rangeOfString("Hello")
let myCountOfRange = myRange.count
Now it is not possible to do this in swift3
var str = "Hello, playground"
let myRange = str.range(of: "Hello")
let myCountOfRange = myRange.count // type index does not conform to protocol strideable
In Swift3, to find the size of a range you can do:
var str = "Hello, playground"
let myRange = str.range(of: "Hello")
let myCountOfRange = str[myRange!].characters.count
I don't know if this is the best way, but it works.
Alternatively:
let myCountOfRange = str.distance(from: myRange!.lowerBound, to: myRange!.upperBound)
Both require access to the original collection (ie. string), and that apparently is a limitation of Swift 3. The new model for collections and indices is discussed here.
If you want to store the ranges in an array and call .count and .last on them, you can convert the Range<Index> to a CountableRange<Int> while you still have access to the collection:
var str = "Hello, playground"
let myRange = str.range(of: "Hello")!
let lb = str.distance(from: str.startIndex, to: myRange.lowerBound) as Int
let ub = str.distance(from: str.startIndex, to: myRange.upperBound) as Int
let newRange = lb..<ub
newRange.count // 5
newRange.last // 4

Moq: How to ensure Verify() reports on non-matching parameters

I have the following unit test verification using Moq:
var mock = new Mock<IDoSomethingUseful>();
var sut = new Thingy(mock.Object);
sut.CallDoSomethingUseful();
mock.Verify(
somethingUseful => somethingUseful.Move(
It.Is<MyVector>(
myVector => myVector.x == 123)), Times.Once, "This fail message needs to be hard-coded with myVector.x was not equal to 123");
How can I get Verify() to tell me that the predicate match failed? The test runner only reports that the call failed so I need to rely on the hard-coded message.
Using Callback the invocation arguments can be accessed. See section Callbacks here.
In your case you could add an expected value for x to the test and get the actual value in Callback. Finally use an Assert to verify if expected and actual values equal where the message can be formated using both values. HTH
int expected_x_value = 123;
int actual_x_value = 0;
var mock = new Mock<IDoSomethingUseful>();
mock.Setup(m => m.Move(It.IsAny<MyVector>()))
.Callback<MyVector>(
(v) =>
{
actual_x_value = v.x;
}
);
var sut = new Thingy(mock.Object);
sut.CallDoSomethingUseful();
Assert.AreEqual(expected_x_value, actual_x_value,
string.Format("myVector.x was expected to be called with x = '{0}' but was '{1}'",
expected_x_value, actual_x_value));

Add "blocking" to Swift for-loop

I am using Swift in a project, and using SQLite.swift for database handling. I am trying to retrieve the most recent entry from my database like below:
func returnLatestEmailAddressFromEmailsTable() -> String{
let dbPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first as String
let db = Database("\(dbPath)/db.sqlite3")
let emails = db["emails"]
let email = Expression<String>("email")
let time = Expression<Int>("time")
var returnEmail:String = ""
for res in emails.limit(1).order(time.desc) {
returnEmail = res[email]
println("from inside: \(returnEmail)")
}
return returnEmail
}
I am trying to test the returned string from the above function like this:
println("from outside: \(returnLatestEmailAddressFromEmailsTable())")
Note how I print the value from both inside and outside of the function. Inside, it works every single time. I am struggling with the "from outside:" part.
Sometimes the function returns the correct email, but sometimes it returns "" (presumably, the value was not set in the for loop).
How can I add "blocking" functionality so calling returnLatestEmailAddressFromEmailsTable() will always first evaluate the for loop, and only after this return the value?

Resources