Jump to content
Xtreme .Net Talk

excaliber

Members
  • Posts

    9
  • Joined

  • Last visited

Everything posted by excaliber

  1. Thanks, that did the trick :D
  2. I am attempting to add a browse button to this particular property (in the PropertyGrid). Ive found code on the net telling me to add in the EditorAttribute with FileNameEditor in it. Unfortunately, I am being told that "System.Windows.Forms.Design.FileNameEditor is not defined". Sure enough, it doesnt appear that FileNameEditor is part of the Design Namespace. Any help? Thanks <CategoryAttribute("Mesh"), _ EditorAttribute(GetType(System.Windows.Forms.Design.FileNameEditor), GetType(System.Drawing.Design.UITypeEditor)), _ Browsable(True), _ [ReadOnly](False), _ BindableAttribute(False), _ DefaultValueAttribute(""), _ DesignOnly(False), _ DescriptionAttribute("Path to Normal Map")> _ Public Property NormalMap() As String Get Return _NormalMap End Get Set(ByVal Value As String) _NormalMap = Value End Set End Property
  3. Bump for interest. I'll let the thread die this time if there is no interest. Thanks :)
  4. Hi all. This post is actually stemming from this conversation over at XVBT: http://www.xtremevbtalk.com/showthread.php?p=908999 I had PM'd Mike_R about some questions that went "deep" into .Net, to which he replied as a thread for others to see. I had also mentioned to him a piece of code I had found on the net (in C#.Net) that allowed pseudo-inline ASM. I converted it to VB.Net (being the language I'm most comfortable in), and had asked a few questions. He wasn't quite sure, so referred me here. The original code is from here: here Private MEM_COMMIT As UInt32 = Convert.ToUInt32(4096) Private PAGE_EXECUTE_READWRITE As UInt32 = Convert.ToUInt32(64) Private MEM_RELEASE As UInt32 = Convert.ToUInt32(32768) ' <DllImport("KERNEL32.DLL")> _ Private Shared Function VirtualAlloc(ByVal lpStartAddr As UInt32, ByVal size As UInt32, _ ByVal flAllocationType As UInt32, ByVal flProtect As UInt32) As UInt32 End Function ' <DllImport("KERNEL32.DLL")> _ Private Shared Function VirtualFree(ByVal lpAddress As IntPtr, ByVal dwSize As UInt32, _ ByVal dwFreeType As UInt32) As Boolean End Function ' <DllImport("KERNEL32.DLL")> _ Private Shared Function CreateThread(ByVal lpThreadAttributes As UInt32, ByVal dwStackSize As UInt32, _ ByVal lpStartAddress As UInt32, ByVal param As IntPtr, ByVal dwCreationFlags As UInt32, _ ByRef lpThreadId As UInt32) As IntPtr End Function ' <DllImport("KERNEL32.DLL")> _ Private Shared Function CloseHandle(ByVal handle As IntPtr) As Boolean End Function ' <DllImport("KERNEL32.DLL")> _ Private Shared Function WaitForSingleObject(ByVal hHandle As IntPtr, ByVal dwMilliseconds As UInt32) As UInt32 End Function ' <DllImport("KERNEL32.DLL")> _ Private Shared Function GetModuleHandle(ByVal moduleName As String) As IntPtr End Function ' <DllImport("KERNEL32.DLL")> _ Private Shared Function GetProcAddress(ByVal hModule As IntPtr, ByVal procName As String) As UInt32 End Function ' <DllImport("KERNEL32.DLL")> _ Private Shared Function LoadLibrary(ByVal lpFileName As String) As UInt32 End Function ' <DllImport("KERNEL32.DLL")> _ Private Shared Function GetLastError() As UInt32 End Function ' <StructLayout(LayoutKind.Sequential)> _ Friend Structure PROCESSOR_INFO Public dwMax As UInt32 Public id0 As UInt32 Public id1 As UInt32 Public id2 As UInt32 Public dwStandard As UInt32 Public dwFeature As UInt32 Public dwExt As UInt32 End Structure ' ' ' Private Sub TestInline() Dim proc() As Byte = {85, 139, 236, 131, 236, 0, 83, 81, 82, 87, 139, 125, 8, 51, _ 192, 15, 162, 137, 7, 137, 95, 4, 137, 87, 8, 137, 79, 12, 184, 1, 0, 0, 0, 15, _ 162, 137, 71, 16, 137, 87, 20, 184, 0, 0, 0, 128, 15, 162, 61, 0, 0, 0, 128, _ 114, 10, 184, 1, 0, 0, 128, 15, 162, 137, 87, 24, 95, 89, 91, 90, 139, 229, _ 93, 51, 192, 194, 4, 0} ' Dim funcAddr As UInt32 = VirtualAlloc(Convert.ToUInt32(0), Convert.ToUInt32(proc.Length), MEM_COMMIT, PAGE_EXECUTE_READWRITE) Dim handle As New IntPtr(Convert.ToInt64(funcAddr)) ' Marshal.Copy(proc, 0, handle, proc.Length) ' Dim hThread As IntPtr = IntPtr.Zero Dim threadId As UInt32 = Convert.ToUInt32(0) Dim info As PROCESSOR_INFO = New PROCESSOR_INFO Dim pinfo As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(GetType(PROCESSOR_INFO))) Marshal.StructureToPtr(info, pinfo, False) hThread = CreateThread(Convert.ToUInt32(0), Convert.ToUInt32(0), funcAddr, pinfo, Convert.ToUInt32(0), threadId) ' WaitForSingleObject(hThread, Convert.ToUInt32(10000)) info = CType(Marshal.PtrToStructure(pinfo, GetType(PROCESSOR_INFO)), PROCESSOR_INFO) ' Marshal.FreeHGlobal(pinfo) CloseHandle(hThread) VirtualFree(handle, Convert.ToUInt32(0), MEM_RELEASE) End Sub As you can see, I had to do some changing around. VB.Net (for some unexplicable reason) does not like type coercion. For instance, it will not let you CType() or DirectCast() an UInt32 (or even a Int32 for that matter) into a IntPtr like C# will. Also, VB.Net doesn't seem to play nice with the unsigned numbers either (all the UIntXX types). For instance, on this line: Dim handle As New IntPtr(Convert.ToInt64(funcAddr)) The declaration will only allow signed numbers, so I manually forced the Unsigned Int32 into a a Signed 64 (which should make sure nothing is lost in the process from unsigned to signed). This particular line is also different from the original. Because of some limitations, I decided to declare a IntPtr and pass in the pointer value instead of direct casting (mentioned earlier) or Marshal.WriteIntXX methods. As to the explanation of how it works, here is what I *think* is going on. The byte array proc() contains the ASM opcodes and data to execute (you can find a disassembly of it here: http://www.tong-web.com/disassembly.txt). VirtualAlloc is called (imported method from Kernel32) which allocates a chunk of memory and returns the address of the base of that chunk. From there, we put the address into a IntPtr for .Net to use. Now we use the IntPtr to copy the data into the allocated chunk of memory. Next we make a few declarations (a new pointer for a thread) and declare an object to hold our return data (in this case a PROCESSOR_INFO object). It looks like we then allocate some unmanaged heap space for our ROCESSOR_INFO object, grab the base address of the object and store it into pinfo (IntPtr). And now for the real genius part. We use the Kernel32 CreateThread method to make a new child thread, passing it the pointer to our inline ASM (the array proc() ) as well as a pointer to our return object's allocated (but unused) heap space. We call a WaitForSingleObject to give the thread time to finish what it was doing, then use Marshal.PtrToStructure to convert the pinfo pointer (and the space allocated with it) back into a managed object. Lastly, we unallocated heap space and generally clean up. Now, some questions of my own. I know that data is passed into the thread (and therefore the ASM) via pinfo. But inside the ASM itself, where is the data located? Is it located at the base memory address for the thread? Is the pointer to the data stored in one of the registers? Conversly, how is the data returned? From the disassembly of the code, it looks like it stores it to memory then RET's a memory location (which is converted back into a managed structure later). Let me know if I have messed up this conversion from C# to VB.Net. When running, I got the same values in C# as I did in my converted code, but there could be a bug somewhere.
  5. Well, I found the problem, which was a combination of things (isn't it always). First was the of not catching a 0 length return array for the buffer (which means the client is shutting down). Doh. I was no longer getting the error from "proper" shutdown on the client end. Unfortunately, I was still getting the error when the client would disconnect suddenly. After some digging around, I found this article: http://groups.google.com/groups?hl=en&lr=lang_en&safe=off&selm=%23FjgHuY5DHA.1816%40TK2MSFTNGP12.phx.gbl Which, although the error is different, was the answer. I have Nod32 installed as my AntiVirus, and apparently (I've heard this before too) hooks itself into the low-level socket structure of windows. When suddenly disconnecting, either Nod32 wasn't returning the error, or Windows was not handling it correctly. Either way, I was getting the sourceless, untrappable error. With Nod32 removed, I now can trap the error as normal, and see which object it is, etc. All is good :D Thanks again for your help, I really appreciate it!
  6. Hi, I'm using asynchronous sockets for my server. Whenever a client disconnects (either "legally" or suddenly), the server code "explodes". I get the following error: An unhandled exception of type 'System.NullReferenceException' occurred in system.dll Additional information: Object reference not set to an instance of an object. It then proceeds to tell me that there is no code to display, only ASM. Which is entirely unhelpful. I'm completely out of ideas about how to tackle this, let alone what is wrong. I can't seem to trap it. I have exception handling around all the Asynch methods (BeginAccept, BeginRecieve, BeginSend, and all their EndX counterparts). Nothing is ever thrown. Checking for mSocket.Connected = False does nothing as well. I am quite out of ideas. So, let me explain how I am currently doing things: For accepting, I have a While True loop which begins BeginAccept, and a ManualResetEvent to control when the loop should continue (controlled from the callback delegate of BeginAccept) For Recieving, I do the following. I call the BeginRecieve method and wait. When I get # of bytes recieved by calling EndRecieve on the IAsynch Object passed in. I then proceed to parse and process data, fill buffers, etc. At the end of the sub, I call the function that calls BeginRecieve again, so I can get the rest of the data (or new commands). I also use BeginSend in similar fashion, but it is usually called from the callback delegate of BeginRecieve (ie. it gets data, then proceeds to send data back). Any help would be great. Thanks
  7. Hi all, I've got a minor problem that I think deals with synchronization. I've got asynchronous socket code working on my server. When it recieves a command, it will call the follow function to perform an asynchronous SQL query on my database: SyncLock pgConn strSQL = "SELECT * FROM usertable" pgCommand = New CoreLab.PostgreSql.PgSqlCommand(strSQL, pgConn) pgDataReader = pgCommand.BeginExecuteReader(AddressOf dbQueryReturn, _netclient, CommandBehavior.Default) End SyncLock But here is my problem. The asynch command is saving the result to pgDataReader, which is privately declared in the module (yes, module. Bad coding practice :D ). I'm figuring that is bad, as all the results will be stored there and overwrite the last. But I would like to avoid as much overhead and redundant object creation as possible. So with that in mind, I'm in a quandry. Can I put another SyncLock in the callback delegate (dbQueryReturn) on the pgDataReader to prevent other threads from modifying it until it is copyied to a local variable? Wouldn't that negate the benefit of asynch programming though? Should I create a new class instance for each DB query, and keep the dataobjects in there? I was avoiding that because that is a lot of additional overhead (a string, command and reader object per query, plus the class overhead itself). Should I keep a "pool" of datareaders privately declared in the module? As they are used, I can change a state property for each object to used, and pass the index as the state object for the asynch call. Then on the callback delegate, the state object is used to get the datareader object from the pool. When it is done, the object is returned to "free" state. Would also allow me to dynamically increase or decrease the number of pooled readers, depending on load (and thus save some memory) Last idea. Would it be possible to create a new DataReader object, then pass as the state object? Or is that not a "legal move"? Thanks, I really appreciate it.
  8. Yes, Homesite is very good. Very easy and clean, with nice syntax highlighting. Notepad, is really bad. Sorry, but it is. It doesnt preserve tabs, has a nasty habit of inserting CrLf (carriage return linefeed) in the middle of a line to wrap, instead of handling it internally.
  9. Straight HTML/PHP in Homesite 4.0. Has syntax highlighting and many other nice features. Only good way to code websites is by hand.
×
×
  • Create New...